JavaScript
Android
HTML5
webView

Android の WebView で addJavascriptInterface を使わず情報を渡す

WebView 使ってても Android 側から HTML (JavaScript) 側に,またはその逆方向に情報を渡したくなりますよね.

それを最も簡単に実現するのは addJavascriptInterface メソッドを使う方法だと思います.

しかし addJavascriptInterface は危険らしいです.詳しくは

を参照して下さい.

で,じゃあそれを使わないで何とかする方法を考えた時,HTML から Android への方向は,割と簡単に何とかなります.

しかし逆はちょっとしたハックをしなければなりません.その詳しい方法は

を参照して下さい.

この,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 に上げてます.

https://github.com/kaosf/android-webview/commit/77cf7f00fc5d239d0dfa8611690b77c327add342

WebView に関して色々実験してるリポジトリなので,関係ないコードも多いですけど…

あと,HTML から Android 側へ情報を渡すサンプルもついでに付随しております.お得!

HTML は sample-htmls ディレクトリ内の passing-a-string.html です.MainActivity.java 内の

webView.loadUrl("http://google.com");

部分を passing-a-string.html を指す URL に変えてやって下さいな.

このサンプルだけに特化したアプリを作っておきたい.

ちなみに結構まだまだ問題は残ってると思います.