'Android 11: AndroidProtocolHandler: WebView does not show local html file with local images via FileProvider

For many years my app downloaded files and linked images to e.g. the "/Download" folder with the Download Manager. I could show the HTML contents within a WebView.

Since Android 11 this solution is not possible anymore. The links to the locally stored images are broken. Of course I read many posts on this subject.

Downloading an HTML file was succesfully done to /Android/data/my.base.package/files worked. I can show it in a WebView.

When I also download the images to my mobile the WebView does not show the locally downloaded images. In my downloaded HTML file I converted all external URL's of the used images to local pathnames.

The simplified HTML file looked like:

<html...>... 
<img alt="some picture" src="file:///storage/emulated/0/Android/data/my.base.package/files/some-picture.png" />
</html>

Presenting the HTML in a WebView is simplified:

String baseUrl = null; // or "file:///storage/emulated/0/Android/data/base.package.name/files"
myWebView.setWebViewClient(new WebViewClient() {
    view.postDelayed(new Runnable() {
       public void run() { // will convert it to Lambda ;-)
           gcLongDescr.scrollTo(0, scrollPosition);
       }
    }, 300);
});
myWebView.loadDataWithBaseURL( baseUrl, the-html-string, "text/html", "utf-8", null);

QUESTION : Assume I can present the HTML file (as a string) in a WebView. How can I use a (relative) file pathnames to the downloaded pictures?

Try 1: use absolute pathnames in my HTML. Does not work.

Try 2: use the /Download folder. The methods like getExternalStorageDirectory() and getExternalStoragePublicDirectory() on Environment are deprecated.

Try 3: Use the file provider to store the image files.

UPDATE: The last method seems to be the correct method. But I now get the following error:

E/AndroidProtocolHandler: Unable to open content URL: content://nl.xyz.abc.provider/myimages/some-picture.png

Step 1: Make a file provider: in my AndroidManife

<provider
    android:name="androidx.core.content.FileProvider"
    android:authorities="nl.xyx.abc.provider"
    android:exported="false"
    android:grantUriPermissions="true">
    <meta-data
        android:name="android.support.FILE_PROVIDER_PATHS"
        android:resource="@xml/provider_paths"/>
</provider>

Add the provider paths to the XML folder:

<?xml version="1.0" encoding="utf-8"?>
<paths>
    ...
    <files-path name="files" path="." />
    <files-path path="images" name="myimages" />
</paths>

Step 2: I copy the image files to the folder file:///storage/emulated/0/Android/data/my.base.package/files/images.

Step 3: In the downloaded HTML file I change the external image URL's to the local files via the FileProvider. An example is:

<img alt="some image" src="content://nl.xyz.abc.provider/myimages/some-picture.png" />


Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source