[Android] JavaScript との連携 - WebView ================================================================================ WebView を使うことで、レイアウトの中で、HTML を表示することができる。 自分のアプリケーションから独立しているブラウザーでは、アプリケーションから HTML を制御することはできないが、アプリケーション内の WebView を使えば、アプリケーシ ョンから HTML の制御は可能になる。たとえば、JavaScript と Java のプログラムとを 連携させることができる。 JavaScript との連携方法としては次の 2 つがある。 (1) JavaScript から Java のメソッド呼び出し (2) Java から JavaScript の関数呼び出し どちらも、以下の処理を行う必要がある。 ・WebView オブジェクトを取得し、HTML の中で JavaScript を使えるようにする 上記を行ったのちの、それぞれの概要は以下のとおり。 (1) JavaScript から Java のメソッド呼び出し ・JavaScript から使える Java のメソッドのオブジェクトを登録 WebView.addJavascriptInterface(オブジェクト, インターフェース名); (2) Java から JavaScript の関数呼び出し ・つぎのメソッドを使う WebView.loadUrl("javascript:関数名(引数リスト)"); JavaScript を扱う上での注意点として、以下をあげる。 ・alert や prompt を使うときには設定が必要 WebView.setWebChromeClient(WebChromeClient オブジェクト); ・JavaScript インターフェースのメソッドで、アクティビティのビューを操作する場合 はハンドラー Handler オブジェクトが必要 Handler.post(new Runnable() { public void run() { // ビューの操作 } }); WebView を使う上での注意点 ・マニフェストに次の権限を設定する <uses-permission android:name="android.permission.INTERNET"/> ▲ アクティビティ 上記の概要に基づいたクラス。 □ WebViewJavaScript01Activity.java --- package jp.marunomaruno.android.webviewjavascript; import android.app.Activity; import android.os.Bundle; import android.os.Handler; import android.view.View; import android.webkit.WebChromeClient; import android.webkit.WebSettings; import android.webkit.WebView; public class WebViewJavaScript01Activity extends Activity { private WebView webView1; // (1) /** Called when the activity is first created. */ @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.main); Handler handler = new Handler(); // (2) webView1 = (WebView) findViewById(R.id.webView1); webView1.loadUrl("file:///android_asset/index.html"); // (3) WebSettings settings = webView1.getSettings(); // (4) settings.setJavaScriptEnabled(true); // (5) webView1.addJavascriptInterface(new JavaScriptInterfaceFunctions(this, handler), "AndroidFunctions"); // (6) webView1.setWebChromeClient(new WebChromeClient()); // (7) } public void onClickHandler(View view) { webView1.loadUrl("javascript:showText()"); // (8) } } --- (1) WebView オブジェクト private WebView webView1; // (1) △ WebView クラス HTML をアプリケーション内から表示するためのクラス。 java.lang.Object + android.view.View + android.view.ViewGroup + android.widget.AbsoluteLayout + android.webkit.WebView ・主なメソッド --- void addJavascriptInterface(Object obj, String interfaceName) WebSettings getSettings() void loadData(String data, String mimeType, String encoding) void loadDataWithBaseURL(String baseUrl, String data, String mimeType, String encoding, String historyUrl) void loadUrl(String url) void loadUrl(String url, Map<String, String> extraHeaders) void setDownloadListener(DownloadListener listener) void setWebChromeClient(WebChromeClient client) void setWebViewClient(WebViewClient client) void stopLoading() --- ・履歴関係のメソッド --- boolean canGoBack() boolean canGoBackOrForward(int steps) boolean canGoForward() void goBack() void goBackOrForward(int steps) void goForward() --- ・画面のズーム関係のメソッド --- boolean canZoomIn() boolean canZoomOut() boolean zoomIn() boolean zoomOut() --- (2) ハンドラー・オブジェクトの生成 JavaScript から呼ばれたメソッドで、アクティビティのビューを操作できるようにする ために、Handler クラスのオブジェクトを生成しておく。 Handler handler = new Handler(); // (2) △ Handler クラス Handler クラスは、マルチスレッドで、スレッド間でメッセージをやり取りするのを実現 するためのクラス。 java.lang.Object + android.os.Handler 詳細は、以下のURLを参照のこと。 Android の Handler とは何か? http://www.adamrocker.com/blog/261/what-is-the-handler-in-android.html --- ・AndroidのUI操作はシングル・スレッド モデル ・ユーザビリティ向上の為にはマルチスレッドが必要 ・Handlerで実現 ・Handlerを使わない場合に起きる例外は実行スレッドのチェックで発生 ・Handlerを使うと、UI Threadの持つキューにジョブを登録できる ・キューはUI Threadにより実行される ・別スレッドからUI Threadに処理を登録するのでスレッドチェックで例外が発生しない --- ・メッセージを送るメソッド --- final boolean post(Runnable r) final boolean postAtFrontOfQueue(Runnable r) final boolean postAtTime(Runnable r, Object token, long uptimeMillis) final boolean postAtTime(Runnable r, long uptimeMillis) final boolean postDelayed(Runnable r, long delayMillis) final boolean sendEmptyMessage(int what) final boolean sendEmptyMessageAtTime(int what, long uptimeMillis) final boolean sendEmptyMessageDelayed(int what, long delayMillis) final boolean sendMessage(Message msg) final boolean sendMessageAtFrontOfQueue(Message msg) boolean sendMessageAtTime(Message msg, long uptimeMillis) final boolean sendMessageDelayed(Message msg, long delayMillis) --- ・メッセージを受け取るメソッド --- void handleMessage(Message msg) --- (3) HTML を読み込む webView1.loadUrl("file:///android_asset/index.html"); // (3) プロジェクトの assets フォルダは、「/android_asset」でアプリケーション内から参照 できる。 (5) HTML で JavaScript が使えるようにする WebSettings settings = webView1.getSettings(); // (4) settings.setJavaScriptEnabled(true); // (5) △ WebSettings クラス WebView オブジェクトに関する設定関係のオブジェクト。 java.lang.Object + android.webkit.WebSettings ・主なメソッド --- synchronized void setJavaScriptEnabled(boolean flag) JavaScript 有効無効の設定 void setSaveFormData(boolean save) フォームデータ保存の有効無効の設定 void setSavePassword(boolean save) パスワード保存の有効無効の設定 void setSupportZoom(boolean support) ズームの有効無効の設定 --- (6) JavaScript から Java のメソッドを使えるようにする webView1.addJavascriptInterface(new JavaScriptInterfaceFunctions(this, handler), "AndroidFunctions"); // (6) 形式 --- void addJavascriptInterface(Object JavaScriptインターフェース・オブジェクト, String インターフェース名) --- JavaScript 側からは、インターフェース名.メソッド名() で呼び出せる。 (7) JavaScript で、alert や prompt が使えるようにする webView1.setWebChromeClient(new WebChromeClient()); // (7) △ WebChromeClient クラス JavaScript で使う prompt や alert は、Android のダイアログになる。これらをサポー トするクラス。デフォルトで用意されているが、必要に応じて、このクラスのメソッドを オーバーライドしてカスタマイズする。 java.lang.Object + android.webkit.WebChromeClient ・JavaScript 関係の主なメソッド --- boolean onJsAlert(WebView view, String url, String message, JsResult result) boolean onJsConfirm(WebView view, String url, String message, JsResult result) boolean onJsPrompt(WebView view, String url, String message, String defaultValue, JsPromptResult result) boolean onJsTimeout() --- (8) JavaScript の関数を呼び出す webView1.loadUrl("javascript:showText()"); // (8) ・形式 --- webView1.loadUrl("javascript:関数名(引数リスト)"); --- ▲ JavaScript から使う関数を定義したクラス 単なる Java のクラスとして作ればよい。 ただし、アクティビティのビューを操作するときは、ハンドラー・オブジェクトが必要。 □ JavaScriptInterfaceFunctions.java --- package jp.marunomaruno.android.webviewjavascript; import android.app.Activity; import android.content.Context; import android.os.Handler; import android.widget.TextView; import android.widget.Toast; public class JavaScriptInterfaceFunctions { private Context context; private Handler handler; // (1) public JavaScriptInterfaceFunctions(Context context, Handler handler) { this.context = context; this.handler = handler; } public void showToast(String message) { Toast.makeText(context, getMessage(message), Toast.LENGTH_LONG).show(); } public void setTextView(final String message) { handler.post(new Runnable() { // (2) public void run() { // (3) TextView textView1 = (TextView) ((Activity) context) .findViewById(R.id.textView1); textView1.setText(getMessage(message)); } }); } public String getMessage(String message) { return String.format("<span class='html'>☆%s☆</span> %s", message, getMessage()); } public String getMessage() { return String.format("<span class='java'>★%s★</span>", "これはJavaの文字列"); } } --- (1) JavaScript から呼ばれたメソッドで、アクティビティのビューを操作できるように する コンストラクターの引数をそのまま設定する。 private Handler handler; // (1) (2)(3) テキスト・ビューに値を設定する ハンドラーの post() メソッドを使って実行する。 handler.post(new Runnable() { // (2) public void run() { // (3) TextView textView1 = (TextView) ((Activity) context) .findViewById(R.id.textView1); textView1.setText(getMessage(message)); } }); ▲ HTML ファイル 通常の HTML ファイル。 JavaScript から、Android の Java メソッドを呼ぶには、インターフェース名が必要。 インターフェース名.メソッド名(引数リスト) □ assets/index.html --- <!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd"> <html> <head> <meta http-equiv="Content-Type" content="text/html; charset=utf-8"> <style TYPE="text/css"> #area { background-color: lightgreen; } .html { color: red; } .java { color: green; } </style> <script type="text/javascript"> // Android のトースト表示 function showToast(message){ AndroidFunctions.showToast(message); // (1) } // Android のテキストビューに設定 function setTextView(message){ AndroidFunctions.setTextView(message); } // メッセージを組み立て function makeMessage(message){ var message = AndroidFunctions.getMessage(message); // (2) document.getElementById("area").innerHTML = message; } // メッセージ取得 function getMessage(){ var message = AndroidFunctions.getMessage(); // (3) document.getElementById("area").innerHTML = message; } // メッセージをプロンプトから取得する function messageFromPrompt(){ var message = prompt("文字列を入力してください。", ""); // (4) alert(message); // (5) } // Android から呼ばれる function showText(){ document.getElementById("area").innerHTML = "Javaから呼ばれたJavaScriptの関 数"; } </script> <title>Insert title here</title> </head> <body> <p> <input type="button" value="Androidのトーストを表示" onclick="showToast('HTMLの文字列')"/> </p> <p> <input type="button" value="Androidのテキストビューに表示" onclick="setTextView('HTMLの文字列')"/> </p> <p> <input type="button" value="Androidからメッセージを組み合わせる" onclick="makeMessage('HTMLの文字列')"/> </p> <p> <input type="button" value="プロンプトから文字列を読んでアラート表示" onclick="messageFromPrompt()"/> </p> <p> <input type="button" value="Androidからメッセージを得る" onclick="getMessage()"/> </p> <p> <div id="area">ここに文字列が入る</div> </p> </body> </html> --- (1) Java 側のメソッドの呼び出し AndroidFunctions.showToast(message); // (1) Java 側では以下のような設定をしている。 webView1.addJavascriptInterface(new JavaScriptInterfaceFunctions(this, handler), "AndroidFunctions"); (2)(3) Java 側のメソッドはオーバーロード可能 var message = AndroidFunctions.getMessage(message); // (2) var message = AndroidFunctions.getMessage(); // (3) (4)(5) prompt や alert を使う var message = prompt("文字列を入力してください。", ""); // (4) alert(message); // (5) Java 側では以下のような設定をしている。 webView1.setWebChromeClient(new WebChromeClient()); ▲レイアウト □ res/layout/main.xml --- <?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="fill_parent" android:layout_height="fill_parent" android:orientation="vertical" > <TextView android:id="@+id/textView1" android:layout_width="fill_parent" android:layout_height="wrap_content" android:text="@string/hello" /> <WebView android:id="@+id/webView1" android:layout_width="match_parent" android:layout_height="400dp" /> <!-- (1) --> <Button android:id="@+id/button1" android:layout_width="wrap_content" android:layout_height="wrap_content" android:onClick="onClickHandler" android:text="JavaScriptの呼び出し" /> </LinearLayout> --- (1) WebView <WebView android:id="@+id/webView1" android:layout_width="match_parent" android:layout_height="400dp" /> <!-- (1) --> ▲ マニフェスト --- <?xml version="1.0" encoding="utf-8"?> <manifest xmlns:android="http://schemas.android.com/apk/res/android" package="jp.marunomaruno.android.webviewjavascript" android:versionCode="1" android:versionName="1.0" > <uses-sdk android:minSdkVersion="8" /> <uses-permission android:name="android.permission.INTERNET"/> <!-- (1) --> <application android:icon="@drawable/ic_launcher" android:label="@string/app_name" > <activity android:label="@string/app_name" android:name=".WebViewJavaScript01Activity" > <intent-filter > <action android:name="android.intent.action.MAIN" /> <category android:name="android.intent.category.LAUNCHER" /> </intent-filter> </activity> </application> </manifest> --- (1) WebView を使うときは以下の設定が必要 <uses-permission android:name="android.permission.INTERNET"/> <!-- (1) --> 以上
最新の画像[もっと見る]
- あけましておめでとうございます 11年前
- 今年もよろしくお願いいたします 12年前
- あけましておめでとうございます 13年前
- あけましておめでとうございます 16年前
※コメント投稿者のブログIDはブログ作成者のみに通知されます