HttpURLConnection抛出java.net.SocketTimeoutException:在Android 4.1.1中SSL握手超时

时间:2015-06-17 11:14:31

标签: 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<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(); 
        }
    }

我已经做了很多研究,这非常令人沮丧。我出了什么问题?这是服务器问题吗?非常感谢您的帮助。

1 个答案:

答案 0 :(得分:-1)

在较低的sdk级别上使用TrustManager吗?

在您较旧的设备上,可信证书有可能不是最新的。如果设备处于特定的sdk级别,则可以尝试实现并使用SimpleTrust

一个简单的库,用于信任自签名或未正确签名的域。 但是对于您而言,我认为只为您的域设置一个例外并且不检查特定sdk级别下的证书会很方便。

此存储库使用TrustManager来为某些证书/域设置例外。如果要使用它,请确保正确使用它,因为Google Play可能不会接受您的应用程序更新/发布。

请参阅我对this其他问题的回答。