最近的一個 app 需要讓 Android 可以呼叫 WebView 中的 Javascript,並且按下 WebView 中的按鈕時,也可以呼叫 Android 內部的方法,這篇文章記錄一下大概的做法,免得下次遇到又忘記 …

這個 app 需要做到的功能很簡單,在 Android 端希望可以點選「字體放大」、「字體縮小」的按鈕來呼叫 WebView 中的 Javascript;並且點選 WebView 中的行事曆按鈕後,可以開啟 Android 內建的 Google 行事曆。

  • Android 呼叫 WebView 中的 Javascript

透過 Android 本身的按鈕來達到呼叫 Javascript 的功能很簡單,以小蛙的例子是用 fragment 中放置一個 WebView

// 取得 WebView 物件
WebView wv = (WebView) v.findViewById(R.id.webView1);
// 設定此 WebView 支援 Javascript
wv.getSettings().setJavaScriptEnabled(true);

// 取得按鈕物件
Button b = (Button) v.findViewById(R.id.button1);
b.setOnClickListener(new View.OnClickListener() {
	@Override
	public void onClick(View v) {
                wv.loadUrl("javascript:fontSize('+')");
	}
});

上面的程式碼只寫出個大概,取得 WebView 後設定支援 Javascript,並且設定按鈕來執行 Javascript,上面例子小蛙 WebView 中有一個字體放大的 Javascript 叫做 fontSize(‘+’),因此直接使用 wv.loadUrl(‘要呼叫的 Javascript’); 即可!

  • 從 WebView 呼叫 Android Function

這個部分就比較複雜一些些,首先必須先建立一個 JavascriptInterface 物件,設定好要執行的相對應功能。例如:

public class JavaScriptInterface {
       private Activity activity;
       public JavaScriptInterface(Activity activiy) {
               this.activity = activiy;
       }
       @JavascriptInterface
       public void showToast(){
               Toast.makeText(activity, "我被從WebView呼叫了", Toast.LENGTH_SHORT).show();
       }
}

這邊要注意的是如果 targetSdkVersion 設定為 17 以上,就必須在每個可以被 Javascript 呼叫的方法前面加上 @JavascriptInterface,否則會出現以下錯誤

Uncaught TypeError: Object [object Object] has no method 'showToast'

將設定好的 JavaScriptInterface 設定給 WebView 物件

wv.addJavascriptInterface(new JavaScriptInterface(getActivity()), "JSInterface");

後面的參數名字可以自己取,小蛙這邊使用 JSInterface,這個名字是讓 Javascript 可以知道透過哪個物件來呼叫。Android 這邊完成後接著在 html 中加入相對應的動作,例如:

<input type='button' value='按我' onclick='javascript:showToast();'>
<script type='text/javascript'>
function showToast(){
	if(JSInterface)
		JSInterface.showToast();
}
</script>

設定一個 button 讓使用者點選時執行 function showToast(),而 showToast 方法中倘若存在 JSInterface 物件 (這個物件是上面 wv.addJavascriptInterface 時設定的),就執行 JSInterface.showToast() 的方法 (這一步就會對應到我們自訂的 JavaScriptInterface 類別中的 public void showToast()),在 app 中顯示 Toast 訊息。

到這邊,從 Android 呼叫 Javascript 以及從 Javascript 呼叫 Android 方法都已經完成,但是在 Android 2.3.x 版本中會發生一些錯誤,造成當機無法正確執行,解決方法請參考 Android 2.3 @JavascriptInterface Issue @ 蛙齋

相關文章

Android 2.3 @JavascriptInterface Issue

JavascriptInterface 這個問題相信 Google 一下就可以找到很多文章,雖然如此小蛙還是試了好久才成功,這篇文章記錄一下當時小蛙不成功的盲點在哪裡。上一篇文章「
2014-03-28 20:25:25
hans

18

JavaScript 重新整理頁面

突然發現蛙齋的JavaScript分類中的文章只有三篇,但對於小蛙的工作來說JavaScript也算是重要的一環,還是記錄一下以後查找方便。這篇主要是記錄網路上查到的一些關於「重新整理頁面」的資料。
2012-09-19 20:00:30
hans

18

Javascript用RegExp達成trim()

Java 中有個功能叫做 trim(),當字串中前後可能會有空白字元的時候,可以透過 trim() 來去除,小蛙使用 JavaScr
2011-03-14 15:33:47
hans

18

Javascript用RegExp達成replaceAll()

Java 有個很方便的功能,透過 replaceAll() 可以把字串中所有符合的子字串替換成別的字串,這篇文章記錄一下在網路上蒐尋到在 JavaScript 實作的方法。
2011-03-14 14:58:00
hans

18

Android Vuforia with jPCT-AE (5) – 多重模型載入,以 obj 為例

要進到這系列最後一篇文章了,這篇文章拖了很久,一直沒有時間整理,結果到最後 ... 程式碼留下來了,記憶卻有些模糊了,這邊小蛙配著程式碼盡可能的把還記得的東西寫下來。
2016-07-06 11:24:19
hans

8

Android Vuforia with jPCT-AE (4) – 載入 3DS 測試

延續 jPCT-AE Loader 載入模型的部份,這篇要記錄載入 3ds 檔案格式的方法,基本上跟前面幾個 obj, md2 的方法差不多,只有一些小小的變化而已。
2016-07-06 10:24:33
hans

8

Android Vuforia with jPCT-AE (3) – 載入 md2 測試

前兩篇介紹如何直接透過 jPCT-AE 直接繪圖以及載入 .obj 檔案,這邊繼續介紹 jPCT-AE 載入 md2 的方法,載入動作大致上類似,唯一不同的只有 texture 設定部份。
2016-07-06 09:24:43
hans

8

Android Vuforia with jPCT-AE (2) – 載入 obj 測試

上一篇 Android Vuforia with jPCT-AE (1) –
2016-07-06 08:24:55
hans

8




 回覆

你可以使用以下語法 HTML tags and attributes: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <s> <strike> <strong> <pre class="">

(required)

(required)

   
© 2012 蛙齋 Suffusion theme by Sayontan Sinha