3

I have an Android page that features a WebView. I initially generate some HTML and load it into the webview using some code that looks like:

String ASSET_DIR = "file:///android_asset/subdir/";
webview.loadDataWithBaseURL(ASSET_DIR, html, "text/html", "UTF-8", null);

In the onPageFinished callback to my WebViewClient, I want to scroll the view to an anchor in the generated html. In that callback, I call

webview.loadUrl(ASSET_DIR + "#" + myAnchor);

On older versions of WebView (44), this works fine, but on newer versions (70), I get the error:

The webpage at file:///android_asset/subdir/#myAnchor could not be loaded because: net::ERR_FILE_NOT_FOUND

I've tried adding permissions to webview.getSettings(), but without success. How do I fix this?


Note: I'd like to avoid using Javascript to solve this issue. I tried a solution with findElementById.scrollIntoView, but it scrolls off the page on newer WebView versions.

karl
  • 3,544
  • 3
  • 30
  • 46
  • 1
    "Below Oreo, this works great" -- that is very surprising, and I would not count on it. Since the implementation of `WebView` is updated independently of the OS, edge case behavior can change at any point. The error that you are getting is exactly what I would expect for you to get, as there is no file at `file:///android_asset/subdir/` (since that is not a file). – CommonsWare Nov 26 '18 at 23:29
  • @CommonsWare There is a file at `assets/subdir/style.css` in my project. Including `` in the generated HTML (and providing that base URL) works consistently across all versions. I've also verified that `ASSET_DIR` is the same value that gets passed to `onPageFinished` in the `url` parameter. – karl Nov 27 '18 at 15:04
  • @CommonsWare It's certainly possible that the API version is coincidence and I'm just getting old `WebView` versions on my older devices/emulators, but the question is still mostly the same - what has changed in `WebView` from older versions, and how do I fix it? – karl Nov 27 '18 at 15:06
  • 1
    "There is a file at assets/subdir/style.css in my project" -- I don't see how that relates to the code in your question, though. You specifically attempt to load a URL (`ASSET_DIR + "#" + myAnchor`) that you know does not exist. If this Web page were in `ASSET_DIR`, then you could use `loadUrl()` to access it, but this Web page is dynamically generated. Other than trying just `"#" + myAnchor` or going the JavaScript route, I don't know what you can do. My point is that I am stunned that it ever worked. – CommonsWare Nov 27 '18 at 22:28
  • @CommonsWare I think I get what you're saying. `file:///android_asset/subdir/` is what `onPageFinished` reports as being the URL of the generated HTML, which is why I was using it. Thank you for the tip on `WebView` versions. I haven't been able to find a lot of different versions to test it with, but it _does_ work on version 44. – karl Nov 28 '18 at 15:01
  • I tried using `"#" + myAnchor`, but that results in a blank page. – karl Nov 28 '18 at 15:02
  • 1
    `loadDataWithBaseURL()` breaks a lot of the standard Web rules, so I'm not terribly surprised that `onPageFinished()` gives odd results. Would it be possible for you to write the HTML to a file on the filesystem (e.g., `getFilesDir()`), add an actual `` element to the `` that points to `file:///android_asset/subdir/`, then use `loadUrl()` to load the file? I have no idea if that works, but it's one way for you to have an addressable URL (on which `#` should work) but that still points to `assets/` for the rest of your content. – CommonsWare Nov 28 '18 at 23:09
  • Thanks. Writing to a file and then loading it _mostly_ works. The scrolling is inconsistent, though - sometimes it scrolls to the correct place, and sometimes it scrolls a couple of lines too far. I can get both behaviors just by repeatedly hitting back and loading it again. – karl Nov 29 '18 at 16:50

0 Answers0