咱们先看下报错结果图:
我这边是华为荣耀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();
}
}