Retrofit在Android 5.0以下设备请求失败:不支持协议问题求助
Got it, let's break down why this is happening and how to fix it:
Your error SSL23_GET_SERVER_HELLO:unsupported protocol is caused by older Android versions (pre-5.0, API level <21) not enabling TLS 1.2 by default. Most modern websites (including the Hepsiburada one you're targeting) have phased out support for insecure, outdated protocols like SSLv3, TLS 1.0, and TLS 1.1. So when your app tries to connect from an older device, the server rejects the handshake because it doesn't recognize the protocol being used.
Here's the step-by-step fix:
1. Customize OkHttp to enforce modern TLS protocols
Retrofit relies on OkHttp for network calls, so we need to tweak the OkHttpClient instance to force TLS 1.2 support on older devices.
First, ensure you have OkHttp in your build.gradle (it's usually included with Retrofit, but explicit is better):
implementation 'com.squareup.okhttp3:okhttp:4.11.0' // Use the latest stable version available
2. Update your Retrofit initialization code
Replace your existing Retrofit setup with this code that includes a custom OkHttpClient:
private static final String TAG = "TESTTESTTESTTEST"; private static String url = "https://www.hepsiburada.com/lassa-235-65r17-108h-xl-competush-" + "l-p-OTLST216410?magaza=LastikArt%C4%B1&utm_source=pc&utm_medium=cimri&utm_campaign" + "=c&utm_content=c&utm_term=5083&wt_pc=cimri.c.5083.pc/"; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); // Create a connection spec that uses only secure modern protocols ConnectionSpec modernTlsSpec = new ConnectionSpec.Builder(ConnectionSpec.MODERN_TLS) .tlsVersions(TlsVersion.TLS_1_2, TlsVersion.TLS_1_3) .cipherSuites( CipherSuite.TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256, CipherSuite.TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256, CipherSuite.TLS_DHE_RSA_WITH_AES_128_GCM_SHA256 ) .build(); // Build OkHttpClient with the custom spec OkHttpClient okHttpClient = new OkHttpClient.Builder() .connectionSpecs(Collections.singletonList(modernTlsSpec)) // Uncomment below if you need to support legacy servers (not recommended) // .connectionSpecs(Arrays.asList(modernTlsSpec, ConnectionSpec.COMPATIBLE_TLS)) .build(); // Initialize Retrofit with our custom OkHttpClient Retrofit retrofit = new Retrofit.Builder() .addConverterFactory(ScalarsConverterFactory.create()) .baseUrl("https://www.google.com/") .client(okHttpClient) // This line is crucial! .build(); IGetHtml iGetHtml = retrofit.create(IGetHtml.class); Call<String> stringCall = iGetHtml.getHtml(url); stringCall.enqueue(new Callback<String>() { @Override public void onResponse(Call<String> call, Response<String> response) { if (response.isSuccessful()) { String responseString = response.body(); Log.e(TAG, "onResponse: " + response.body()); } } @Override public void onFailure(Call<String> call, Throwable t) { Log.e(TAG, "onFailure: " + t); } }); }
3. What this does exactly
ConnectionSpec.MODERN_TLSdefines a set of secure protocols and cipher suites that are widely accepted by modern servers.- By explicitly specifying
tlsVersions(TlsVersion.TLS_1_2, TlsVersion.TLS_1_3), we override the default protocol settings on older Android devices, forcing them to use these supported protocols. - If you absolutely need to connect to some older servers that still use legacy protocols, you can add
ConnectionSpec.COMPATIBLE_TLSas a fallback (commented in the code), but this is not ideal for security.
Quick checks to avoid other issues
- Ensure your
minSdkVersionis set correctly inbuild.gradle(if you're supporting pre-5.0 devices, this fix is non-negotiable). - Double-check that your
IGetHtmlinterface is correctly defined to handle the full URL (since you're passing the full URL togetHtml(), make sure the interface uses@Urlannotation):
public interface IGetHtml { @GET Call<String> getHtml(@Url String url); }
内容的提问来源于stack exchange,提问作者Emil Mammadov

