应用上架GooglePlay 收到邮件提示
出现这个原因是因为我在app中使用webview加载Https的H5界面,在onReceivedSslError()中处理SslErrorHandler时,出现白屏现象,原因是webview默认在加载有证书验证的url时,会默认使用handler.cancel()进行拦截操作,这里只需要改成handler.proceed()。
2种解决方式
1.常规解决方式 :
出现在错误的时候让用户同意
final AlertDialog.Builder builder = new AlertDialog.Builder(HomeWebActivity.this); String message = "SSL Certificate error."; switch (error.getPrimaryError()) { case SslError.SSL_UNTRUSTED: message = "The certificate authority is not trusted."; break; case SslError.SSL_EXPIRED: message = "The certificate has expired."; break; case SslError.SSL_IDMISMATCH: message = "The certificate Hostname mismatch."; break; case SslError.SSL_NOTYETVALID: message = "The certificate is not yet valid."; break; } message += " Do you want to continue anyway?"; builder.setTitle("SSL Certificate Error"); builder.setMessage(message); builder.setPositiveButton("continue", new DialogInterface.OnClickListener() { @Override public void onClick(DialogInterface dialog, int which) { handler.proceed(); } }); builder.setNegativeButton("cancel", new DialogInterface.OnClickListener() { @Override public void onClick(DialogInterface dialog, int which) { handler.cancel(); } }); final AlertDialog dialog = builder.create(); dialog.show();
2.第二种加载https 证书
证书一般常规可以问前端或者后端要。参考 从网页中获取Ssl证书_NextWarm的博客-CSDN博客)拿到将证书(.cer文件)复制到应用程序的res / raw文件夹中
private static final int[] CERTIFICATES = { R.raw.cardhobby, // you can put several certificates }; private ArrayList<SslCertificate> certificates = new ArrayList<>(); private void loadSSLCertificates() { try { CertificateFactory certificateFactory = CertificateFactory.getInstance("X.509"); for (int rawId : CERTIFICATES) { InputStream inputStream = getResources().openRawResource(rawId); InputStream certificateInput = new BufferedInputStream(inputStream); try { Certificate certificate = certificateFactory.generateCertificate(certificateInput); if (certificate instanceof X509Certificate) { X509Certificate x509Certificate = (X509Certificate) certificate; SslCertificate sslCertificate = new SslCertificate(x509Certificate); certificates.add(sslCertificate); } else { } } catch (CertificateException exception) { } finally { try { certificateInput.close(); inputStream.close(); } catch (IOException e) { e.printStackTrace(); } } } } catch (CertificateException e) { e.printStackTrace(); } }
binding.webview.setWebViewClient(new WebViewClient() { public void onReceivedSslError(WebView view, SslErrorHandler handler, SslError error) { //handler.cancel(); // Android默认的处理方式 // handler.proceed(); // 接受所有网站的证书 //handleMessage(Message msg); // 进行其他处理 SslCertificate serverCertificate = error.getCertificate(); Bundle serverBundle = SslCertificate.saveState(serverCertificate); for (SslCertificate appCertificate : certificates) { if (TextUtils.equals(serverCertificate.toString(), appCertificate.toString())) { // First fast check Bundle appBundle = SslCertificate.saveState(appCertificate); Set<String> keySet = appBundle.keySet(); boolean matches = true; for (String key : keySet) { Object serverObj = serverBundle.get(key); Object appObj = appBundle.get(key); if (serverObj instanceof byte[] && appObj instanceof byte[]) { // key "x509-certificate" if (!Arrays.equals((byte[]) serverObj, (byte[]) appObj)) { matches = false; break; } } else if ((serverObj != null) && !serverObj.equals(appObj)) { matches = false; break; } } if (matches) { handler.proceed(); return; } } }