AndroidのWebViewでassets内のhtmlを#つきで読み込む

アプリ内ヘルプで利用しようと、assetsフォルダにhtmlや画像一式を入れて、webViewで

webView.loadUrl("file:///android_asset/index.html");

とかしますよね。file://じゃなくてfile:///なのがポイントです。

これならこのまま動くんですが。

問題は、URLがindex.html#hogeとかの場合です。つまりアンカーリンクを指定した場合です。

何故かファイルが見つからないとなってしまう。

ぐぐってみたら、どうも3.xあたりからのバグのようで、4.2では直ってましたが、現時点でたいていのターゲットは4.0だと思うので問題になります。

遅延させてロードさせろとか色々解決策を書いてる人はいましたが、どれも実際に組み込んでみるとダメでした。

結果、試行錯誤の末、以下のような手順を取る事に。

1.ページエラーが生じたとき、URLに#が入ってた場合はとりあえず#抜きのURLを表示する。

2.javascriptで指定のnameタグまでスクロールさせる

実際のコードは以下の通りです。

クラス内にanchorというインスタンス変数を用意しておいて、onCreateなどで以下のようにWebViewを初期化します。

webView = (WebView) findViewById(R.id.web);
webView.setWebViewClient(new WebViewClient() {
@Override
public void onPageStarted(WebView view, String url, Bitmap favicon) {
super.onPageStarted(view, url, favicon);
}
@Override
public void onPageFinished(WebView view, String url) {
super.onPageFinished(view, url);
if (!anchor.equals("")) {
view.loadUrl("javascript:location.hash=\"" + anchor + "\"");
}
anchor = "";
}
@Override
public void onReceivedError(WebView view, int errorCode, String description, String failingUrl) {
super.onReceivedError(view, errorCode, description, failingUrl);
loadUrl(failingUrl);
}
});

loadUrlの中身は下記の通りです。

private void loadUrl(String url) {
int index = url.indexOf("#");
if (index == -1) {
anchor = "";
} else {
anchor = url.substring(index + 1);
url = url.substring(0, index);
}
webView.loadUrl(url);
}

同じ事で悩んでる人はお試しください。

こちらの記事もどうぞ