ほぼ2年間、問題なくHTTPURLを使用してWebサーバーからデータを正常にフェッチしてきました。
最近、セキュリティ上の理由からHTTPSに移行しましたが、そのときに問題が発生しました。
WiFiを使用すると、すべてが正常に機能します。2Gポケットデータに定期的に接続すると、サーバーの問題によって接続がリセットされます。
DefaultHttpClientを使用してサーバーに接続しています。
私は多くの回避策を試しましたが、何も私を救いませんでした。
javax.net.ssl.SSLException:読み取りエラー:ssl = 0x56e63588:システムコール中のI/Oエラー、ピアによって接続がリセットされました
利用可能なすべてのプロパティをHttpConnectionParamsに適用しました
_HttpConnectionParams.setConnectionTimeout(httpClient.getParams(),120000);
HttpConnectionParams.setSoTimeout(httpClient.getParams(), 120000);
HttpConnectionParams.setLinger(httpClient.getParams(), 120000);
HttpConnectionParams.setTcpNoDelay(httpClient.getParams(), true);
HttpConnectionParams.setStaleCheckingEnabled(httpClient.getParams(), false);
_
そして別のグーグルグループの議論は、この問題が活動の理想的な状態の原因である可能性があることを示唆したので、私は画面を目覚めさせ続けるためにこのようなものを実装しました。
_powerManager = (PowerManager) getSystemService(Context.POWER_SERVICE);
wakeLock = powerManager.newWakeLock(PowerManager.FULL_WAKE_LOCK,"My Tag");
wakeLock.acquire();
_
そして、onDestroy()
でwakeLock.release();
でリリースしました
しかし、それも役に立ちませんでした。
また、サーバー側で確認する必要があるものは他にありますか?
同様のSSLエラーが発生していました。 Pre-LollipopデバイスはSSLTLSv1.1、TLSv1.2をサポートしていないことが判明しました。これらのSSLプロトコルを有効にするTLSSocketFactoryラッパークラスを含めることで修正しました。コードに以下を追加してみてください。
static {
final SSLSocketFactory sslSocketFactory;
try {
sslSocketFactory = new TLSSocketFactory();
HttpsURLConnection.setDefaultSSLSocketFactory(sslSocketFactory);
} catch (KeyManagementException ignored) {
} catch (NoSuchAlgorithmException e) {
e.printStackTrace();
}
}
import Java.io.IOException;
import Java.net.InetAddress;
import Java.net.Socket;
import Java.net.UnknownHostException;
import Java.security.KeyManagementException;
import Java.security.NoSuchAlgorithmException;
import javax.net.ssl.SSLContext;
import javax.net.ssl.SSLSocket;
import javax.net.ssl.SSLSocketFactory;
/**
* @author fkrauthan
* http://blog.dev-area.net/2015/08/13/Android-4-1-enable-tls-1-1-and-tls-1-2/
*
*
// IMPORTANT: Pre-Lollipop devices do not support SSL TLSv1.1, TLSv1.2
// so I've included a TLSSocketFactory wrapper class that enables these SSL
// protocols.
*/
public class TLSSocketFactory extends SSLSocketFactory {
private SSLSocketFactory internalSSLSocketFactory;
public TLSSocketFactory() throws KeyManagementException, NoSuchAlgorithmException {
SSLContext context = SSLContext.getInstance("TLS");
context.init(null, null, null);
internalSSLSocketFactory = context.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)) {
((SSLSocket)socket).setEnabledProtocols(new String[] {"TLSv1.1", "TLSv1.2"});
}
return socket;
}
}