1

I have a couple problems when loading urls on Webview on certain devices: such as emulators in general (Nexus 5, Android API 21) and, real devices (Huawei P30, Android 10).

EDIT: I am using minSDK 19. The urls is a https scheme.

binding.webview.apply {
        settings.javaScriptEnabled = true
        settings.loadWithOverviewMode = true
        settings.domStorageEnabled = true
        settings.databaseEnabled = true
        settings.setRenderPriority(WebSettings.RenderPriority.HIGH)
        settings.cacheMode = WebSettings.LOAD_CACHE_ELSE_NETWORK
        settings.setAppCacheEnabled(true)
        settings.layoutAlgorithm = WebSettings.LayoutAlgorithm.NARROW_COLUMNS
        settings.useWideViewPort = true
        settings.enableSmoothTransition()

        webViewClient = object : WebViewClient() {
            override fun onPageStarted(view: WebView?, url: String?, favicon: Bitmap?) {
                writeData(getString(XXX).toString())
                super.onPageStarted(view, url, favicon)
                binding.layoutProgress.progressLayout.show()
            }

            override fun onPageFinished(view: WebView?, url: String?) {
                super.onPageFinished(view, url)
                binding.layoutProgress.progressLayout.invisible()
            }
        }
    }

I am writting stuff on localStorage that need to have the browser via javascript, in order to load. I am not sure if here is the problem...

private fun writeData(value: String) {
    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) {
        binding.webview.evaluateJavascript(
            "localStorage.setItem('$XXX','$value');",
        ) { returnedValue -> Log.d("chromium1", "onReceiveValue: $returnedValue") } //returns null on the devices that does not work or value on the working devices
    } else {
        binding.webview.loadUrl("javascript:localStorage.setItem('$XXX','$value');")
    }
}

The chromium error that appears on devices that did not load is:

"Uncaught SecurityError: Failed to read the 'localStorage' property from 'Window': Access is denied for this document.",
"Unrecognized Content-Security-Policy directive 'navigate-to'. ", source: url.com (0)
"Unrecognized Content-Security-Policy directive 'navigate-to'.   ", source: url.com (0)
"The key "shrink-to-fit" is not recognized and ignored.", source: url.com (5)
"Refused to load the stylesheet 'https://fonts.googleapis.com/css?family=Source+Code+Pro:300,600&display=swap' because it violates the following Content Security Policy directive: "style-src 'self' 'unsafe-inline' https://widget.freshworks.com blob:". ", source: url.com (11)
"Uncaught SyntaxError: Use of const in strict mode.", source: url.something.js (21)

Thank you very much in advance.

Amg91
  • 165
  • 8
  • 25
  • Please elaborate on "certain devices" to help troubleshoot the issue. Is it happening only on specific device brand? Or maybe on certain API versions? – Pawel May 13 '20 at 17:29
  • Thank you very much. I updated the comment with some devices. – Amg91 May 13 '20 at 17:54
  • Just a thought here but could it have to do anything with your permission settings? If those aren't listed in the android manifest you'll have issues. – Vahalaru May 24 '20 at 01:37
  • What if you check another settings in Chromium browser? https://stackoverflow.com/questions/30481516/iframe-in-chrome-error-failed-to-read-localstorage-from-window-access-deni (and similar links). – CoolMind May 26 '20 at 15:26

3 Answers3

1

If consistency and reliability are what you want, maybe try GeckoView. It is a replacement WebView library built by Mozilla Firefox team to make pages act the same across all devices.

Not sure if you will encounter the same chromium errors on those devices.

It currently is supported on Android 4.3+, API 18+

https://wiki.mozilla.org/Mobile/GeckoView

Gibolt
  • 42,564
  • 15
  • 187
  • 127
  • 1
    I will try it right away and let you know. Thank you very much. – Amg91 May 25 '20 at 18:48
  • I am getting FAILED BINDER TRANSACTION. Is there a way I can get the implementation of the posted code on GeckoView please? – Amg91 May 25 '20 at 19:45
  • Sounds like an improvement. Look at https://stackoverflow.com/a/23424889/974045 How big is the data you are passing? Try testing once with a tiny piece of data. – Gibolt May 25 '20 at 21:56
  • Is there a way you could post the translation from webview to geckoview? I am still getting the error. Thanks. – Amg91 Jun 02 '20 at 21:09
  • I haven't directly worked with it, wish you luck. If you own the site being loaded, you could alternatively pass your value via the url `?param=1` and use native web storage or pass it on each new visit and store the value in your app – Gibolt Jun 03 '20 at 00:13
0

This might be because of the url being loaded using webview.

  1. Add @xml/network_security_config into your resources:

     <network-security-config>
        <base-config cleartextTrafficPermitted="true">
            <trust-anchors>
                <certificates src="system" />
                <certificates src="user"/>
            </trust-anchors>
        </base-config>
    </network-security-config>
    
  2. Add this security config to your Manifest like this:

    <application
        ...
        android:networkSecurityConfig="@xml/network_security_config"
        ...>
    
        ...
    </application>
    
shruity
  • 178
  • 1
  • 2
  • 16
0

The first error seems to be you have not given the path for accessing the cache.

Uncaught SecurityError: Failed to read the 'localStorage' property from 'Window': Access is denied for this document."

If I am not wrong, inorder to store data in cache, we have to explicitly give the access via setAppCachePath.

And the description says the following.

Sets the path to the Application Caches files. In order for the Application Caches API to be enabled, this method must be called with a path to which the application can write. This method should only be called once: repeated calls are ignored.

The path may be something like this (may not be exactly the same).

val cache_path = getApplicationContext().getFilesDir().getAbsolutePath() + "/cache"

settings.setAppCacheEnabled(true)
settings.setAllowFileAccess(true)
settings.setAppCachePath(cache_path)
Sreehari
  • 5,621
  • 2
  • 25
  • 59