webview上でjavascriptからjavaメソッドを実行する
書籍でみかけたりはしてた。
が、頭の中で整理できてない気がするので、すっきりしようと。
1. webkit上にHTMLを表示
WebView webView = new WebView(this); webView.loadData("<h1>まずはHTMLを表示</h1>", "text/html", "utf-8"); setContentView(webView);
2. javascriptも表示
String html = "<script type='text/javascript'>alert('jsですよー');</script>\n" + "<h1>まずはHTMLを表示</h1>"; WebView webView = new WebView(this); // JavaScriptを有効にする webView.getSettings().setJavaScriptEnabled(true); webView.loadData(html, "text/html", "utf-8"); setContentView(webView);
ここで、webkit(webview)にjavaオブジェクトを登録する方法を確認してみる.
public void addJavascriptInterface (Object obj, String interfaceName) Use this function to bind an object to Javascript so that the methods can be accessed from Javascript.
<html> <head><title>JS calls Android Method</title></head> <body> <h1>JS on Android</h1> <script type="text/javascript"> document.write(roid.gps("<i>", "</i>")); </script> </body> </html>
public class WebkitTest extends Activity { /** Called when the activity is first created. */ @Override public void onCreate(Bundle icicle) { super.onCreate(icicle); WebView wv = new WebView(this); wv.getSettings().setJavaScriptEnabled(true); JsObj jo = new JsObj(this); wv.addJavascriptInterface(jo, "roid"); setContentView(wv); wv.loadUrl("http://www.adamrocker.com/android/js2android.html"); } class JsObj { private Context con; public JsObj(Context con) { this.con = con; } public String gps(String top, String end) { LocationManager locman = (LocationManager) con .getSystemService(Context.LOCATION_SERVICE); Location loc = locman.getCurrentLocation("gps"); int lat = (int) (loc.getLatitude() * 1000000); int lon = (int) (loc.getLongitude() * 1000000); return top + "緯度:" + lat + ", 経度: " + lon + end; } } }
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd"> <html> <head> <meta http-equiv="Content-Type" content="text/html; charset=utf-8"> <title>JsTest</title> </head> <body> <div id="container"> <div id="android_js"><h2>Broeser->Android</h2> <p id="android_js_get"></p> <form> <input type="button" value="送信" onClick="for_android()"> </form> <script type="text/javascript"> function for_android() { android.setString("for Browser"); } </script> </div> </div> </body> </html>
/* JavaScriptの許可と登録 */ webview.getSettings().setJavaScriptEnabled(true); Hoge hoge = new Hoge(); webview.addJavascriptInterface(hoge, "android"); /* WebPage指定 */ webview.loadUrl("file:///android_asset/index.html"); public class Hoge { public void setString(final String arg) { /* メインスレッドの実行キューにセット */ handler.post(new Runnable() { public void run() { textview.setText(arg); } }); } }
要するに、つながりかたは、
<script type="text/javascript"> javascript-object.android-method(); </script>
Hoge android-object = new Hoge(); webview.addJavascriptInterface(android-object, "javascript-object");
という雰囲気、うまくかけないけども。
3. javascriptからトーストを。
<uses-permission android:name="android.permission.INTERNET" />
<head> <meta http-equiv="Content-Type" content="text/html; charset=utf-8"> <script type="text/javascript"> function for_android() { android.appearToast("パンが焼けましたよ"); } </script> </head> <body> <input type="button" value="パンを焼く?" onClick="for_android()"> </body> </html>
package com.example.js2toast; import android.app.Activity; import android.os.Bundle; import android.content.Context; import android.webkit.WebView; import android.widget.Toast; public class Js2Toast extends Activity { public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); WebView webview = new WebView(this); webview.getSettings().setJavaScriptEnabled(true); Hoge hoge = new Hoge(this); webview.addJavascriptInterface(hoge, "android"); setContentView(webview); webview.loadUrl("http://yourhost/js2toast.html"); } public class Hoge { private Context con; public Hoge(Context con) { this.con = con; } public void appearToast(String message) { Toast.makeText(con, message, Toast.LENGTH_LONG).show(); } } }
WEBサーバ上にあるHTMLファイル内のJavascript内の文字列の
「パンが焼けましたよ」
がAndroidアプリ上のトーストに表示される。