Android Question WebView displays source

johnf2013

Member
Licensed User
Longtime User
I have implemented a WebView to display application help. It loads an asset file using Erel's WebViewAssetFile sub. This works very well in the emulator and on the real device for simple html documents that I write from scratch.

So now for the serious stuff. I have an index.html and a lot of support files. These are generated by HelpAndManual, a help authoring tool. This tool can generate many different outputs and is typically used (by me) to produce Microsoft compiled help files (.chm). It can also generate WebHelp files which are (supposed) to be OS agnostic.

I generate the WebHelp and it works perfectly in my browser. When I try to use it my Android app I just get the source displayed. I expect this will be quite confusing to my customers and not at all useful.
B4X:
HelpView.LoadUrl(BalUtils.WebViewAssetFile("index.html"))

I seem to be missing something here. Are there some kind of limitations on the capabilities of WebView?
Where should I begin looking for the solution to this?

I've looked at the source and it appears to be "vanilla" html. A default project style sheet, a bit of simple javascript, and little more.

Any help would be appreciated.
 

eurojam

Well-Known Member
Licensed User
Longtime User
did you try loadhtml also:
B4X:
HelpView.Loadhtml(File.ReadString(File.DirAssets, "index.html") )
 
Upvote 0

johnf2013

Member
Licensed User
Longtime User
did you try loadhtml also:
B4X:
HelpView.Loadhtml(File.ReadString(File.DirAssets, "index.html") )

Ok, this worked, "sort of".
It loads the index page but none of the links work.

I managed to get it all working with the following simple code, but it only works if I compile in release mode.
B4X:
HelpView.LoadUrl("file:///android_asset/index.html")
In debug mode the links in the document are invalid.

Compiling in debugger mode makes use of a virtual assets folder. I can get the name of this folder with
B4X:
jo.GetField("virtualAssetsFolder")
but when I apply this to the File.ReadString method the extra forward slashes are stripped away so the method fails.

So, GetField returns the following, as expected;
B4X:
"file://" & jo.GetField("virtualAssetsFolder")
file:///data/user/0/B4A.turbineBalancer/files/virtual_assets/
and getting the filename returns the following, as expected;
B4X:
jo.RunMethod("getUnpackedVirtualAssetFile", Array As Object("index.html"))
index.html.unpacked

Using the above returned strings, ReadString then attempts to read the following file;
B4X:
File.ReadString(dir, file)
file:/data/user/0/B4A.turbineBalancer/files/virtual_assets/index.html.unpacked
Note the additional 2 forward slashes are stripped so the file path is now invalid.

And if I combine the folder and the filename and use it as a URL I get a blank WebView. No error messages, just a blank.
B4X:
HelpView.LoadUrl(File.Combine(dir, file))

I tried many things but cannot seem to get around this hurdle.

It does not stop me carrying on with development, but it is a pita when I need to revert to release mode to work on parts of the code.
 
Upvote 0

johnf2013

Member
Licensed User
Longtime User
Can you upload a project with the help files?
Ok Erel
I am somewhat of a newbie with this forum stuff.
How do I upload and to where?
How much do you want? Should I just archive the entire project folder?
The .rar archive is 11Mb. If you want I can upload it to DropBox and send you a link?

The help file is from another project (Windows) and was not written for use on a mobile device. I am using it for development because I have not gotten around to writing the help for this app yet.
 
Upvote 0

johnf2013

Member
Licensed User
Longtime User
The best option is to create a small example that doesn't work for you and upload it directly to the forum.


This is only relevant if you can publish it in the forum.
Ok. It may take a while to create an example. I'll do it tonight after dinner.
 
Upvote 0

johnf2013

Member
Licensed User
Longtime User
Here is a small test which demonstrates the behaviour.
 

Attachments

  • WebViewTest.zip
    19.7 KB · Views: 190
Upvote 0

johnf2013

Member
Licensed User
Longtime User
It would seem to me that the only thing making the use of the virtual assets folder difficult is the file.Combine(dir, fname) method. If it did not strip out what it considers "redundant" forward slashes then file:// & jo.GetField("virtualAssetsFolder") could be used as the dir parameter. When combined with the filename returned by jo.RunMethod("getUnpackedVirtualAssetFile", Array As Object(filename)) the result can be successfully used as the parameter to HelpView.LoadUrl(filename).

All of this would then work in release and debug mode.
 
Upvote 0

johnf2013

Member
Licensed User
Longtime User
Yes, you are right. Disabling virtual assets works and now I can move on.
What got me confused is that (eventually) I could get WebView to load the correct file, either from the assets or the virtual assets depending on the compilation mode, however when it loaded from assets the file was correctly displayed but when it loaded from virtual assets it only displayed html source. No errors were returned.
Maybe in 100 years when I am a Java guru I will understand why.
 
Upvote 0

Erel

B4X founder
Staff member
Licensed User
Longtime User
It was indeed confusing. Your files include the UTF 8 BOM. If you remove it then it will show the frames but will fail to show the correct content.
 
Upvote 0

johnf2013

Member
Licensed User
Longtime User
Solved.....

To get my html files to display in a webview when they are hosted locally. The files are authored in Help-n-Manual. The output style is selected to be a mobile device compatible one, so it includes a lot of active content and query capability. They would display correctly if I uploaded them to my hosted server but they would not work at all if they were just placed into the assets folder.

After reading 10^6 words from as many forums, the solution ended up quite simple, and makes use of some code published here by Erel.

B4X:
Sub Globals
    Private HelpView As WebView
End Sub

Sub Activity_Create(FirstTime As Boolean)
    Activity.LoadLayout("TurbineBalancerHelp")
    HelpView.ZoomEnabled = True

    Dim jo As JavaObject = HelpView
    Dim settings As JavaObject = jo.RunMethod("getSettings", Null)
    Dim r As Reflector

    r.Target = settings
    r.RunMethod2("setAllowUniversalAccessFromFileURLs", True, "java.lang.boolean")

    HelpView.LoadUrl("file:///android_asset/index.html")
End Sub

That's it. I can now bundle my html documents into the apk, in this case a set of help files.
Thanks to everyone who offered solutions.
 
Upvote 0
Cookies are required to use this site. You must accept them to continue using the site. Learn more…