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


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