2010-10-04 17 views
10

Sto provando a caricare/fare riferimento alle immagini dalla cartella delle risorse dell'app da una pagina HTML in una WebView. A differenza della maggior parte degli esempi, la pagina HTML non si trova nella cartella delle risorse ma viene caricata da un server tramite http. Lo sfondo di questa domanda sono alcuni miglioramenti delle prestazioni che dovrebbero ridurre il tempo di caricamento (e la quantità di dati trasferiti) caricando le immagini statiche direttamente dal dispositivo. Non sono sicuro che Android abbia alcune restrizioni qui perché esiste una certa possibilità di sfruttare l'app consentendo l'accesso all'archiviazione di file locale da una pagina Web caricata da remoto.Android: come fare riferimento alle immagini degli asset da una pagina html caricata in remoto nella webview

Prima ho provato a caricare le immagini usando <img src="file:///android_asset/myimage.png"> ma questo non è riuscito (per ovvi motivi). Il mio prossimo tentativo è stato quello di utilizzare una classe ContentProvider e immagini di riferimento usando <img src="content://com.myapp.assetcontentprovider/myimage.png">. Questo ContentProvider è implementato come segue:

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 
} 

Quando si carica la pagina HTML che posso vedere nel registro di debug che openFile() viene effettivamente attivato dal WebView e restituisce un oggetto valido ParcelFileDescriptor ma ancora non viene visualizzata l'immagine. Non ci sono messaggi di errore mostrati nel registro che mi dicono che WebView ha rifiutato di caricare/visualizzare l'immagine. Qualche idea se e come potrebbe funzionare?

+0

Hai trovato una risposta alla tua domanda iniziale (perché 'file: //' schema ro 'content: //' non funziona correttamente)? – Olegas

risposta

3

Questo è come lo faccio da parte java:

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

applausi

+0

Grazie per la risposta, ma non è proprio la soluzione che stavo cercando. Nella mia app la pagina HTML viene caricata da un URL su HTTP con myWebView.loadUrl(). O ti proponi di caricare il codice HTML con qualcosa come org.apache.http e poi metterlo manualmente nella webview con loadDataWithBaseURL()? – brotherli

+0

Potresti farlo. Ma dipende se l'HTML che stai scaricando usa link relativi o assoluti. Ah, assicurati che i tuoi beni siano nominati nella forma corretta. (niente spazi e caratteri strani ...) –

6

OK, grazie alla risposta di mufumbo ora trovato un lavoro trucco per combinare le risorse locali in pagine HTML caricate da remoto. Le pagine caricate utilizzando il metodo loadUrl() di WebView non caricano le immagini collegate al file: /// android_asset/... Per ovviare al problema, è possibile recuperare la pagina HTML utilizzando org.apache.http.client.methods.HttpGet.HttpGet() e quindi passarla a WebView con loadDataWithBaseURL(). In questo caso WebView caricherà le risorse collegate al file: /// android_asset/così come immagini e script via HTTP. Ecco il mio codice di visualizzazione web personalizzato:

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(); 
    } 
} 

Si prega di notare che l'intero recupero http è avvolto nella home-grown classe di utilità NetUtil.

Con questa classe è possibile eseguire il rendering di pagine HTML da un server Web e disporre di risorse statiche come immagini o fogli di stile caricati dalla cartella delle risorse dell'app per migliorare la velocità di caricamento e risparmiare larghezza di banda.

+0

Come hai fatto a far funzionare questo link per i link che sono stati cliccati all'interno della webview? Il mio funziona solo con il caricamento della prima pagina. – BradLaney

+0

@BradLaney @brotherli Dove ottengo la classe 'NetUtil' – GameDevGuru

Problemi correlati