Android WebView JavaScript 交互
Android WebView 使用 JavaScript 可以完成 HTML5 与 Android 手机间的互相访问
-
定义一个类,用于将数据暴露出来,JS 通过该类公开的 (public) 添加了
@JavascriptInterface
注解的方法 访问 Android App 中的数据class JsObject { @JavascriptInterface public String toString() { return "injectedObject"; } }
-
设置
WebView
开启JavaScript
支持webview.getSettings().setJavaScriptEnabled(true); webview.addJavascriptInterface(object,"name");
-
在 JavaScript 或者 HTML 中调用 name.xxx 调用对象里的暴露的方法
< input type="button" value="Toast提示" onclick="name.showToast('呵呵');"/>
-
WebView
通过调用evaluateJavascript()
方法调用 JavaScript 中的方法ms_webview.evaluateJavascript()(script, new ValueCallback<String>() { @Override public void onReceiveValue(String value) { // code here } });
HTML 通过 JS 显示 Toast 与普通列表的对话框
-
创建一个 空的 Android 项目
cn.twle.android.WebViewJavaScript
-
修改
AndroidManifest.xml
添加网络权限<uses-permission android:name="android.permission.INTERNET" />
-
在
app
上点右键,然后选择Folder - Assets Folder
创建assets
目录,并在该名录下创建一个 HTML 文件demo_e.html
<!DOCTYPE html> <meta charset="utf-8" /> <title>Android WebView JavaScript 交互</title> <h1>Android WebView JavaScript 交互</h1> <p><input type="button" value="弹出 Toast 提示" onclick="jsbridge.showToast('简单教程,简单编程');"/></p> <p><input type="button" value="弹出语言类表" onclick="jsbridge.showDialog();"/> <script> function show_dialog() { alert("简单教程的网址是:https://www.twle.cn/"); } </script>
或者直接使用我们的网址 https://www.twle.cn/static/i/android/demo_e.html
-
修改
activity_main.xml
添加一个WebView
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" android:padding="5dp" android:layout_width="match_parent" android:layout_height="match_parent"> <WebView android:id="@+id/ms_webview" android:layout_width="match_parent" android:layout_height="match_parent" /> </RelativeLayout>
-
自定义一个 Object 对象
JsBridge.java
,JavaScript 通过该类暴露的方法来调用 Androidpackage cn.twle.android.webviewjavascript; import android.app.AlertDialog; import android.content.Context; import android.webkit.JavascriptInterface; import android.widget.Toast; public class JsBridge { private Context context; public JsBridge(Context context) { this.context = context; } //将显示 Toast 和对话框的方法暴露给 JavaScript 脚本调用 @JavascriptInterface public void showToast(String name) { Toast.makeText(context, name, Toast.LENGTH_SHORT).show(); } @JavascriptInterface public void showDialog() { new AlertDialog.Builder(context) .setTitle("开发语言列表") .setItems(new String[]{"Java", "C", "C++", "Python", "PHP"}, null) .setPositiveButton("确定", null).create().show(); } }
-
修改
MainActivity.java
启用 JavaScript 支持,然后通过addJavascriptInterface()
暴露对象package cn.twle.android.webviewjavascript; import android.os.Bundle; import android.support.v7.app.AppCompatActivity; import android.webkit.WebSettings; import android.webkit.WebView; public class MainActivity extends AppCompatActivity { private WebView ms_webview; //private static final String SITE_URL = "file:///android_asset/demo_e.html" private static final String SITE_URL = "https://www.twle.cn/static/i/android/demo_e.html"; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); ms_webview = (WebView) findViewById(R.id.ms_webview); WebSettings webSettings = ms_webview.getSettings(); webSettings.setJavaScriptEnabled(true); webSettings.setDefaultTextEncodingName("UTF-8"); //将 JsBridge 对象暴露给 JavaScript ms_webview.addJavascriptInterface(new JsBridge(MainActivity.this), "jsbridge"); ms_webview.loadUrl(SITE_URL); } }
自定义 HTML 中的三种不同的对话框
-
创建一个 空的 Android 项目
cn.twle.android.WebViewCallJs
-
修改
AndroidManifest.xml
添加网络权限<uses-permission android:name="android.permission.INTERNET" />
-
在
app
上点右键,然后选择Folder - Assets Folder
创建assets
目录,并在该名录下创建一个 HTML 文件demo_f.html
<!DOCTYPE html> <meta charset="utf-8" /> <title>APP 通过 JavaScript 弹出 HTML 中的三种不同的对话框</title> <script> function alertFun() { alert("Alert 警告对话框!"); } function confirmFun() { if(confirm("访问简单教程?")) {location.href = "https://www.twle.cn";} else alert("取消访问!"); } function promptFun() { var word = prompt("Prompt 对话框","请输入点什么...:"); if(word) { alert("你输入了:"+word) }else{ alert("你什么都没写!"); } } </script> <p>APP 通过 JavaScript 弹出 HTML 中的三种不同的对话框</p> <p>alert 对话框</p> <p> <input type="submit" name = "Submit1" value="展示1" onclick="alertFun()"/> </p> <p>Confirm对话框</p> <p> <input type="submit" name = "Submit2" value="展示2" onclick="confirmFun()"/> </p> <p>Prompt对话框</p> <p> <input type="submit" name = "Submit3" value="展示3" onclick="promptFun()"/> </p>
或者直接使用我们的网址 https://www.twle.cn/static/i/android/demo_f.html
-
修改
activity_main.xml
添加一个WebView
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" android:padding="5dp" android:layout_width="match_parent" android:layout_height="match_parent"> <WebView android:id="@+id/ms_webview" android:layout_width="match_parent" android:layout_height="match_parent" /> </RelativeLayout>
-
创建一个对话框布局
alertdialog.xml
<?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent" android:layout_height="match_parent" android:orientation="vertical"> <TextView android:id="@+id/text" android:layout_width="match_parent" android:layout_height="wrap_content" /> <EditText android:id="@+id/edit" android:layout_width="match_parent" android:layout_height="wrap_content" android:scrollHorizontally="true" android:selectAllOnFocus="true" /> </LinearLayout>
-
修改
MainActivity.java
package cn.twle.android.webviewjavascript; import android.content.Intent; import android.net.Uri; import android.os.Bundle; import android.support.v7.app.AppCompatActivity; import android.webkit.WebSettings; import android.webkit.DownloadListener; import android.webkit.WebView; public class MainActivity extends AppCompatActivity { private WebView ms_webview; //private static final String SITE_URL = "file:///android_asset/demo_e.html" private static final String SITE_URL = "https://www.twle.cn/static/i/android/demo_f.html"; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); ms_webview = (WebView) findViewById(R.id.ms_webview); WebSettings webSettings = ms_webview.getSettings(); webSettings.setJavaScriptEnabled(true); webSettings.setDefaultTextEncodingName("UTF-8"); webSettings.setAllowFileAccess(true); webSettings.setBuiltInZoomControls(true); ms_webview.loadUrl(SITE_URL); } } //这里需要自定义一个类实现WebChromeClient类,并重写三种不同对话框的处理方法 //分别重写onJsAlert,onJsConfirm,onJsPrompt方法 class MyWebChromeClient extends WebChromeClient { @Override public boolean onJsAlert(WebView view, String url, String message, final JsResult result) { //创建一个Builder来显示网页中的对话框 new Builder(MainActivity.this).setTitle("Alert对话框").setMessage(message) .setPositiveButton("确定", new OnClickListener() { @Override public void onClick(DialogInterface dialog, int which) { result.confirm(); } }).setCancelable(false).show(); return true; } @Override public boolean onJsConfirm(WebView view, String url, String message, final JsResult result) { new Builder(MainActivity.this).setTitle("Confirm对话框").setMessage(message) .setPositiveButton("确定", new OnClickListener() { @Override public void onClick(DialogInterface dialog, int which) { result.confirm(); } }) .setNegativeButton("取消", new DialogInterface.OnClickListener() { @Override public void onClick(DialogInterface dialog, int which) { result.cancel(); } }).setCancelable(false).show(); return true; } @Override public boolean onJsPrompt(WebView view, String url, String message, String defaultValue, final JsPromptResult result) { //①获得一个LayoutInflater对象factory,加载指定布局成相应对象 final LayoutInflater inflater = LayoutInflater.from(MainActivity.this); final View myview = inflater.inflate(R.layout.prompt_view, null); //设置TextView对应网页中的提示信息,edit设置来自于网页的默认文字 ((TextView) myview.findViewById(R.id.text)).setText(message); ((EditText) myview.findViewById(R.id.edit)).setText(defaultValue); //定义对话框上的确定按钮 new Builder(MainActivity.this).setTitle("Prompt对话框").setView(myview) .setPositiveButton("确定", new OnClickListener() { @Override public void onClick(DialogInterface dialog, int which) { //单击确定后取得输入的值,传给网页处理 String value = ((EditText) myview.findViewById(R.id.edit)).getText().toString(); result.confirm(value); } }) .setNegativeButton("取消", new OnClickListener() { @Override public void onClick(DialogInterface dialog, int which) { result.cancel(); } }).show(); return true; } } }