Table of contents

Fix Android 9+ Error: Cleartext HTTP traffic not permitted

Android Apr 26, 2020 Viewed 2.4K Comments 0

Question

My Android project works fine on on Android 8 and below, but on Android P+, the http connection fails. Android Studio shows an exception.

java.net.UnknownServiceException: CLEARTEXT communication to example.com not permitted by network security policy
        at okhttp3.internal.connection.RealConnection.connect(RealConnection.kt:176)
        at okhttp3.internal.connection.ExchangeFinder.findConnection(ExchangeFinder.kt:249)
        at okhttp3.internal.connection.ExchangeFinder.findHealthyConnection(ExchangeFinder.kt:108)

There is also a mistake when I use HttpURLConnection .

D/NetworkSecurityConfig: No Network Security Config specified, using platform default
W/System.err: java.io.IOException: Cleartext HTTP traffic to example.com not permitted
W/System.err:     at com.android.okhttp.HttpHandler$CleartextURLFilter.checkURLPermitted(HttpHandler.java:115)
W/System.err:     at com.android.okhttp.internal.huc.HttpURLConnectionImpl.execute(HttpURLConnectionImpl.java:458)
W/System.err:     at com.android.okhttp.internal.huc.HttpURLConnectionImpl.getResponse(HttpURLConnectionImpl.java:407)
W/System.err:     at com.android.okhttp.internal.huc.HttpURLConnectionImpl.getResponseCode(HttpURLConnectionImpl.java:538)

Solution

There are 3 ways to solve this issue.

1. Use HTTPS instead of HTTP

Starting with Android 9 (API level 28), cleartext support is disabled by default. The cause of the problem is the protocol so we can just switch connection’s protocol to https. Using encrypted transfer protocol is recommended.

2. Add android:usesCleartextTraffic

As the document usesCleartextTraffic says, apps that target API level 28 or higher default to "false" . So we can add android:usesCleartextTraffic="true" to application tag in AndroidManifest.xml . This is the most simple way.

<?xml version="1.0" encoding="utf-8"?>
<manifest ...>
    <uses-permission android:name="android.permission.INTERNET" />
    <application
        ...
        android:usesCleartextTraffic="true"
        ...>
    </application>
</manifest>

3. Set network-security-config

Refer to network-security-config.

  • Create res/xml/network_security_config.xml file. 
<?xml version="1.0" encoding="utf-8"?>
<network-security-config>
    <domain-config cleartextTrafficPermitted="true">
        <!-- Matches the domain and all subdomains -->
        <domain includeSubdomains="true">example.com</domain>
        <!-- Only match api.dev.com -->
        <domain includeSubdomains="false">api.dev.com</domain>
    </domain-config>
</network-security-config>
  • Add android:networkSecurityConfig

Add android:networkSecurityConfig to application tag in AndroidManifest.xml .

<?xml version="1.0" encoding="utf-8"?>
<manifest ...>
    <uses-permission android:name="android.permission.INTERNET" />
    <application
        ...
        android:networkSecurityConfig="@xml/network_security_config"
        ...>
    </application>
</manifest>
Updated Apr 26, 2020