Skip to content Skip to sidebar Skip to footer

Html Link To Local File In Webview With Target Api 24

How can one use HTML links to navigate to local files (HTML pages) in WebView if targeting API 24 or higher? This has been discussed before and solutions use the file:// URI scheme

Solution 1:

The following workaround (based on this answer) intercepts the loading of a file:// URI in the WebView and then loads it directly by app code with WebView.loadUrl(...). This is possible by overriding WebView.shouldOverrideUrlLoading in a WebViewClient passed to the WebView, e.g. when initializing it.

As there was an API change for this method in API 24, for compatibility there are two versions in the code (technically in the API<24 case one could also do as before, letting WebView open the file:// URI because the exception is not raised on devices running API<24).

if (android.os.Build.VERSION.SDK_INT >= 24) {
    webView.setWebViewClient(newWebViewClient() {
        @OverridepublicbooleanshouldOverrideUrlLoading(WebView webView, WebResourceRequest webResourceRequest) {
            if (webResourceRequest.getUrl().getScheme().equals("file")) {
                webView.loadUrl(webResourceRequest.getUrl().toString());
            } else {
                // If the URI is not pointing to a local file, open with an ACTION_VIEW Intent
                webView.getContext().startActivity(newIntent(Intent.ACTION_VIEW, webResourceRequest.getUrl()));
            }
            returntrue; // in both cases we handle the link manually
        }
    });
} else {
    webView.setWebViewClient(newWebViewClient() {
        @OverridepublicbooleanshouldOverrideUrlLoading(WebView webView, String url) {
            if (Uri.parse(url).getScheme().equals("file")) {
                webView.loadUrl(url);
            } else {
                // If the URI is not pointing to a local file, open with an ACTION_VIEW Intent
                webView.getContext().startActivity(newIntent(Intent.ACTION_VIEW, Uri.parse(url)));
            }
            returntrue; // in both cases we handle the link manually
        }
    });
}

The reason why there is an exception when letting the WebView open the link must have something to do with the Intent created by the WebView but I don't see whether or how it is exposed to another app.

That the workaround works is then because the WebView does not do anything with the link (no Intent is created), instead, when the link is clicked, the app gets control and opens the file:// URI direclty by passing it to WebView.loadUrl(...) - which seems to be fine.

I assume (but do not claim) that regarding security this is fine because the URI is only used to load the file it points to in this single WebView (and if this was problematic the system should throw the FileUriExposedException).

Solution 2:

I never link in the HTML that way if you need to load an other page:

<a href="file:///android_asset/my_page.html">Go to local page</a>

I link this way because my map struture look like this:

<a href="my_page.html">Go to local page</a>

You just need that methode in your MainActivity.java and that will work:

privateclassMyBrowserextendsWebViewClient {
    @OverridepublicbooleanshouldOverrideUrlLoading(WebView view, String url) {
        if (url.startsWith("tel:") || url.startsWith("sms:") || url.startsWith("smsto:") || url.startsWith("mailto:") || url.startsWith("mms:") || url.startsWith("mmsto:") || url.startsWith("market:")) {
            Intentintent=newIntent(Intent.ACTION_VIEW, Uri.parse(url));
            startActivity(intent);
            returntrue;
        }
        else {
            view.loadUrl(url);
            returntrue;
        }
    }
}

If you have any questions or It still don't work let me know

Post a Comment for "Html Link To Local File In Webview With Target Api 24"