WebView 使ってても Android 側から HTML (JavaScript) 側に,またはその逆方向に情報を渡したくなりますよね.
それを最も簡単に実現するのは addJavascriptInterface
メソッドを使う方法だと思います.
しかし addJavascriptInterface
は危険らしいです.詳しくは
を参照して下さい.
で,じゃあそれを使わないで何とかする方法を考えた時,HTML から Android への方向は,割と簡単に何とかなります.
しかし逆はちょっとしたハックをしなければなりません.その詳しい方法は
- AppとWebViewの相互の機能の呼び方、そしてhistory.back()について(iPhone・Android) | ひささん日記
- Day After Neet: AndroidのWebViewでJavaScriptを実行する
を参照して下さい.
この,alert を無理矢理抑えこむ方法を使うとちょっと問題が発生します.alert が全て発生しなくなります.
なので,今回ここで紹介するのはそれを回避する方法です.
方法はいたって簡単.onJsAlert
メソッドは,alert に渡された文字列を受け取ることが出来ます.こいつを使って場合分けして運用で回避です.
...
public class MainActivity extends Activity {
...
protected void onCreate(Bundle savedInstanceState) {
...
webView.setWebChromeClient(new WebChromeClient() {
@Override
public boolean onJsAlert(WebView view, String url, String message, JsResult result) {
if (message.equals("net.kaosfield.wv1")) {
try {
Log.d("wv1", "url: " + url + ", message: " + message);
return true;
} finally {
result.confirm(); // in order not to alert
}
}
else {
return false;
}
}
...
});
...
}
...
}
したがって,この処理に突入するために使う
view.loadUrl("javascript:alert(window.method(\"" + argument + "\"))");
が用いている window.method
関数は,必ず "net.kaosfield.wv1"
を返すようにしておきます.
逆に言えば alert にこの文字列を表示することだけが出来なくなります.なので,一意でかつ絶対に alert で出したくならない・出ることがない文字列にしておく必要があります.
このサンプルを GitHub に上げてます.
WebView に関して色々実験してるリポジトリなので,関係ないコードも多いですけど…
あと,HTML から Android 側へ情報を渡すサンプルもついでに付随しております.お得!
HTML は sample-htmls
ディレクトリ内の passing-a-string.html
です.MainActivity.java
内の
webView.loadUrl("http://google.com");
部分を passing-a-string.html
を指す URL に変えてやって下さいな.
このサンプルだけに特化したアプリを作っておきたい.
ちなみに結構まだまだ問題は残ってると思います.