美文网首页
WebView在使用setUserAgentString时的坑

WebView在使用setUserAgentString时的坑

作者: 因为我的心 | 来源:发表于2023-03-28 11:58 被阅读0次

1、BridgeWebView开原地址

GitHub上的开源地址:https://github.com/open-android/BridgeWebView

1. 在project的build.gradle添加如下代码

allprojects {
    repositories {
        maven { url "https://jitpack.io" }
    }
}

2. 在Module的build.gradle添加依赖

compile 'com.github.open-android:BridgeWebView:v1.0'

3.布局文件中使用

<com.itheima.view.BridgeWebView
    android:id="@+id/bdwebview"
    android:layout_width="match_parent"
    android:layout_height="match_parent"/>

4.Activity初始化通信桥梁

mBdwebview = (BridgeWebView) findViewById(R.id.bdwebview);//初始化BridgeWebView
mBdwebview.loadUrl("http://10.0.3.2:63343/BridgeWebView/index.html");//显示H5页面
mBdwebview.addBridgeInterface(new MyJavaSctiptInterface(mBdwebview, this));//注册桥梁类,该类负责H5和android通信

5.桥梁类提方法给js调用

public class MyJavaSctiptInterface{
    private Activity mActivity;

    public MyJavaSctiptInterface(Activity mActivity) {
        this.mActivity = mActivity;
    }

    public void callPhone(String[] strs){//拨号
        JSONObject jsonObject = new JSONObject(strs[0]);
        String phone = jsonObject.optString("phone");
        Intent intent = new Intent(Intent.ACTION_CALL, Uri.parse("tel:" + phone));
        mActivity.startActivity(intent);
    }
}

6.js中调用android方法

$("#btn1").on("click", function(){
    var method = "callPhone";//js调用的android方法名
    var params = {"phone":"10086", "callback":""};//callback用于回调js
    callAndroidMethod(method, params);
});

 /**
 * 统一管理js调用安卓方法
 * @param method 方法名
 * @param params 向android传参数 数组格式
 */
var callAndroidMethod = function(method, params){
    window.jsInterface.invokeMethod(method, [JSON.stringify(params)]);
}

2、接入webView

图片.png 图片.png
1、 AndroidManifest.xml
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools">

    <uses-permission android:name="android.permission.INTERNET" />
    <application
        android:allowBackup="true"
        android:dataExtractionRules="@xml/data_extraction_rules"
        android:fullBackupContent="@xml/backup_rules"
        android:icon="@mipmap/ic_launcher"
        android:label="@string/app_name"
        android:roundIcon="@mipmap/ic_launcher_round"
        android:supportsRtl="true"
        android:theme="@style/Theme.HelloAA"
        tools:targetApi="31"
        android:usesCleartextTraffic="true"
        android:networkSecurityConfig="@xml/network_security_config"
        >

        <activity
            android:name=".MainActivity"
            android:exported="true">
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />

                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>

            <meta-data
                android:name="android.app.lib_name"
                android:value="" />
        </activity>
    </application>

</manifest>

添加的"android:usesCleartextTraffic="true"表示启用域名明文,支持http请求。

2、network_security_config.xml

<?xml version="1.0" encoding="utf-8"?>
<network-security-config>
    <base-config cleartextTrafficPermitted="true" />
</network-security-config>

3、WebView在使用setUserAgentString时的坑

在 Android 中,使用 setUserAgentString() 方法设置 WebView 的用户代理字符串是有效的。但是需要注意以下几点:

  • 1、此方法必须在 WebView 加载网页之前调用,否则将不起作用。
  • 2、如果您在加载网页之后调用此方法,则必须重新加载网页才能使更改生效。
  • 3、请确保在调用此方法之前正确获取了 WebView 对象。如果您在没有实例化 WebView 的情况下调用此方法,它将无法正常工作。

以下是一个示例代码:

WebView webView = new WebView(context);
WebSettings webSettings = webView.getSettings();
webSettings.setUserAgentString("Your User Agent String");
webView.loadUrl("http://www.example.com");

请注意,在这个示例中,我们在设置用户代理字符串之前获取了 WebView 对象,并且在加载网页之前设置了用户代理字符串。如果您按照这个流程进行,那么 setUserAgentString() 就应该能够正常工作。

如果要追加设置

WebSettings settings = webView.getSettings();
String ua = settings.getUserAgentString();// 获取默认的UA
settings.setUserAgentString(ua + "; ****");// UA追加自定义标识符

4、webview设置setUserAgentString 之后,用Fiddler拦截器查看,发现User-Agent没有加上去

如果你在使用 setUserAgentString 方法设置 User-Agent 后,却无法在 Fiddler 中看到对应的 User-Agent 信息,可能是因为 WebView 在某些情况下会忽略该设置。以下是一些可能的原因:

  • 1、User-Agent 设置不正确:请检查你使用 setUserAgentString 设置的字符串是否符合规范。
  • WebView 缓存了旧的 User-Agent:尝试清除 WebView 的缓存并重新加载页面,或者使用 WebSettings.setUserAgentString(String userAgent) 方法来覆盖全局的 User-Agent 设置。
  • 其他应用程序更改了 User-Agent:有些应用程序(如 VPN 或广告拦截器)可能会更改应用程序的 User-Agent,从而影响 WebView 的 User-Agent 设置。试着关闭这些应用程序并重新测试。

如果以上解决方法都没有成功,你可以尝试从代码层面上重置 User-Agent,具体方式如下:

webView.getSettings().setUserAgentString(null);
webView.getSettings().setUserAgentString("your custom user agent string");

5、net::ERR_UNKNOWN_URL_SCHEME错误

解决上述问题后,我重新安装了应用,结果应用在加载出网页后有马上出现了这个错误“net::ERR_UNKNOWN_URL_SCHEME……网页无法打开”。仔细观察报错页面,我发现“http/https://”协议变成了“baiduboxapp://utils?……”。

出现这种情况的原因是:WebView 只支持 http 和 https 协议,而我们的请求链接(url)在加载完成后却发生了变化。这种现象叫重定向。

解决办法:在创建 WebViewClient 对象时,通过重写 shouldOverrideUrlLoading(WebView view, String url)方法对会发生重定向的 url 进行拦截。以下是拦截的代码:

webView.setWebViewClient(new WebViewClient(){
            @Override
            public boolean shouldOverrideUrlLoading(WebView view, String url) {
                WebView.HitTestResult hit = view.getHitTestResult();
                //hit.getExtra()为null或者hit.getType() == 0都表示即将加载的URL会发生重定向,需要做拦截处理
                if (TextUtils.isEmpty(hit.getExtra()) || hit.getType() == 0) {
                    //通过判断开头协议就可解决大部分重定向问题了,有另外的需求可以在此判断下操作
                    Log.e("重定向", "重定向: " + hit.getType() + " && EXTRA()" + hit.getExtra() + "------");
                    Log.e("重定向", "GetURL: " + view.getUrl() + "\n" +"getOriginalUrl()"+ view.getOriginalUrl());
                    Log.d("重定向", "URL: " + url);
                }
 
                if (url.startsWith("http://") || url.startsWith("https://")) {//加载的url是http/https协议地址 
                    view.loadUrl(url);
                    return false; //返回false表示此url默认由系统处理,url未加载完成,会继续往下走
 
                } else { //加载的url是自定义协议地址
                    try {
                        Intent intent = new Intent(Intent.ACTION_VIEW, Uri.parse(url));
                        startActivity(intent);
                    } catch (Exception e) {
                        e.printStackTrace();
                    }
                    return true;
                }
            }
});

通过以上方法,应该就能正常使用WebView打开网页了。

6、我的完整代码

   private fun initWebview() {
        Log.d("lyy", "-----打开的网址:------url:${url}")
        edit?.setText(url)
        bdwebview?.loadUrl(url) //显示H5页面
        bdwebview?.addBridgeInterface(
            MyJavaSctiptInterface(
                this@MainActivity
            )
        )
        //支持JavaScript脚本
        bdwebview?.getSettings()?.setJavaScriptEnabled(true);
        bdwebview?.setWebViewClient(object : WebViewClient() {
            override fun shouldOverrideUrlLoading(view: WebView, url: String): Boolean {
                val hit = view.hitTestResult
                //hit.getExtra()为null或者hit.getType() == 0都表示即将加载的URL会发生重定向,需要做拦截处理
                if (TextUtils.isEmpty(hit.extra) || hit.type == 0) {
                    //通过判断开头协议就可解决大部分重定向问题了,有另外的需求可以在此判断下操作
                    Log.e("重定向", "重定向: " + hit.type + " && EXTRA()" + hit.extra + "------")
                    Log.d("重定向", "URL: $url")
                }
                return if (url.startsWith("http://") || url.startsWith("https://")) { //加载的url是http/https协议地址
                    view.loadUrl(url)
                    false //返回false表示此url默认由系统处理,url未加载完成,会继续往下走
                } else { //加载的url是自定义协议地址
                    try {
                        val intent = Intent(Intent.ACTION_VIEW, Uri.parse(url))
                        startActivity(intent)
                    } catch (e: Exception) {
                        e.printStackTrace()
                    }
                    true
                }
            }
        })


    }

    class MyJavaSctiptInterface(private val mActivity: Activity) {
        fun callPhone(strs: Array<String?>) { //拨号
            val jsonObject = JSONObject(strs[0])
            val phone = jsonObject.optString("phone")
            val intent = Intent(Intent.ACTION_CALL, Uri.parse("tel:$phone"))
            mActivity.startActivity(intent)
        }
    }

相关文章

网友评论

      本文标题:WebView在使用setUserAgentString时的坑

      本文链接:https://www.haomeiwen.com/subject/higtddtx.html