How to fix "Cleartext HTTP ... not permitted" for Android development

I met Cleartext HTTP traffic to www.soundhelix.com not permitted error when i tried to stream mp3 files with the Exoplayer library.

2019-10-06 18:22:28.363 8724-9511/com.codechacha.exoplayer E/ExoPlayerImplInternal: Source error.
    com.google.android.exoplayer2.upstream.HttpDataSource$HttpDataSourceException: Unable to connect to http://www.soundhelix.com/examples/mp3/SoundHelix-Song-1.mp3
        at com.google.android.exoplayer2.upstream.DefaultHttpDataSource.open(DefaultHttpDataSource.java:282)
        .....
     Caused by: java.io.IOException: Cleartext HTTP traffic to www.soundhelix.com not permitted
        at com.android.okhttp.HttpHandler$CleartextURLFilter.checkURLPermitted(HttpHandler.java:124)
        at com.android.okhttp.internal.huc.HttpURLConnectionImpl.execute(HttpURLConnectionImpl.java:462)
        ....

The cause of the problem is that Android doesn't allow HTTP access by default. Accessing HTTPS is no problem, but if the site doesn't support HTTPS, or if you need to access HTTPS, you should handle this.

According to Opt out of cleartext traffic in Android Developer, Starting with Android 9 (API level 28), cleartext support is disabled by default.

So, you have to configure about cleartext HTTP to get access to HTTP sites with API level 28 or above.

Allow all connections to HTTP URLs

You can allow all connections to HTTP URLs if you set the usesCleartextTraffic property to true in AndroidManifest.xml

<application
        android:label="@string/app_name"
        ...
        android:usesCleartextTraffic="true">

Allow connections to specific sites.

If you want to allow connections to specific sites. then make a /res/xml/network_security_config.xml file and add some sites.

if you add a domain-config like below, you can allow connections to secure.example.com.

<?xml version="1.0" encoding="utf-8"?>
<network-security-config>
    <domain-config cleartextTrafficPermitted="false">
        <domain includeSubdomains="true">secure.example.com</domain>
    </domain-config>
</network-security-config>

Also, you have to let the system know where the config file is. Add following code to your AndroidManifest.xml.

<application
    android:label="@string/app_name"
    ...
    android:networkSecurityConfig="@xml/network_security_config"

References

codechachaCopyright ©2019 codechacha