2

地図を表示する Android アプリがあります。マップは、解像度を維持するためにマップごとに 100 タイルにスライスされた高解像度画像です。現在、アセット フォルダー内の個別のフォルダーに各マップがあります。これにより apk が巨大になるため、これらの画像をメインの apk 拡張ファイルに移動したいと考えています。現在、次のコードを使用して webview に画像を表示し、webview でタイルをつなぎ合わせています。

class ShowMapTask extends AsyncTask<String, Void, String> {

    @Override
    protected String doInBackground(String... maps) {
        String html = "<html><table cellpadding=\"0\" border=\"0\" cellspacing=\"0.0\">";
        for (int i = 0; i < 10; i++) {
            html += "<tr>";
            for (int j = 0; j < 10; j++)
                html += "<td><img src=\"maps/" + maps[0] + "/slice_" + i
                        + "_" + j + ".png\"></td>";
            html += "</tr>";
        }
        return html + "</table></html>";
    }

    @Override
    protected void onPostExecute(String result) {
        WebView wv = (WebView) context.findViewById(R.id.webView);
        wv.getSettings().setSupportZoom(true);
        wv.getSettings().setBuiltInZoomControls(true);
        wv.getSettings().setUseWideViewPort(true);
        wv.getSettings().setLoadWithOverviewMode(true);
        wv.loadDataWithBaseURL("file:///android_asset/", result,
                "text/html", "utf-8", null);
        super.onPostExecute(result);
    }
}

apk 拡張ファイルに移行するにはどうすればよいですか? obbをSDカードに解凍せずに画像を使用することは可能ですか?

4

2 に答える 2

3

元の回答がコメントに格下げされたため、新しい回答で回答してみます。理由はわかりませんが、現在、API 10 以下と API 11 以上のソリューションがあります。明確にするためにコードを投稿します。

API 11 以降の場合、webview クライアントで ShouldInterceptRequest をオーバーライドするだけです。

API 10 以下では、この http リスナーhttp://elonen.iki.fi/code/nanohttpd/を使用します。

2 つのアプローチをまとめると、関連するコードは次のとおりです。

final String assetPrefix = "file:///android_asset/";
final String httpPrefix = "http://localhost:8001";

// for me this part is in onCreateView after the webview settings bit...
{

    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.HONEYCOMB)
        webView.setWebViewClient(new HoneyCombWebViewClient());
    else
        webView.setWebViewClient(new MyWebViewClient());    

    webViewLoadUrl();
}

private void webViewLoadUrl() {
    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.HONEYCOMB) {

        curURL = assetPrefix + curFileName;


        webView.loadUrl(curURL);
    }
    else
    {
        curURL = httpPrefix + '/' + curFileName;

        String str = assetFileToString(curFileName);        
        webView.loadDataWithBaseURL(httpPrefix, str, "text/html", "UTF-8", null);    
    }
}

// then for the WebViewClient
private class HoneyCombWebViewClient extends MyWebViewClient {

    public WebResourceResponse shouldInterceptRequest(WebView view, String url)
    {
                    // remove the asset prefix from the url
        String fileName = url.substring(assetPrefix.length() - 1);

                    // ExpansionFiles is the pointer to your ZipResourceFile
        InputStream inputStream = ExpansionFiles.getWebResource(fileName);

        if (url.endsWith("jpg") || url.endsWith("png"))
            return new WebResourceResponse("image/*", "base64", inputStream);

        return super.shouldInterceptRequest(view, url);
    }
}

private class MyWebViewClient extends WebViewClient {
    @Override
    public boolean shouldOverrideUrlLoading(WebView view, String url) {

            else if (url.startsWith(httpPrefix)) {

            curURL = url;

            String str = assetFileToString(url.substring(httpPrefix.length() + 1));

            webView.loadDataWithBaseURL(httpPrefix, str, "text/html", "UTF-8", null); 
            return true;
        }
        else if (url.startsWith(assetPrefix)){
            curURL = url;

            view.loadUrl(url);
            return true;        
        }
        // else.....
    }
}

最後に、NanoHTTPD を使用するには、メソッド serve を見つけて、拡張ファイルから入力ストリームをファイルに返します。

public Response serve( String uri, String method, Properties header, Properties parms, Properties files )
{
    InputStream data = ExpansionFiles.getWebResource(uri);

    String mimeType;
    if (uri.endsWith("jpg") || uri.endsWith("png"))
        mimeType = "base64";
    else if (uri.endsWith("css"))
        mimeType = "text/css";
    else if (uri.endsWith("js"))
        mimeType = "text/javascript";
    else
        mimeType = "text/html";

    return new Response( HTTP_OK, mimeType, data );
}

トップレベルのどこかにコンストラクターを呼び出します。

if (Build.VERSION.SDK_INT < Build.VERSION_CODES.HONEYCOMB) {
    // this for loading images from expansion file under webview in API 10
    try
    {
        webServer = new NanoHTTPD(8001, new File("."));
    }
    catch( IOException ioe )
    {
        System.err.println( "Couldn't start server:\n" + ioe );
        System.exit( -1 );
    }
}

ああ、NanoHTTPD からメイン メソッドを削除する必要があります。

これがお役に立てば幸いです。それは私にとって長くて苦痛なプロセスでした....

于 2012-11-28T22:22:47.263 に答える
1

JOBBツールを使用して拡張ファイルをパックし、StorageManagerを使用してそれをマウントすることは、良い代替手段です。その後、拡張ファイル内のファイルは、ファイル システム内の通常のファイルとしてアクセスできるようになります。この場合、拡張ファイルの解凍は必要ありません。

于 2013-11-05T16:06:29.717 に答える