Display local image in Android WebView on Marshmallow (ERR_ACCESS_DENIED)

10,291

I figured it out. That was way more difficult that it should have been.

So here was the problem:
I was using an Android Marshmallow device as my test device. It seems that the <uses-permission ../> tag for READ_EXTERNAL_STORAGE and WRITE_EXTERNAL_STORAGE does not work on Marshmallow. You are required to use the new permissions API to request permissions at runtime.

Check out the correct answer to this question for code:
READ_EXTERNAL_STORAGE permission for Android

Share:
10,291
Bobbyloujo
Author by

Bobbyloujo

Updated on July 01, 2022

Comments

  • Bobbyloujo
    Bobbyloujo almost 2 years

    I'd like to be able to display images in local directories such as /sdcard/Pictures/ and /sdcard/Download/ in a WebView.

    Here is what I've tried:

    I have an image file called "levels.png" that I copied from my computer to my device. It is at the "root" of the internal storage that I can access through my computer. This is the /sdcard/ path.

    String base = Environment.getExternalStorageDirectory().getAbsolutePath();
    String imagePath = "file://" + base + "/levels.png";
    String html = "<html><head></head><body><img src=\""+ imagePath + "\"></body></html>";
    loadDataWithBaseURL("", html, "text/html","utf-8", "");
    

    The above code just shows a broken image icon.

    loadUrl("file:///"+ Environment.getExternalStorageDirectory().getAbsolutePath() +"/levels.png");
    

    This code shows me the "Webpage not available" page with the upside down android. It says:

    The webpage at file:///storage/emulated/0/levels.png could not be loaded because: net::ERR_ACCESS_DENIED

    If I change the file name to a file I know does not exist, I get ERR_FILE_NOT_FOUND instead. So it seems that the app finds the file but can't access it due to a permissions problem. In my manifest I have:

    <uses-permission android:name="android.permission.INTERNET"/>
    <uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
    <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
    

    I also call all of these methods in my WebView before loadUrl:

    getSettings().setAllowFileAccess(true);
    getSettings().setJavaScriptEnabled(true);
    getSettings().setAllowFileAccessFromFileURLs(true);
    getSettings().setAllowContentAccess(true);
    

    I've only been able to find solutions that load images from the app's assets folder but that is not what I'm trying to do. I'd like to simply be able to specify the exact path of an image on the device and display it in a WebView. (I promise what I'm trying to do makes sense for my application).