Fix Android 9+ Error: Cleartext HTTP traffic not permitted
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>