Android开发之WebView加载自定义scheme报错net::ERR_UNKNOWN_URL_SCHEME(附带源码标题下面可点击下载)

咱们先看下报错结果图:

我这边是华为荣耀7i手机才出现这个情况,总结得出结论android6.0以上加载自定义scheme会报错如下,6.0以下貌似不会

三星和模拟器没有可以直接加载这个url

,网页出来后才出现这个错误页面,原因是加载的这个url内部有JavaScript代码里面包含自定义scheme代码导致加载这个JavaScript代码里面的自定义scheme的时候就报错无法加载。

下面的加载的url地址:

https://www.yunzhijia.com/pubacc/public/data/19/06/26/ewsqZbAD.html?p=XT-1088eb69-d338-4779-9298-77d89b8be806&f=ewsqZbAD&success=false&errorMsg=

看下报错日志:

[INFO:CONSOLE(62)] "Mixed Content: 
The page at 'https://www.yunzhijia.com/pubacc/public/data/19/06/26/ewsqZbAD.html?p=XT-1088eb69-d338-4779-9298-77d89b8be806&f=ewsqZbAD&success=false&errorMsg=' 
was loaded over HTTPS, but requested an insecure resource 'xuntong:getPersonInfo:1:%7B%7D'. 
This content should also be served over HTTPS.", source: https://do.yunzhijia.com/pub/js/qingjs.js (62)

看最后一句https://do.yunzhijia.com/pub/js/qingjs.js这是无法加载的JavaScript源码:

我先说下我这边情况,我这边加载的https网址,但是https网址里面携带有自定义的scheme属性JavaScript文件,android中默认加载http和https协议,其他自定义协议规定为不安全默认不让加载。咱们可以看下webview的报错提示:

chromium: [INFO:CONSOLE(1)] "Mixed Content: The page at 'https://www.yunzhijia.com/pubacc/public/data/19/06/26/ewsqZbAD.html?p=XT-1088eb69-d338-4779-9298-77d89b8be806&f=ewsqZbAD&success=false&errorMsg=' was loaded over HTTPS, but requested an insecure image 'http://do.yunzhijia.com/microblog/filesvr/5d13288c90144e08bfcd6496'. This content should also be served over HTTPS.", source: https://www.yunzhijia.com/pubacc/public/data/19/06/26/ewsqZbAD.html?p=XT-1088eb69-d338-4779-9298-77d89b8be806&f=ewsqZbAD&success=false&errorMsg= (1)

划重点了:计解决办法如下

遇到这种情况我们有两种解决办法

第一种:就是在shouldOverrideUrlLoading方法中设置为外部浏览器打开(体验差不推荐)

第二种:就是在shouldOverrideUrlLoading方法中拦截自定义scheme

如下代码我才用的第二种方案:

webview.setWebViewClient(new WebViewClient() {
            @Override
            public boolean shouldOverrideUrlLoading(WebView view, String url) {
                Uri uri = Uri.parse(url);
                LogUtils.e("打印Scheme", uri.getScheme() + "==" + url);
                if (!"http".equals(uri.getScheme()) || !"https".equals(uri.getScheme())) {
                    return false;
                } else {
                    view.loadUrl(url);
                    return false;
                }

            }

            @Override
            public void onPageFinished(WebView view, String url) {
                super.onPageFinished(view, url);
            }
        });
        webview.loadUrl(url);

咱们再来看下效果:

但是当我们点击进去JavaScript里面带有自定义scheme的js页面发现点击是不了,报了个错:

I/chromium: [INFO:CONSOLE(2)] "tap事件:ours.getNS().saveForm(ours.getNS().afterSaveForm)不能被执行,", source: https://www.formtalk.net/res_common/ours_phone_form.min.js?V=1.1.2.6 (2)
I/chromium: [INFO:CONSOLE(2)] "TypeError: Cannot read property 'getItem' of null", source: https://www.formtalk.net/res_common/ours_phone_form.min.js?V=1.1.2.6 (2)

说的是JavaScript里面的js方法不能被执行,什么原因呢?

搜了下找到了个可行的方法

//允许android调用javascript
webSettings.setDomStorageEnabled(true);

再此感谢原博主博主链接

然后点击JavaScript页面生效了。

最后贴出完整代码:

package com.yhsh.wallet.ui;


import android.content.Intent;
import android.net.Uri;
import android.os.Build;
import android.os.Bundle;
import android.support.v7.widget.Toolbar;
import android.text.TextUtils;
import android.util.DisplayMetrics;
import android.webkit.WebSettings;
import android.webkit.WebView;
import android.webkit.WebViewClient;
import android.widget.TextView;

import com.yhsh.mobile.basic.util.LogUtils;
import com.yhsh.mobile.common.base.BaseActivity;
import com.yhsh.mobile.uiwidget.widget.CustomWebview;

/**
 * 暂定为集团理财
 *
 * @author DELL
 */
public class H5Activity extends BaseActivity {
    @Override
    public int getLayoutResId() {
        return com.yhsh.mobile.login.R.layout.agreement_dialog;
    }

    @Override
    public void initView(Bundle savedInstanceState) {
        String title = getIntent().getStringExtra("title");
        String url = getIntent().getStringExtra("url");
        String welcome = getIntent().getStringExtra("welcome");
        Toolbar toolbar = findViewById(com.yhsh.mobile.login.R.id.toolbar);

        TextView tvTitle = findViewById(com.yhsh.mobile.login.R.id.toolbar_title);
        tvTitle.setText(title);
        CustomWebview wvAgreement = findViewById(com.yhsh.mobile.login.R.id.wv_agreement);
        setSupportToolbar(toolbar, v -> {
            if (wvAgreement.canGoBack()) {
                wvAgreement.goBack();
            } else {
                if (!TextUtils.isEmpty(welcome)) {
                    //当是欢迎页面进来的时候,点击返回直接进入首页
                    startActivity(new Intent(this, SplashActivity.class));
                }
                finish();
            }
        });

        WebSettings webSettings = wvAgreement.getSettings();
        webSettings.setSupportZoom(true);
        webSettings.setJavaScriptEnabled(true);
        //允许android调用javascript
        webSettings.setDomStorageEnabled(true);
        webSettings.setJavaScriptCanOpenWindowsAutomatically(true);


        webSettings.setBuiltInZoomControls(true);
        webSettings.setAllowFileAccess(true);
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN) {
            webSettings.setAllowFileAccessFromFileURLs(true);
            webSettings.setAllowUniversalAccessFromFileURLs(true);
        }
        webSettings.setUseWideViewPort(true);
        webSettings.setLoadWithOverviewMode(true);
        webSettings.setCacheMode(WebSettings.LOAD_NO_CACHE);
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
            webSettings.setMixedContentMode(WebSettings.MIXED_CONTENT_ALWAYS_ALLOW);
        }
        DisplayMetrics metrics = new DisplayMetrics();
        getWindowManager().getDefaultDisplay().getMetrics(metrics);
        int mDensity = metrics.densityDpi;
        if (mDensity == 240) {
            webSettings.setDefaultZoom(WebSettings.ZoomDensity.FAR);
        } else if (mDensity == 160) {
            webSettings.setDefaultZoom(WebSettings.ZoomDensity.MEDIUM);
        } else if (mDensity == 120) {
            webSettings.setDefaultZoom(WebSettings.ZoomDensity.CLOSE);
        } else if (mDensity == DisplayMetrics.DENSITY_XHIGH) {
            webSettings.setDefaultZoom(WebSettings.ZoomDensity.FAR);
        } else if (mDensity == DisplayMetrics.DENSITY_TV) {
            webSettings.setDefaultZoom(WebSettings.ZoomDensity.FAR);
        }

        wvAgreement.setWebViewClient(new WebViewClient() {
            @Override
            public boolean shouldOverrideUrlLoading(WebView view, String url) {
                Uri uri = Uri.parse(url);
                LogUtils.e("打印Scheme", uri.getScheme() + "==" + url);
                if (!"http".equals(uri.getScheme()) || !"https".equals(uri.getScheme())) {
                    return false;
                } else {
                    view.loadUrl(url);
                    return false;
                }

            }

            @Override
            public void onPageFinished(WebView view, String url) {
                super.onPageFinished(view, url);
            }
        });
        wvAgreement.loadUrl(url);
    }
}

最终结论经过我后期代码测试发现最终上面问题解决办法:

说简单点直接设置setWebViewClient重写shouldOverrideUrlLoading方法即可

 @Override
        public boolean shouldOverrideUrlLoading(WebView view, String url) {
            return super.shouldOverrideUrlLoading(view, url);
        }

请看最终代码如下:直接用下面这个原生简单的webview就可以正常加载自定义scheme和JS事件点击了

package com.xiayiye.mytestapp;

import android.app.Activity;
import android.os.Bundle;
import android.webkit.WebSettings;
import android.webkit.WebView;
import android.webkit.WebViewClient;
import android.widget.TextView;

public class MainActivity extends Activity {

    private WebView wvInternetPage;
    private TextView tvTittle;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        wvInternetPage = findViewById(R.id.wv_internet_page);
        tvTittle = findViewById(R.id.tv_tittle);
        WebViewOption();
    }

    private void WebViewOption() {
        WebSettings settings = wvInternetPage.getSettings();
        settings.setJavaScriptEnabled(true);
        //允许打开js新窗口
        settings.setJavaScriptCanOpenWindowsAutomatically(true);
        settings.setDomStorageEnabled(true);
        wvInternetPage.setWebViewClient(new MyWebViewClient());
        wvInternetPage.loadUrl("https://www.yunzhijia.com/pubacc/public/data/19/06/26/ewsqZbAD.html");
//        wvInternetPage.loadUrl("https://www.baidu.com");
    }

    private class MyWebViewClient extends WebViewClient {

        @Override
        public boolean shouldOverrideUrlLoading(WebView view, String url) {
            return super.shouldOverrideUrlLoading(view, url);
        }

        @Override
        public void onPageFinished(WebView view, String url) {
            tvTittle.setText(view.getTitle());
            super.onPageFinished(view, url);
        }
    }

    @Override
    public void onBackPressed() {
        if (wvInternetPage.canGoBack()) {
            wvInternetPage.goBack();
            return;
        }
        super.onBackPressed();
    }
}
发布了191 篇原创文章 · 获赞 105 · 访问量 36万+

猜你喜欢

转载自blog.csdn.net/xiayiye5/article/details/97908815
今日推荐