我正在使用一个Android应用程序,该应用程序只能在Android 4.2.2设备上专门运行。
该应用程序具有Web视图。在该Web视图中,我正在加载一个网站,该网站托管在Firebase服务器上。
public class TLSSocketFactory extends SSLSocketFactory {
private static final String TAG = "TLSSocketFactory";
private SSLSocketFactory internalSSLSocketFactory;
public TLSSocketFactory() {
internalSSLSocketFactory = getSslContext().getSocketFactory();
}
@Override
public String[] getDefaultCipherSuites() {
return internalSSLSocketFactory.getDefaultCipherSuites();
}
@Override
public String[] getSupportedCipherSuites() {
return internalSSLSocketFactory.getSupportedCipherSuites();
}
@Override
public Socket createSocket(Socket s, String host, int port, boolean autoClose) throws IOException {
return enableTLSOnSocket(internalSSLSocketFactory.createSocket(s, host, port, autoClose));
}
@Override
public Socket createSocket(String host, int port) throws IOException, UnknownHostException {
return enableTLSOnSocket(internalSSLSocketFactory.createSocket(host, port));
}
@Override
public Socket createSocket(String host, int port, InetAddress localHost, int localPort) throws IOException, UnknownHostException {
return enableTLSOnSocket(internalSSLSocketFactory.createSocket(host, port, localHost, localPort));
}
@Override
public Socket createSocket(InetAddress host, int port) throws IOException {
return enableTLSOnSocket(internalSSLSocketFactory.createSocket(host, port));
}
@Override
public Socket createSocket(InetAddress address, int port, InetAddress localAddress, int localPort) throws IOException {
return enableTLSOnSocket(internalSSLSocketFactory.createSocket(address, port, localAddress, localPort));
}
private Socket enableTLSOnSocket(Socket socket) {
if(socket != null && (socket instanceof SSLSocket) && isTLSServerEnabled((SSLSocket) socket) ) {
((SSLSocket)socket).setEnabledProtocols(new String[] {"TLSv1.2"});
}
return socket;
}
public static X509TrustManager getTrustManager() {
return new X509TrustManager() {
@Override
public java.security.cert.X509Certificate[] getAcceptedIssuers() {
return new java.security.cert.X509Certificate[] {};
}
@Override
public void checkClientTrusted(X509Certificate[] chain, String authType) throws CertificateException {}
@Override
public void checkServerTrusted(X509Certificate[] chain, String authType) throws CertificateException {}
};
}
public static SSLContext getSslContext() {
try {
SSLContext sslContext = SSLContext.getInstance("TLS");
sslContext.init(null, null, null);
return sslContext;
} catch (Exception ex) {
Log.e(TAG, "Problem while getting SslContext", ex);
throw new RuntimeException(ex);
}
}
}
public class MainActivity extends AppCompatActivity {
private static final String TAG = "MainActivity";
private static final String HTTP = "http://";
private static final String HTTPS = "https://";
private static final String CSS_FILE = ".css";
private static final String JS_FILE = ".js";
private static final String CSS_DIR = "/css/";
private static final String JS_DIR = "/js/";
private WebView webView;
private ImageView button;
private EditText urlView;
private ProgressBar progressBar;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
progressBar = (ProgressBar) findViewById(R.id.progress_bar);
progressBar.getProgressDrawable().setColorFilter(getResources().getColor(R.color.colorAccent), android.graphics.PorterDuff.Mode.SRC_IN);
urlView = (EditText) findViewById(R.id.url);
webView = (WebView) findViewById(R.id.web_view);
WebSettings settings = webView.getSettings();
settings.setJavaScriptEnabled(true);
settings.setDomStorageEnabled(true);
webView.setWebChromeClient(buildWebChromeClient());
webView.setWebViewClient(buildClient());
webView.post(new Runnable() {
@Override
public void run() {
webView.loadUrl("https://sample-project.firebaseapp.com");
}
});
button = (ImageView) findViewById(R.id.button);
button.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
onButtonClick();
}
});
}
private WebViewClient buildClient() {
return new WebViewClient() {
private OkHttpClient okHttp = new OkHttpClient.Builder().sslSocketFactory(new TLSSocketFactory(), TLSSocketFactory.getTrustManager()).build();
@Override
public WebResourceResponse shouldInterceptRequest(WebView view, String url) {
Log.e(TAG, "URL -> " + url);
/* if (url.contains(CSS_FILE) || url.contains(JS_FILE) || url.contains(CSS_DIR) || url.contains(JS_DIR)) {
Log.e(TAG, "Css or js -> default interceptor");
return super.shouldInterceptRequest(view, url);
} else {*/
Request okHttpRequest = new Request.Builder().url(url).header("User-Agent", "OkHttp Example").build();
try {
Response response = okHttp.newCall(okHttpRequest).execute();
return new WebResourceResponse("text/html", "UTF-8", response.body().byteStream());
} catch (IOException e) {
e.printStackTrace();
}
return null;
// }
}
public void onPageFinished(WebView view, String url) {
Log.i(TAG, "Finished loading URL: " + url);
super.onPageFinished(view, url);
// webView.loadUrl(url);
}
public void onReceivedError(WebView view, int errorCode, String description, String failingUrl) {
// MessageDialogFragment.getInstance(R.string.information, getString(R.string.oh_no) + description).show(getSupportFragmentManager(), "MessageDialogFragment");
Log.i(TAG, "failing URL: " + failingUrl);
}
@Override
public void onReceivedSslError(WebView view, SslErrorHandler handler, SslError error) {
handler.proceed(); // Ignore SSL certificate errors
}
};
}
private WebChromeClient buildWebChromeClient() {
return new WebChromeClient() {
public void onProgressChanged(WebView view, int progress) {
if (progress < 100 && progressBar.getVisibility() == ProgressBar.GONE) {
progressBar.setVisibility(ProgressBar.VISIBLE);
}
progressBar.setProgress(progress);
if (progress == 100) {
progressBar.setVisibility(ProgressBar.GONE);
}
}
@Override
public boolean onConsoleMessage(ConsoleMessage m) {
switch (m.messageLevel()) {
case LOG:
Log.i(TAG, String.format("%s (%s:%d)", m.message(), m.sourceId(), m.lineNumber()));
return true;
case TIP:
Log.v(TAG, String.format("%s (%s:%d)", m.message(), m.sourceId(), m.lineNumber()));
return true;
case DEBUG:
Log.d(TAG, String.format("%s (%s:%d)", m.message(), m.sourceId(), m.lineNumber()));
return true;
case WARNING:
Log.w(TAG, String.format("%s (%s:%d)", m.message(), m.sourceId(), m.lineNumber()));
return true;
case ERROR:
Log.e(TAG, String.format("%s (%s:%d)", m.message(), m.sourceId(), m.lineNumber()));
return true;
}
return false;
}
};
}
private void onButtonClick() {
KeyboardManager.hideKeyboard(this, getCurrentFocus());
if(NetworkManager.isNetworkEnable(this)) {
String url = urlView.getText().toString();
if (StringUtils.isNotBlank(url)) {
if(!(url.startsWith(HTTP) || url.startsWith(HTTPS))){
// url = HTTP + url;
}
// webView.loadUrl(url);
} else {
MessageDialogFragment.getInstance(R.string.information, getString(R.string.wrong_url)).show(getSupportFragmentManager(), "MessageDialogFragment");
}
} else {
MessageDialogFragment.getInstance(R.string.information, getString(R.string.no_network)).show(getSupportFragmentManager(), "MessageDialogFragment");
}
}
}
当我尝试在WebView中加载网站URL时遇到的问题是
E /铬:外部/铬/网络/套接字/ssl_client_socket_openssl.cc:792:[0102/102633:ERROR:ssl_client_socket_openssl.cc(792)]握手失败;返回-1,SSL错误代码1,net_error -107