之前就知道在 Windows Phone 中的 WebView 可以使用 WebBrowser.InvokeScript 這個 Method 呼叫網頁中的 Javascript function 取得回傳值,所以當下直接和處理 Web 端的同事說 Android 也可以比照辦理,實際在開發時才發現事情並沒有想像中的順利,Android 的 WebView 並沒有提供類似的 Method,只能透過 External Object 的方式來間接達到效果。
假設我的網頁內容長這樣,裡面有個叫作 getFacebookShareURL 的 Javascript function 供 Client 查詢分享連結
<html>
<head>
<script type="text/javascript">
function getFacebookShareURL()
{
return "http://www.facebook.com/xxx/yyy/zzz";
}
</script>
</head>
<body>
<font size="5">Hello</font>
</body>
</html>
在 Windows 上直接很方便的使用 WebBrowser.InvokeScript("getFacebookShareURL") 就可以拿到 return 的值,看過同事 iOS 專案的程式碼,也是類似的 Method 一行搞定,但在 Android 上 call 網頁上的 Javascript function 的方式是使用 WebView.loadUrl("Javascript:function()") 這樣的方式,這個 Method 並沒有回傳值,所以我們拿不到這個 function 的 return 值,因為這個原因,我們必須製作一個 External Object 讓網頁執行將資料送給 Client 的動作,而這個 External Object 所要回傳的值,我們利用參數的方式帶進去,也就是 gerFacebookShareURL 這個 function 的 return 值,如此我們還是可以使用同樣的網頁來取得 Javascript function 想告訴 App 的資訊,同樣以 getFacebookShareURL 為範例,我在網頁載入完成的事件加入如下指令
public class MyActivity extends Activity {
private String shareURL;
private WebView webView;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_my);
webView = (WebView) findViewById(R.id.webview);
WebSettings webSettings = webView.getSettings();
webSettings.setSupportZoom(true);
webSettings.setBuiltInZoomControls(true);
webSettings.setJavaScriptEnabled(true);
webView.addJavascriptInterface(new JsCallBack(), "ExtObj");
webView.setWebViewClient(new WebViewClientImpl());
webView.loadUrl("http://192.168.10.183/~ascii/news.html");
}
private final class WebViewClientImpl extends WebViewClient
{
@Override
public void onPageFinished(WebView view, String url)
{
view.loadUrl("javascript:window.ExtObj.responseResult(getFacebookShareURL())");
}
}
private class JsCallBack
{
@JavascriptInterface
public void responseResult(final String result)
{
shareURL = result;
}
}
}
如果撰寫 External Object 時,在網頁上直接顯示找不到 responseResult 的錯誤訊息,特別注意一下是不是忘了在 Method 加上 @JavascriptInterface 這個 annotation,這在 Android Level 17 以上是必須的。
沒有留言:
張貼留言