Android Example Webview & File.DirAssets - Enough Already

UPDATE: AFTER READING THIS POST, PLEASE REFER TO POST#5 FOR A BETTER SOLUTION (AT LEAST, IN MY OPINION).
a code module provided by member Ivica Golubovic allows you to continue using your current code by simply adding the module to your app(s). in the event you use some unusual coding syntax which causes the module to break, i would think it would be much easier to modify the module to suit, rather than having to change your coding.
--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------

there are some misunderstandings about webview and file.dirassets. i am not here to judge.

from android documentation (https://developer.android.com/reference/android/webkit/WebSettings#setAllowFileAccess(boolean))
relating to the setAllowFileAccess setting: "Enables or disables file access within WebView. Note that this enables or disables file
system access only. Assets and resources are still accessible using file:///android_asset and file:///android_res."

clear enough? the webview setting to disable this is not necessary, as the setting itself does not relate to files in dirassets.
from android's viewpoint, dir.assets is not part of a file system. android resources are identified by an id number. if you have resources
to include in your app and which you want to access by name, you have to put them in dirassets and use the asset manager to deal with
them on your behalf. this is handled for us as part of b4a's core.

google would prefer:
1) that the file:// scheme not be used.
2) that the so-called webviewassetloader api be used instead.

whether google will eventually outlaw the first entirely and require the second is unclear. google feels (or may have discovered) that the
file:// scheme used to load files permits someone to cause your webview to load files without your (or your user's) knowledge. in addition,
the webviewassetloader api address CORS issues and presents a uniform addressing scheme compatible with google's https:// loading
preference. how the api works is beyond the scope of this post. you can search for webviewassetloader in the little box in the upper
righthand corner of this page.

while it is possible (although discouraged) to use the file:// scheme to load a webview with resources in dirassets, there is a problem relating
to files kept in subfolders in dirassets. this is due to google's introduction of the aab bundle format and software used to prepare the bundle.
erel has alluded to this, and i have read the documentation regarding aapt2 (the software which packages our projects), but i did not see a
direct reference to the dirassets subfolder issue. nevertheless, as people who having been using subfolders have discovered, there is
definitely a problem. so let's deal with it.

for those who do not want to or cannot give up subfolders in dirassets, there are 2 solutions:
1) include the XUI library and load your files thus: webview.LoadUrl(xui.FileURI(File.DirAssets, "subfolder\cat1\filename.html"))
note the backslash separator!
or
2) use the familiar file:// scheme, but with the urlencoded (%5C) separator: webview.LoadUrl("file:///android_asset/subfolder%5Ccat1%5Cfilename.html")

unfortunately, for files kept in subfolders to be loaded from within the webview itself, the solution will require you to edit those html files which load
resources kept in subfolders in dirassets. use this, eg: <img src='file:///android_asset/subfolder%5Ccat1%5Csomeimage.jpg'>

below please find a working example of what you need to do. i have tested it with b4a 11.20, android28/sdk28 and android30/sdk30 on a device running
android 12 and on a tablet running android 9. both versions work on both devices, so there seems to be no need build separate code to deal with device
build. normally, i might find that a little odd, given that "something" happened with sdk30 that causes apps which worked before to break. the usual thing
to do would be to test for device build and then code for older versions and code for newer sdk's, but for whatever reason, the example works fine on
my devices.

as to recommendations that subfolders be copied from dirassets to some other location, i believe you will find they are no longer accessible from
within a webview. at least i was not able to get it to work. i suspect this might be a big problem. the subfolder tree structure is fine for loading from
within the app; i'm talking about loading from within the webview. it appears that only the dirassets subfolder tree is still available, and urlencoding a
backslash separator is a small price to pay, since it may be the only option.

flattening all the subfolders is a simple solution, but it doesn't take into account how many files and subfolders we're talking about and how your app
searches for them. but, mainly, unless you flatten them and put them in dirassets (proper) or dirinternal, they're not going to be accessible from the webview. and
copying them from dirassets to dirinternal means you just carry twice the load. and for no reason since dirassets and subfolders still works.
 

Attachments

  • assets.zip
    82.9 KB · Views: 638
Last edited:

drgottjr

Expert
Licensed User
Longtime User
son of a b**ch!:mad:
i believe the example is in compliance with google's version of android, and if i had a samsung tab a, i would spend time on it with the example. this, presumably is one of the (many) reasons erel tries to steer people away from webview. samsung is under no obligation to be in compliance with anything other than its own version of android (if i may be so bold). they are free to use android as they see fit.

access_denied tends toward the vague, although webview sometimes mentions the file to which access was denied. file_not_found would have signalled an issue with the use of subfolders and/or the file separator. i don't believe it's possible to extract more details regarding the access error. i think it occurs at an early stage before webviewclient kicks in with its various error-trapping methods. it would certainly be handled by the os and passed to webview, which would simply echo it to us. maybe i'll find a tab a lying on the street; it's pretty rough around here. my apologies to samsung users.

i regret that i did not include a simple webview.loadUrl( "file:///android_asset/test.html") call. if that triggers an access_denied error, then the file:// scheme simply no longer works on samsung tab a (sdk30). regardless of subfolders. if it did work, then subfolders is the issue. it would certainly be trivial enough for someone to add.

i have not mentioned the other way to load local files - webview.loadHtml( file.readstring( file.dirassets, "test.html" ) ) - as the forum members who complain about dir.assets no longer working are using the webview.loadUrl() method with the file:// scheme. it does exist, and it handles subfolders, but it involves more than simply reversing a file separating symbol. and the approach won't work from within a webview (although, technically, it is possible to have a webview cause b4a to load files from subfolders using the javascript interface, but it's not pretty. given the alternative of no access to the subfolders, it could be something to consider. i did try it.)

i searched online for information about samsung and webview and sdk30. nothing for the moment.
 

drgottjr

Expert
Licensed User
Longtime User
many pages into googling "samsung tab a webview android11", and things start to appear. the complaints i'm seeing relate to an update of webview which has adversely affected samsung tab users. they complain of random crashes. there are quite a number of complaints. while it would be a stretch to suggest this has something to do with using subfolders and file.dirassets, there is evidence that some users are experiencing troubles with webview on a samsung tab a under android11. this doesn't let me off the hook - i did seem to imply i was issuing the final word relating to webview and file.dirassets - but it could mean samsung might deal with it.
 

Ivica Golubovic

Active Member
Licensed User
Yes, Samsung Tab A has problems with WebView and Asset folder. But there is a solution for everything (If WebView is not allowed to access files in the Asset folder, it can be accessed systemically via File.ReadString and the LoadHTML method). I slightly modified your example by adding a code module called "AdaptHTML". The purpose of the module is to automatically modify the HTML file and customize it to work in the Asset folder. It is not necessary to manually modify the HTML code to allow access to files in subfolders (imagine that you need to modify an HTML file that uses 1000 or more objects located in several subfolders - the brain would explode). You can easily use "file: ///android_asset/subfolder/file.html" or "file:///android_asset/ subfolder\file.html" and "file: ///android_asset/subfolder%5Cfile.html" in the HTML file. Download the redesigned project and view the contents of the HTML file. I wish you a nice day.

Important:
Unzip the "subfolder.zip" to the Files folder (ExportAsZip option does not zip folders from Asset folders) and run "SyncFolder" to make the project work.
 

Attachments

  • assets.zip
    45.5 KB · Views: 380
  • subfolder.zip
    38.1 KB · Views: 363
Last edited:

drgottjr

Expert
Licensed User
Longtime User
very nice helper mod. i had hoped to draw attention to the webview/dirassets problem and to encourage users who refused to abandon file:// and subfolders by showing them it was still possible to use that scheme if that's what they really had to do. your mod allows them to have their cake and eat it too, so to speak, by letting them think nothing has changed. software vaping, if you like.

i'm going to edit my initial post to point any future readers to post #5 regarding your code module. i could extract it from your example and post it myself as a separate upload, but maybe that's something you would prefer to do.
 

Ivica Golubovic

Active Member
Licensed User
very nice helper mod. i had hoped to draw attention to the webview/dirassets problem and to encourage users who refused to abandon file:// and subfolders by showing them it was still possible to use that scheme if that's what they really had to do. your mod allows them to have their cake and eat it too, so to speak, by letting them think nothing has changed. software vaping, if you like.

i'm going to edit my initial post to point any future readers to post #5 regarding your code module. i could extract it from your example and post it myself as a separate upload, but maybe that's something you would prefer to do.
The module will be inserted into the UltimateWebView library. As for sharing the module, I have nothing against you doing that, so we help each other no matter whose idea it is. So share the module wherever you want.
 

drgottjr

Expert
Licensed User
Longtime User
my guess would be that users who have been affected by the dirassets/subfolder
problem either don't use an additional webview-related library or they already have
one in place. the code module doesn't require any library. adding your library just
to get the helper might interfere with what they are already accustomed to. (i don't
know what all your library overrides when initialized.) they could, of course, always
learn how to use the library.

anyone who has downloaded the modified example has the module (with operating
instructions in the simple main module). they can just copy and paste as needed
or save it in a shared folder for use when required. if they get your library, then
win-win.
 

Ivica Golubovic

Active Member
Licensed User
I'm talking about the fact that the process of adapting the html file will be added to the library to make it available to people who want to use the library in a future projects. As for those who already have a finished project, of course they will not import the entire library, but will only add a module, or add those two Subs to the activity. The thing is, people will find it very difficult to switch to a webview asset loader in the near future because they have used the file schema for years, it will be especially difficult for those with less programming experience and knowledge of the Java programming language.
 

drgottjr

Expert
Licensed User
Longtime User
if we are required to use webviewassetloader, then the helper module breaks since it's based on loading a string, and the point of the assetloader api is to make us use the https:// scheme. so long as loading a string is allowed, your module is good, and assetloader - if mandated - for the file:// scheme is irrelevant.

and since loading a webview with a string is actually woven in the webview's own calls, i'm thinking it will be a while before google makes that change. in any case, i won't be around to have to deal with it. good luck!
 
Top