Android Question [Solved]WebView cannot access local web page files in Android 10

cqzhongcheng

Member
Licensed User
hi:

i use webview to show local web page files at File.DirDefaultExternal.
the code is : webview1.LoadUrl("file:///storage/emulated/0/Android/data/pldata.check/files/web/index.html")
in Android 9 ,this code run success
but in Android 10 , failed. the fail message is "net::ERR_ACCESS_DENIED"
why?

thanks.
 

cqzhongcheng

Member
Licensed User
sorry, the code is:
B4X:
webview1.LoadUrl("file://" & File.Combine(File.DirDefaultExternal, "/web/index.html")

I guess the path obtained by file. Combine is wrong
 
Upvote 0

cqzhongcheng

Member
Licensed User
i find other article , some say the code should use: XUI.FileUri
but i can't find this function in whitch library ?
i check library XUI ,XUI Views , XUI2D , there have no this function: XUI.FileUri
 
Upvote 0

FrostCodes

Active Member
Licensed User
sorry, the code is:
B4X:
webview1.LoadUrl("file://" & File.Combine(File.DirDefaultExternal, "/web/index.html")

I guess the path obtained by file. Combine is wrong
I think Erel warned that you should never use DirDefaultExternal instead why not Use XUI to load the URL and also if you need to copy out the files, copy it using runtime permissions or copy it to the DirInternal.
 
Upvote 0

cqzhongcheng

Member
Licensed User
i change the manifest file :
<uses-sdk android:minSdkVersion="14" android:targetSdkVersion="30"/>
to
<uses-sdk android:minSdkVersion="14" android:targetSdkVersion="29"/>

then the webview show normal

But this is not the best solution. If WebView is really unavailable in the future, many parts of my app will have to be changed
Don't know if other friends have a better way?
 
Upvote 0

DonManfred

Expert
Licensed User
Longtime User
Upvote 0

drgottjr

Expert
Licensed User
Longtime User
i find this article: https://www.b4x.com/android/forum/threads/webview-access-denied-with-api-30.132424/#content
it say "Webview- Access Denied with API 30"
is it true ?
if use loadhtml function ,how can i load js and css file ?
NO, NO, NO. you totally misread the thread. it is the "file://" scheme that is not allowed. webview can load local files with api 30. several methods are available, including the new assetloader api. i provided examples in that post and elsewhere.
 
Upvote 0

cqzhongcheng

Member
Licensed User
NO, NO, NO. you totally misread the thread. it is the "file://" scheme that is not allowed. webview can load local files with api 30. several methods are available, including the new assetloader api. i provided examples in that post and elsewhere.
the first method "loadhtml" , if the html contains css file, js file and image file ,then loadhtml will not show correct

the second method "androidx.webkit.WebViewAssetLoader " , I can't use Java technology. I tried it without success , I'm waiting. B4a can give a convenient calling method

another question : if the html file put in assert directory , It is very inconvenient to reference CSS, JS and image file
Thank you for your answer !
 
Last edited:
Upvote 0

cqzhongcheng

Member
Licensed User
Don´t use Webview. Build a native UI instead.
My technology is not good. It's difficult for me to make a beautiful interface with the native UI.
HTML5 has many beautiful free frameworks .
I don't know if there is a free beautiful native b4a UI framework to use ?
Thank you for your answer!
 
Upvote 0

drgottjr

Expert
Licensed User
Longtime User
the first method "loadhtml" , if the html contains css file, js file and image file ,then loadhtml will not show correct

the second method "androidx.webkit.WebViewAssetLoader " , I can't use Java technology. I tried it without success , I'm waiting. B4a can give a convenient calling method

another question : if the html file put in assert directory , It is very inconvenient to reference CSS, JS and image file
Thank you for your answer !

your first mistake is thinking that a webview is a substitute for a browser.
it isn't. android's documentation is quite clear about this. it does not
do everything that a browser does. and it often does not do what it says
it will do.

if you load your html, css, js and images correctly before calling loadhtml(),
the resulting string will be a correctly rendered webpage. (note: if there is
a feature in your webpage that is not supported by webview, the display will
not be correct.)

as for your dislike of being inconvenienced, i certainly sympathize with you,
but you've chosen the wrong tool for the job at hand.

in any case, attached please find a simple example showing that you can
have separate html text, .js, .css and image files loaded and displayed correctly
with webview.loadhtml() in android 30.
 

Attachments

  • webviewload.zip
    46.3 KB · Views: 430
Last edited:
Upvote 0

cqzhongcheng

Member
Licensed User
your first mistake is thinking that a webview is a substitute for a browser.
it isn't. android's documentation is quite clear about this. it does not
do everything that a browser does. and it often does not do what it says
it will do.

if you load your html, css, js and images correctly before calling loadhtml(),
the resulting string will be a correctly rendered webpage. (note: if there is
a feature in your webpage that is not supported by webview, the display will
not be correct.)

as for your dislike of being inconvenienced, i certainly sympathize with you,
but you've chosen the wrong tool for the job at hand.

in any case, attached please find a simple example showing that you can
have separate html text, .js, .css and image files loaded and displayed correctly
with webview.loadhtml() in android 30.

Thank you very much for your reply !
The code you gave solved the problem perfectly, thank you !
 
Upvote 0

williamxvii

New Member
your first mistake is thinking that a webview is a substitute for a browser.
it isn't. android's documentation is quite clear about this. it does not
do everything that a browser does. and it often does not do what it says
it will do.

if you load your html, css, js and images correctly before calling loadhtml(),
the resulting string will be a correctly rendered webpage. (note: if there is
a feature in your webpage that is not supported by webview, the display will
not be correct.)

as for your dislike of being inconvenienced, i certainly sympathize with you,
but you've chosen the wrong tool for the job at hand.

in any case, attached please find a simple example showing that you can
have separate html text, .js, .css and image files loaded and displayed correctly
with webview.loadhtml() in android 30.

what if a user's phone does not have "android 30"? I have a webapp with a tons of html and css and it is dependent on javascript functions. I managed to compile it a few years ago. However it is over 250 mb and I need to use extension files so I'm really worried how to implement this. I'v downloaded your attachment... I have no clue atm to be honest regarding what you mean about [how to] "load html, css, js, images" and .mp3 files before calling loadhtml(). I mean specifically calling it from a compressed .obb file...

I was going to use caching so that I can use edge side includes on a hosted vps for ad revenue, but have decided I would rather sell the app, that way I do not have the hassle of dealing with ad revenue or managing a server with traffic, it would be a waste of time.
 
Upvote 0

drgottjr

Expert
Licensed User
Longtime User
if you intend to distribute the app via play, it has to target
sdk30. so that solves problem #1. if you use another
distribution source, then you can probably set the target
sdk to whatever you want, and all your problems are
solved.

the workaround which involves using webview.loadhtml()
relies on concatenating the files necessary to construct
a web page, eg, with a stringbuilder. this is exactly how a
web browser functions in reality: the end result is a giant
string of bytes which is rendered as a "page". instead
of the browser's loading each resource (html, css, js, jpg)
one by hand and rendering the page, here, you add all the
files into a big string and load it all at once into the webview
using webview.loadhtml( stringbuilder.tostring ).
others seem to understand how to do it (eg, the guy in the
post above yours), i'm sure you can grasp the concept too.
i'm not saying it's pretty.

keeping files in file.direxternal is out. from google's point
of view, this is a security risk: a malicious app can easily
see what's there. frankly, a malicious enough app can
probably see whatever it wants to see, but i'm just the
messenger here.

i only know what an .obb file is, not what happens to it once
copied into the app's space on disk. i don't know how it
appears to the app or how one goes about loading some
resource therein. you'll have to test it.
 
Upvote 0

williamxvii

New Member
if you intend to distribute the app via play, it has to target
sdk30. so that solves problem #1. if you use another
distribution source, then you can probably set the target
sdk to whatever you want, and all your problems are
solved.

the workaround which involves using webview.loadhtml()
relies on concatenating the files necessary to construct
a web page, eg, with a stringbuilder. this is exactly how a
web browser functions in reality: the end result is a giant
string of bytes which is rendered as a "page". instead
of the browser's loading each resource (html, css, js, jpg)
one by hand and rendering the page, here, you add all the
files into a big string and load it all at once into the webview
using webview.loadhtml( stringbuilder.tostring ).
others seem to understand how to do it (eg, the guy in the
post above yours), i'm sure you can grasp the concept too.
i'm not saying it's pretty.

keeping files in file.direxternal is out. from google's point
of view, this is a security risk: a malicious app can easily
see what's there. frankly, a malicious enough app can
probably see whatever it wants to see, but i'm just the
messenger here.

i only know what an .obb file is, not what happens to it once
copied into the app's space on disk. i don't know how it
appears to the app or how one goes about loading some
resource therein. you'll have to test it.
According to my understanding of Google Play, which is where I initially would publish, is that I would need an extension file placed (an obb compressed, butvredeabke resource on the local device then according to you statement, use a stringbuilder to load that in a WebView?

Is it possible you can create an example of how to implement such a stringbuilder, drawing the concatenated info from an obb file? I apologise for asking this also this 'b4x' is it an API that accepts different languages or is it such a thing as just mentioned, with its own unique syntax and semantics, too? Is there someone I could hire to create such an obb file to load a concatenated string from for my WebView app to work. I am sure with assistance I can solve this, but for me android syntax is very unique and not for me at least very human-friendly. Not that it is unfriendly it's just really beefy and involved I guess, not sure how to describe it, it's certainly not straightforward...
 
Upvote 0

drgottjr

Expert
Licensed User
Longtime User
your description of how you would use the obb file may or may
not be feasible. you'd have to ask somebody who knows. you need
to start a new thread for that. you've glommed onto a different
thread having nothing to do with obb use. any obb mavens would
have missed your post because it has nothing to do with this thread.

i see some references to what appears to be a possible api for obb.
that means there may be a github project out there. that means someone
here might have wrapped it (or could be persuaded to wrap it). that would
give you a hook for use with b4a. that means a ready-to-use library.

in the absence of an existing library, there is a "for hire" forum here.
you should make inquiries there.

i think success or failure hinges on how android sees your obb once in
place (wherever that might be). without getting your hopes up, i would
tend to think android would let you treat the obb as a kind of file system,
perhaps along the lines of file.dirasset. which means concatenating
files could work.

as for webview.loadhtml(), a couple of the links above your post should
provide an example for you. without getting into the minutiae of forum
etiquette, you're supposed to search (search box above) first, study the
links, put something together and run it. if it fails, you post your code,
and somebody here tries to fix it. sometimes a nice someone will save
you the search time by providing the link.

obb aside, i'm guessing you understand how file concatenation would
work with a stringbuilder. if not see if the example in post #13 help. i
claim it did when i wrote it, but memory is fading. if not, start a new thread.
we're starting to wander wiith this one.
 
Upvote 0

William Lancee

Well-Known Member
Licensed User
Longtime User
Since the original poster @cqzhongcheng is happy with the solution this thread should be closed to further discussion.

However, it seems that a new member (my namesake) @williamxvii is a bit lost.
I think he has trouble with his existing webapp using Android Studio (?), and is investigating B4X as a solution.

He should start a new question on the B4A Forum for that, but he needs to learn more about B4X first.

1. B4X is a different programming language than Java used in Android Studio, more like VisualBasic than anything else.
A very good start is one of the instructional booklets https://www.b4x.com/android/files/Booklets.zip
2. Webapps are not similar to B4X apps that use Webviews
3. Try to follow Forum guidelines https://www.b4x.com/android/forum/threads/forum-guidelines.55632/

Welcome William. You have entered a wonderful new world of programming possibilities.
 
Upvote 0
Top