参考 Android WebView与JS的交互方式:https://blog.csdn.net/u011035026/article/details/123267616
代码示例:
代码示例:
package com.jay.wvjsapp; import android.app.Activity; import android.app.AlertDialog; import android.content.Context; import android.content.DialogInterface; import android.net.Uri; import android.os.Build; import android.os.Bundle; import android.util.Log; import android.webkit.JsPromptResult; import android.webkit.JsResult; import android.webkit.ValueCallback; import android.webkit.WebChromeClient; import android.webkit.WebResourceRequest; import android.webkit.WebSettings; import android.webkit.WebView; import android.webkit.WebViewClient; import android.widget.Toast; import java.util.HashMap; import java.util.Set; public class MainActivity extends Activity { private WebView mWv1; Context ctx = this; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); mWv1 = findViewById(R.id.wv1); WebSettings webSettings = mWv1.getSettings(); // 允许javascript 设置支持JS就自动打开IndexedDB存储机制 webSettings.setJavaScriptEnabled(true); // 设置允许JS弹窗 webSettings.setJavaScriptCanOpenWindowsAutomatically(true); webSettings.setPluginState(WebSettings.PluginState.ON); webSettings.setDomStorageEnabled(true); webSettings.setAppCacheEnabled(true); mWv1.setHorizontalScrollBarEnabled(true); mWv1.setVerticalScrollBarEnabled(true); //设置响应js 的Alert()函数 mWv1.setWebChromeClient(new WebChromeClient() { @Override public void onProgressChanged(WebView view, int newProgress) { super.onProgressChanged(view, newProgress); Log.d("MainActivity","newProgress:"+ newProgress ); } @Override public void onReceivedTitle(WebView view, String title) { super.onReceivedTitle(view, title); Log.d("MainActivity","标题:"+ title); } //设置响应js 的Alert()函数 @Override public boolean onJsAlert(WebView view, String url, String message, final JsResult result) { AlertDialog.Builder b = new AlertDialog.Builder(ctx); b.setTitle(""); b.setMessage(message); b.setPositiveButton(android.R.string.ok, new DialogInterface.OnClickListener() { @Override public void onClick(DialogInterface dialog, int which) { result.confirm(); } }); //设置为false,按返回键不能退出。默认为true。 //弹出框如果要求用户必须点击按钮才关闭(点击页面空白或者点击返回键都不能关闭),那么需设置cancelable为false, //如果需要返回键执行事件,那么需要编写对应的监听方法setOnKeyListener b.setCancelable(false); b.create().show(); return true; } //设置响应js 的Confirm()函数 @Override public boolean onJsConfirm(WebView view, String url, String message, final JsResult result) { AlertDialog.Builder b = new AlertDialog.Builder(ctx); b.setTitle(""); b.setMessage(message); b.setPositiveButton(android.R.string.ok, new DialogInterface.OnClickListener() { @Override public void onClick(DialogInterface dialog, int which) { result.confirm(); } }); b.setNegativeButton(android.R.string.cancel, new DialogInterface.OnClickListener() { @Override public void onClick(DialogInterface dialog, int which) { result.cancel(); } }); b.create().show(); return true; } // js调用Android方法,方式3。 // 设置拦截js的Prompt()函数,调用Android方法。 // 在js中调用prompt(),result就是Android返回的值。 // var result = prompt("js://webview?arg1=111&arg2=222"); // 拦截输入框(原理同方式shouldOverrideUrlLoading) // 参数message:代表prompt()的内容(不是url) // 参数result:代表输入框的返回值 @Override public boolean onJsPrompt(WebView view, String url, String message, String defaultValue, final JsPromptResult result) { Log.d("MainActivity","Prompt input is :" + message); // 根据协议的参数,判断是否是所需要的url(原理同方式2) // 一般根据scheme(协议格式) & authority(协议名)判断(前两个参数) //传入进来的 url="js://webview?arg1=111&arg2=222"(同时也是约定好的需要拦截的) Uri uri = Uri.parse(message); // 如果url的协议 = 预先约定的 js 协议,就解析往下解析参数 if (uri.getScheme().equals("js")) { // 如果 authority = 预先约定协议里的webview,即代表符合约定的协议 // 所以拦截url,下面JS开始调用Android需要的方法 if (uri.getAuthority().equals("webview")) { // 执行JS所需要调用的逻辑 System.out.println("js调用了Android的方法"); // 可以在协议上带有参数并传递到Android上 HashMap<String, String> params = new HashMap<>(); // 携带的参数名集合 Set<String> collection = uri.getQueryParameterNames(); for (String item : collection) { // 根据参数名,获取uri中的参数值。 params.put(item, uri.getQueryParameter(item)); } //参数result:代表消息框的返回值(输入值),返回给客户端js。 result.confirm("Android回调给JS的数据为useid=123456"); } return true; } else { result.confirm(); } return super.onJsPrompt(view, url, message, message, result); } }); // js调用Android方法,方式1 // 通过addJavascriptInterface()将Java对象映射到JS对象 // 参数1:JavaScript对象名,参数2:Java对象名 // WebViewJsBridge类对象映射到JS的Android对象 // mWv1.addJavascriptInterface(new WebViewJsBridge(), "Android"); String urlAddress = "http://192.168.9.8:5196/Home/Index"; mWv1.loadUrl(urlAddress); // js调用Android方法,方式2 // 先载入JS代码,格式规定为:file:///android_asset/文件名.html // mWv1.loadUrl("file:///android_asset/Test.html"); // 先载入JS代码,然后复写WebViewClient类的shouldOverrideUrlLoading方法 mWv1.setWebViewClient(new WebViewClient() { // 该重载方法不建议使用了,7.0系统以上已经摒弃了 // shouldOverrideUrlLoading(WebView view, String url)此方法, // 如果要拦截URL,需要做兼容性处理,重写 // shouldOverrideUrlLoading(WebView view, WebResourceRequest request)方法, // 获取得到的可正常使用的URL // @Override // public boolean shouldOverrideUrlLoading(WebView view, String url) { // return super.shouldOverrideUrlLoading(view, url); // } @Override public boolean shouldOverrideUrlLoading(WebView view, WebResourceRequest request) { // 根据协议的参数,判断是否是所需要的url // 一般根据scheme(协议格式) & authority(协议名)判断(前两个参数) // 假定传入进来的url="js://webview?arg1=111&arg2=222"(同时也是约定好的需要拦截的) Uri uri; if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) { uri = request.getUrl(); } else { uri = Uri.parse(request.toString()); } // 如果url的协议 = 预先约定的 js 协议,就解析往下解析参数 if (uri.getScheme().equals("js")) { // 如果 authority = 预先约定协议里的webview,即代表都符合约定的协议 // 所以拦截url,下面JS开始调用Android需要的方法 if (uri.getAuthority().equals("webview")) { //执行JS所需要调用的逻辑 Log.d("TAG", "JS调用了Android的方法"); // 可以在协议上带有参数并传递到Android上 HashMap<String, String> params = new HashMap<>(); Set<String> collection = uri.getQueryParameterNames(); for (String item : collection) { params.put(item, uri.getQueryParameter(item)); } String result = "{\"msg\":\"返回数据:123456\"}"; // view.loadUrl("javascript:returnResult('" + result + "')"); callClientJs("returnResult",result); } return true; } return super.shouldOverrideUrlLoading(view, request); } }); } /** * 调用客户端js * callClientJs("callJs","{\"name\":\"jay.x\"}"); * */ public void callClientJs(String methodName, String para) { if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) { //方式2:通过WebView的evaluateJavascript() //优点:该方法比第一种方法效率更高、使用更简洁。 //(1)因为该方法的执行不会使页面刷新,而第一种方法(loadUrl )的执行则会。 //(2)Android 4.4(即>=19)后才可使用。 // 只需要将第一种方法的loadUrl()换成下面该方法即可 mWv1.evaluateJavascript("javascript:" + methodName + "('" + para + "')", new ValueCallback<String>() { @Override public void onReceiveValue(String value) { // 此处为JS返回的结果 Toast.makeText(getApplicationContext(), "js return:" + value, Toast.LENGTH_SHORT).show(); } }); } else { //方式1:通过WebView的loadUrl mWv1.loadUrl("javascript:" + methodName + "('" + para + "')"); } } }
//WebSettings.LOAD_NO_CACHE 设置去缓存,防止加载的为上一次加载过的LOAD_DEFAULT
webSettings.setCacheMode(WebSettings.LOAD_NO_CACHE);
分类:
Android
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 地球OL攻略 —— 某应届生求职总结
· 周边上新:园子的第一款马克杯温暖上架
· Open-Sora 2.0 重磅开源!
· 提示词工程——AI应用必不可少的技术
· .NET周刊【3月第1期 2025-03-02】