Kitkat mata: No se permite cargar el recurso local: file: ///android_asset/webkit/android-weberror.png

Tengo una aplicación que usa WebViews. Cambié mi targetAPI de 18 a 19 y actualmente estoy probando el nuevo 4.4. Por alguna razón, recibo este error: Not allowed to load local resource: file:///android_asset/webkit/android-weberror.png en 4.4 pero no en 4.3, ¿alguien tiene idea de por qué?

Como realmente no sé por dónde empezar a buscar, no puedo dar el código completo. Puede tener algo que ver con el shouldInterceptRequest(Webview, String) en el WebViewClient, pero no estoy muy seguro. Si sé más, actualizaré la pregunta.

“No se permite cargar el recurso local” es un error de origen de seguridad. El KitKat WebView tiene restricciones de seguridad más fuertes y parece que se están activando. FWIW Intenté simplemente cargar un archivo: /// android_asset URL y funcionó bien.

¿Llamaste por casualidad a alguna de las API de WebSettings relacionadas con archivos (como setAllowFileAccess (false))? ¿Estás intentando cargar el recurso desde una https: URL?

Un poco de intrusismo, pero trabajé alrededor de este problema al introducir un “token único” e implementar el WebViewClient con una anulación de shouldInterceptRequest .

Primero, cambie la URL del file:///android/asset a una ruta relativa con un token de identificación única:

  

Luego, anule shouldInterceptRequest siguiente manera:

 // Injection token as specified in HTML source private static final String INJECTION_TOKEN = "**injection**"; webView.setWebViewClient(new WebViewClient() { @Override public WebResourceResponse shouldInterceptRequest(WebView view, String url) { WebResourceResponse response = super.shouldInterceptRequest(view, url); if(url != null && url.contains(INJECTION_TOKEN)) { String assetPath = url.substring(url.indexOf(INJECTION_TOKEN) + INJECTION_TOKEN.length(), url.length()); try { response = new WebResourceResponse( "application/javascript", "UTF8", getContext().getAssets().open(assetPath) ); } catch (IOException e) { e.printStackTrace(); // Failed to load asset file } } return response; } }); 

Es probable que esto reduzca ligeramente el rendimiento de WebView, ya que llamamos a contains() en cada recurso que se intenta cargar, pero es la única solución que he encontrado para este problema.

Descubrí que tenía este problema en KitKat cuando usaba webview.loadData() . Si en su lugar utilicé webview.loadDataWithBaseURL() (utilicé “file: /// android_asset /” como baseURL), entonces el problema desapareció.

Los métodos setAllowFileAccess() , setAllowFileAccessFromFileURLs() y setAllowUniversalAccessFromFileURLs() no tuvieron ningún efecto que pudiera ver.

AQUÍ ESTÁ LA SOLUCIÓN: este problema se produce cuando intenta cargar un archivo de proyectos de la biblioteca. Si su aplicación depende de una biblioteca donde residen los archivos webview y html, debe incluir activos de ese proyecto de biblioteca en el proyecto de aplicación principal durante la comstackción. Por ejemplo, IntelliJ tiene una opción para hacer esto. En la configuración del comstackdor “Incluir activos de las dependencias en APK”, pero asegúrese de que los archivos de sus activos tengan nombres diferentes a los de la aplicación principal. No desea que la aplicación principal anule el index.html del proyecto de la biblioteca.

Puede ser necesario agregar un permiso

a un manifiesto

Este permiso se aplica a partir del nivel API 19.

La solución a continuación funciona para mí.

 webview.loadDataWithBaseURL( baseUrl, htmlStr, "text/html", "UTF-8", ""); 

donde baseUrl es su dominio externo, no file: /// android_asset / (es decir, http://a.domain.com ).

No disponible en ese momento, ahora funciona (aunque no se recomienda):

 webView.getSettings().setMixedContentMode(WebSettings.MIXED_CONTENT_ALWAYS_ALLOW); 

Esto es lo que dice el documento sobre setMixedContentMode:

Configura el comportamiento de WebView cuando un origen seguro intenta cargar un recurso desde un origen inseguro. De forma predeterminada, las aplicaciones que se dirigen a KITKAT o por debajo de forma predeterminada a MIXED_CONTENT_ALWAYS_ALLOW. Las aplicaciones que se dirigen a LOLLIPOP se asignan por defecto a MIXED_CONTENT_NEVER_ALLOW. El modo de operación preferido y más seguro para WebView es MIXED_CONTENT_NEVER_ALLOW y no se recomienda el uso de MIXED_CONTENT_ALWAYS_ALLOW.

Sin embargo, esto podría no responder a la pregunta original; parece que la restricción solo comenzó con Lollipop.

Encontré una buena solución en este enlace: http://trentmilton.com/android-webview.html

Un resumen de la solución es algo así como:

 WebView webView = new WebView(this); // this is the context webView.getSettings().setDomStorageEnabled(true); 

Espero que ayude