您的位置:

提示UnknownServiceException("CLEARTEXT communication not enabled for client")的解决方案

  发布时间:2024-12-17 13:09:59
出现UnknownServiceException("CLEARTEXT communication not enabled for client")的原因是OkHttp默认不允许使用明文传输数据,解决方法包括使用HTTPS协议、允许明文通信或为OkHttp配置支持明文通信的Interceptor。具体例子中介绍了如何通过修改OkHttp的配置来允许应用程序使用明文流量进行网络通信。

问题原因

出现UnknownServiceException("CLEARTEXT communication not enabled for client")的原因是OkHttp默认情况下不允许使用明文(HTTP)传输数据,而只允许使用加密的 HTTPS。然而,当尝试使用明文(HTTP)请求时,就会触发这个异常。OkHttp 3.x及以上版本默认情况下不支持明文传输数据,这是出于安全考虑。

解决方案

出现UnknownServiceException("CLEARTEXT communication not enabled for client")这个异常是因为最新的Android版本要求App默认不允许通过明文方式(Cleartext)与服务器进行通信,而OkHttp默认只支持加密通信(HTTPS),导致该异常的抛出。 要解决这个问题,可以通过以下几种方式之一: 1. 使用HTTPS协议:推荐的方式是将服务器配置为支持HTTPS协议,这样可以确保通信是加密的,同时也符合安全要求。 2. 允许明文通信:如果无法立即切换到HTTPS,也可以在AndroidManifest.xml文件中的\标签下添加android:usesCleartextTraffic="true"属性,允许App通过明文方式与服务器通信。但这种方式不是长期方案,建议尽快转向HTTPS。 3. 为OkHttp配置支持明文通信:在创建OkHttpClient实例时,可以通过在OkHttpClient.Builder中添加.addNetworkInterceptor(new ClearTextTrafficPermittedInterceptor())来允许明文通信。你也可以自定义一个ClearTextTrafficPermittedInterceptor类实现这个功能。 以下是一个示例代码,展示如何为OkHttp配置支持明文通信的Interceptor:


import okhttp3.Interceptor;
import okhttp3.Response;

import java.io.IOException;

public class ClearTextTrafficPermittedInterceptor implements Interceptor {
    @Override
    public Response intercept(Chain chain) throws IOException {
        if (chain.request().isHttps()) {
            return chain.proceed(chain.request());
        } else {
            throw new IOException("Cleartext traffic is not permitted");
        }
    }
}

在创建OkHttpClient实例时,添加上述Interceptor:


OkHttpClient client = new OkHttpClient.Builder()
        .addNetworkInterceptor(new ClearTextTrafficPermittedInterceptor())
        .build();

通过以上方式,你可以解决OkHttp出现"CLEARTTEXT communication not enabled for client"异常的问题。

具体例子

UnknownServiceException("CLEARTEXT communication not enabled for client")问题的原因是应用程序使用了不安全的明文通信(Cleartext Traffic),而OkHttp默认情况下不允许明文通信。为了保护用户数据安全,Android 9及以上版本不再允许应用程序使用明文流量进行网络通信。造成这个问题的原因是应用程序尝试在Android 9及以上版本中使用明文流量进行网络通信,而OkHttp的默认配置不允许这样的行为。 要解决这个问题,可以通过修改OkHttp的配置来允许应用程序使用明文流量进行网络通信。具体方法是配置OkHttp的ConnectionSpec,允许明文流量的通信。以下是解决问题的示例代码:


OkHttpClient client = new OkHttpClient.Builder()
    .connectionSpecs(Arrays.asList(ConnectionSpec.CLEARTEXT, ConnectionSpec.MODERN_TLS))
    .build();

上述代码中,我们通过将ConnectionSpec.CLEARTEXT添加到OkHttp的连接规范列表中,以允许应用程序使用明文流量进行网络通信。同时,我们还包含了ConnectionSpec.MODERN_TLS,以确保在可能的情况下使用更安全的传输层安全协议。 请注意,虽然上述方法可以解决这个问题,但是应该尽可能避免在应用程序中使用明文通信,因为这会增加用户数据泄露的风险。最好的做法是将应用程序迁移到使用加密通信。