HttpURLConnection抛出java.net.SocketTimeoutException:在Android 4.1.1中SSL握手超时
我的代码在Android 5.0及更高版本中运行时运行良好。但在Android 4.1.1中,它抛出了java.net.SocketTimeoutException:SSL握手超时HttpURLConnection抛出java.net.SocketTimeoutException:在Android 4.1.1中SSL握手超时,java,android,ssl,timeout,httpurlconnection,Java,Android,Ssl,Timeout,Httpurlconnection,我的代码在Android 5.0及更高版本中运行时运行良好。但在Android 4.1.1中,它抛出了java.net.SocketTimeoutException:SSL握手超时 URL url; HttpURLConnection connection = null; String charset = "UTF-8"; String accessToken = ""; try { ArrayList<NameValuePa
URL url;
HttpURLConnection connection = null;
String charset = "UTF-8";
String accessToken = "";
try {
ArrayList<NameValuePair> postParameters = new ArrayList<NameValuePair>();
postParameters.add(new BasicNameValuePair("client_id", CLIENT_ID));
postParameters.add(new BasicNameValuePair("client_secret", CLIENT_SECRET));
postParameters.add(new BasicNameValuePair("grant_type", CLIENT_CREDENTIALS_GRANT_TYPE));
//Create connection
url = new URL(ACCESS_TOKEN_URL);
connection = (HttpURLConnection)url.openConnection();
connection.setReadTimeout( 10000 /*milliseconds*/ );
connection.setConnectTimeout( 15000 /* milliseconds */ );
connection.setInstanceFollowRedirects(false);
connection.setRequestMethod("POST");
connection.setRequestProperty("Content-Type", "application/x-www-form-urlencoded;charset=" + charset);
connection.setUseCaches(false);
connection.setDoInput(true);
connection.setDoOutput(true);
//Send request
DataOutputStream wr = new DataOutputStream(connection.getOutputStream());
wr.write(getQuery(postParameters).getBytes(charset));
wr.flush();
wr.close();
int responseCode = connection.getResponseCode();
InputStream is = null;
if(responseCode==HttpStatus.SC_OK) {
is = connection.getInputStream();
}
else{
is = connection.getErrorStream();
}
Log.d(TAG, "responseCode: "+responseCode);
BufferedReader reader = new BufferedReader(new InputStreamReader(is));
StringBuilder sb = new StringBuilder();
String line = null;
while ((line = reader.readLine()) != null) {
sb.append(line + "\n");
}
is.close();
reader.close();
String jsonResult = sb.toString();
JSONObject jsonObject = new JSONObject(jsonResult);
if(responseCode==HttpStatus.SC_OK){
accessToken = jsonObject.getString("access_token");
SettingsPreference.setAccessToken(accessToken);
Log.d(TAG, "access token: "+accessToken);
}
else {
accessToken = null;
}
} catch (Exception e) {
e.printStackTrace();
} finally {
if(connection != null) {
connection.disconnect();
}
}
URL;
HttpURLConnection=null;
字符串charset=“UTF-8”;
字符串accessToken=“”;
试一试{
ArrayList后参数=新的ArrayList();
添加(新的BasicNameValuePair(“客户端id”,客户端id));
添加(新的BasicNameValuePair(“client_secret”,client_secret));
添加(新的BasicNameValuePair(“授权类型”,客户端授权类型));
//创建连接
url=新url(访问令牌url);
connection=(HttpURLConnection)url.openConnection();
setReadTimeout(10000/*毫秒*/);
setConnectTimeout(15000/*毫秒*/);
connection.setInstanceFollowDirections(false);
connection.setRequestMethod(“POST”);
connection.setRequestProperty(“内容类型”,“应用程序/x-www-form-urlencoded;字符集=“+charset”);
connection.setUseCaches(false);
connection.setDoInput(true);
connection.setDoOutput(真);
//发送请求
DataOutputStream wr=新的DataOutputStream(connection.getOutputStream());
write(getQuery(postParameters).getBytes(charset));
wr.flush();
wr.close();
int responseCode=connection.getResponseCode();
InputStream=null;
if(responseCode==HttpStatus.SC_OK){
is=connection.getInputStream();
}
否则{
is=connection.getErrorStream();
}
Log.d(标签“responseCode:+responseCode”);
BufferedReader reader=新的BufferedReader(新的InputStreamReader(is));
StringBuilder sb=新的StringBuilder();
字符串行=null;
而((line=reader.readLine())!=null){
sb.追加(第+行“\n”);
}
is.close();
reader.close();
字符串jsonResult=sb.toString();
JSONObject JSONObject=新的JSONObject(jsonResult);
if(responseCode==HttpStatus.SC_OK){
accessToken=jsonObject.getString(“访问令牌”);
SettingsReference.setAccessToken(accessToken);
Log.d(标记“访问令牌:”+accessToken);
}
否则{
accessToken=null;
}
}捕获(例外e){
e、 printStackTrace();
}最后{
if(连接!=null){
连接断开();
}
}
我已经做了很多研究,这是相当令人沮丧的。我做错了什么?这是服务器问题吗?非常感谢您的帮助。在较低的sdk级别上使用TrustManager? 您的旧设备上的受信任证书可能不是最新的。如果设备低于某个sdk级别,则可以尝试实现和使用 用于信任自签名或未正确签名的域的简单库。 但在您的情况下,我认为只为您的域创建一个例外,而不检查特定sdk级别下的证书是很方便的 此回购协议使用TrustManager对某些证书/域进行例外处理。如果您要使用它,请确保您正确使用它,因为Google Play可能不会接受您的应用程序更新/发布
请看我对其他问题的回答 我在4.1.1版本的URL连接上也有类似的问题,我的是EOF,而它在其他版本上工作得很好。我记得这篇文章帮助我意识到了问题所在。但是我认为soruce文件不再可用了。无论如何,帮助解决这个问题的是切换到DefaultHttp客户端,它可以在所有版本上工作…这是我向您推荐的最快的解决方案:尝试使用网络库/包装器,如DefaultHttp或Android客户端或OkHttp…您的手机4.1.1的时间正确吗?当客户端和服务器在时间上不同时,SSL不起作用。(当然还有约会!)看起来像是个bug,你可以试试看;我也有类似的问题,但是针对三星galaxy tab的,这是您的情况吗?@Paizo不仅在三星设备中,而且在Genymotion中也是如此。如果您提供URL以查看您尝试访问的主机是否有特殊之处,可能会有所帮助。可能与密码、协议版本、SNI、中间盒有关…添加一些说明here@Billa你是什么意思?我想你可以在另一篇文章的“我的答案”或SimpleTrust的github页面上找到你想要的任何东西。但是,如果你告诉我你需要什么样的描述,我会很乐意创建一个。(我没有在这里做详细描述,因为我不想重复上一个答案)证书问题不会导致握手超时。