2010-10-04 23 views
10

Estoy intentando cargar/referenciar imágenes desde la carpeta de activos de la aplicación desde una página HTML en una WebView. A diferencia de la mayoría de los ejemplos, la página HTML en sí no se encuentra en la carpeta de activos, sino que se carga desde un servidor a través de http. El trasfondo de esta pregunta son algunas mejoras de rendimiento que deberían reducir el tiempo de carga (y la cantidad de datos transferidos) cargando imágenes estáticas directamente desde el dispositivo. No estoy seguro si Android tiene algunas restricciones aquí porque existe una cierta posibilidad de explotar la aplicación al permitir el acceso al almacenamiento de archivos local desde una página web cargada remotamente.Android: Cómo hacer referencia a imágenes de activos desde una página html cargada remotamente en webview

Primero intenté cargar imágenes usando <img src="file:///android_asset/myimage.png"> pero esto falló (por razones obvias). Mi próximo intento fue usar una clase ContentProvider e imágenes de referencia usando <img src="content://com.myapp.assetcontentprovider/myimage.png">. Este ContentProvider se implementa de la siguiente manera:

public class AssetContentProvider extends ContentProvider 
{ 
private static final String URI_PREFIX = "content://com.myapp.assetcontentprovider"; 

public static String constructUri(String url) { 
    Uri uri = Uri.parse(url); 
    return uri.isAbsolute() ? url : URI_PREFIX + url; 
} 

@Override 
public ParcelFileDescriptor openFile(Uri uri, String mode) throws FileNotFoundException { 
    Log.d("AssetContentProvider", uri.getPath()); 
    try { 
     return getContext().getAssets().openFd(uri.getPath().substring(1)).getParcelFileDescriptor(); 
    } catch (IOException e) { 
     Log.d("AssetContentProvider", "IOException for " + uri.getPath()); 
     throw new FileNotFoundException(); 
    } 
} 

// more methods irrelevant for this post 
} 

Al cargar la página HTML que puedo ver en el registro de depuración que se activa realmente openFile() de la vista Web y devuelve un objeto válido ParcelFileDescriptor pero todavía no se muestra la imagen. No hay mensajes de error en el registro que me digan que WebView se negó a cargar/mostrar la imagen. ¿Alguna idea de si esto podría funcionar?

+0

¿Encontró una respuesta a su pregunta inicial (por qué 'file: //' scheme ro 'content: //' no funciona correctamente)? – Olegas

Respuesta

3

Esta es la forma en que hago en la parte java:

cadena myHTML = "< img src = \" file: ///android_asset/myimage.jpg \ ""; myWebView.loadDataWithBaseURL ("file: /// android_asset /", myHTML, "text/html", "UTF-8", "");

aplausos

+0

Gracias por su respuesta, pero no es la solución que estaba buscando. En mi aplicación, la página HTML se carga desde una URL a través de HTTP con myWebView.loadUrl(). ¿O propone cargar el código HTML con algo como org.apache.http y luego ponerlo manualmente en la vista web con loadDataWithBaseURL()? – brotherli

+0

Podrías hacer eso. Pero depende si el HTML que está descargando usa enlaces relativos o absolutos. Ah, asegúrese de que sus activos tengan el nombre en la forma correcta. (sin espacios ni caracteres extraños ...) –

6

bien, gracias a la respuesta de mufumbo ahora encontraron un trabajo hackear para mezclar los activos locales en las páginas HTML de forma remota cargados. Las páginas cargadas con el método loadUrl() de WebView no cargan imágenes vinculadas con el archivo: /// android_asset/... Como solución alternativa puede recuperar la página HTML utilizando org.apache.http.client.methods.HttpGet.HttpGet() y luego pasarla a WebView con loadDataWithBaseURL(). En este caso, WebView cargará recursos vinculados con file: /// android_asset/así como también imágenes y scripts a través de HTTP. Aquí está mi código de vista web personalizada:

public class CustomWebView extends WebView { 
    private String mURL; 

    public void loadUrlWithAssets(final String url) { 
     // copy url to member to allow inner classes accessing it 
     mURL = url; 

     new Thread(new Runnable() { 
      public void run() { 
       String html; 
       try { 
        html = NetUtil.httpGETResponse(mURL); 

        // replace some file paths in html with file:///android_asset/... 

        loadDataWithBaseURL(mURL, html, "text/html", "UTF-8", ""); 
       } 
       catch (IOException e) { 
        Log.e("CustomWebView.loadUrlWithAssets", "IOException", e); 
       } 
      } 
     }).start(); 
    } 
} 

Tenga en cuenta que todo el ir a buscar http está envuelto en la clase de utilidad de cosecha NetUtil.

Con esta clase es posible representar páginas HTML desde un servidor web y tener algunos recursos estáticos como imágenes o hojas de estilo cargadas desde la carpeta de activos de la aplicación para mejorar la velocidad de carga y ahorrar ancho de banda.

+0

¿Cómo se las arregló para hacer que esto funcione para los enlaces en los que se hace clic dentro de la vista web? El mío solo funciona en la carga de la primera página. – BradLaney

+0

@BradLaney @brotherli ¿De dónde saco la clase 'NetUtil' – GameDevGuru

Cuestiones relacionadas