【错误记录】Android WebView 报错 ( 网页无法打开 位于 baiduboxapp://speec... 的网页无法加载, 因为 net::ERR_UNKNOW_URL_SCHEME )

2023-04-24 11:24:46 浏览数 (3)

一、错误记录


报错信息 :

网页无法打开 位于 baiduboxapp://speech/startVoiceSearch?&params={“voiceSource”:“home_naver_long”}&jumpTime 的网页无法加载, 因为 net::ERR_UNKNOW_URL_SCHEME ;

二、解决方案


出现该错误的原因是 WebView 尝试加载不支持的 URL 链接 , 目前 WebView 只能支持加载 http 或 https 协议的 URL 地址 ;

当前要加载的地址是 " baiduboxapp://speech/startVoiceSearch?&params={“voiceSource”:“home_naver_long”}&jumpTime " 这是百度应用的 URL 地址 ;

出现上述问题 , 通过重写 WebViewClient 的 shouldOverrideUrlLoading 函数 , 获取要加载的 URL 地址 , 如果发现了要加载不支持的 URL 协议地址 ,则启动对应的应用加载该地址 , 如 百度 / 淘宝 / 京东 等应用 ;

解决方案 : 为 WebView 设置 WebViewClient , 重写其中的 shouldOverrideUrlLoading 函数 , 如果 url 链接是 http:// 和 https:// 页面 直接加载 , 如果是其它页面 , 直接调用对应的 app 应用 ;

代码语言:javascript复制
        // WebViewClient 是一个用于处理 WebView 页面加载事件的类
        webview.webViewClient = object : WebViewClient() {
            override fun shouldOverrideUrlLoading(view: WebView, url: String): Boolean {
                Log.i("MainActivity", "访问地址 : $url")
                // 4.0 之后必须添加该设置
                // 只能加载 http:// 和 https:// 页面 , 不能加载其它协议链接
                if (url.startsWith("http://") || url.startsWith("https://")) {
                    view.loadUrl(url)
                    return true
                } else {
                    if (url.startsWith("weixin://") ||
                        url.startsWith("alipays://") ||
                        url.startsWith("tel://") ||
                        url.startsWith("baiduboxapp://") ) {
                        val intent = Intent(Intent.ACTION_VIEW, Uri.parse(url))
                        startActivity(intent)
                        return true
                    }
                }
                return false
            }

            // SSL 证书校验出现异常
            override fun onReceivedSslError(
                view: WebView,
                handler: SslErrorHandler,
                error: SslError) {
                when (error.primaryError) {
                    SslError.SSL_INVALID, SslError.SSL_UNTRUSTED -> {
                        handler.proceed()
                    }
                    else -> handler.cancel()
                }
            }
        }

三、开发通过自定义的 URL 协议启动的应用


在 AndroidManifest.xml 清单文件中注册一个自定义的 URL 协议处理器 , 下面注册的协议名称是 myapp ;

代码语言:javascript复制
<activity android:name=".MyActivity">
	<intent-filter>
		<action android:name="android.intent.action.VIEW" />
    	<category android:name="android.intent.category.DEFAULT" />
    	<category android:name="android.intent.category.BROWSABLE" />
    	<data android:scheme="myapp" />
    </intent-filter>
</activity>

在应用中就可以使用 myapp:// 开头的 URL 来启动上述 MyActivity ;

在 WebView 中如果遇到了此类 URL 链接 , 使用 WebViewClient 的 shouldOverrideUrlLoading 方法来拦截不支持的 URL 协议,不直接加载这些链接 , 而是直接启动 ;

通用处理方案如下 , 一般是启动该 url 对应的应用 ;

代码语言:javascript复制
WebView webView = findViewById(R.id.webView);
webView.setWebViewClient(new WebViewClient() {
    @Override
    public boolean shouldOverrideUrlLoading(WebView view, String url) {
        if (url.startsWith("myapp://")) {
            // 处理 myapp 协议的 URL
            return true;
        }
        // 其他协议的 URL 使用默认行为
        return super.shouldOverrideUrlLoading(view, url);
    }
});

0 人点赞