What? Android P blocks HTTP without S? Who cares, I use only HTTPS anyway, because I am secure. Yep, I thought the same, until I got this exception myself. Because testing.

Surely there is a possibility that you might not see it ever. But it’s probably just a matter of time.

You are probably communicating with outside world via internet. And for testing, you want to mock your server. Some people prefer to have external mock or some kind of dev environment (which doesn’t hurt of course!) but for stability of your tests and bigger independence you might try to start web server on the device.

Two big players are MockWebServer and Wiremock. Both are pretty easy to use.

But by default they start at http://localhost. Which is understandable - https requires official valid certificate, trusting every certificate (which is usually a bad idea!) or certificate pining. It complicates stuff, so by default it’s not switched on.

Therefore, when running “integration” tests on your Android P device you will sooner or later see

UnknownServiceException: CLEARTEXT communication to localhost
not permitted by network security policy

Since Android P http is blocked by default, what are the possibilities?

Of course you could play with keystore and configure it correctly. Especially if you have common module for testing, this is very viable option. However, there are alternatives:

1. Explicitly saying that you accept clear text for some host.

It’s actually really simple.

  • Create res/xml/network_security_config.xml with content:
<?xml version="1.0" encoding="utf-8"?>
<network-security-config>
    <domain-config cleartextTrafficPermitted="true">
        <domain includeSubdomains="true">localhost</domain>
    </domain-config>
</network-security-config>

Of course for testing purposes you can specify any domain you want.

  • Point to this file from your manifest (for bonus points add it only for the test manifest):
<application
        android:networkSecurityConfig="@xml/network_security_config"
        android:label="@string/app_name"
        android:theme="@style/AppTheme">
        <activity android:name=" (...)
    </application>

That’s it.

2. Accept certificates from given Certificate Authority

Fortunately, our dear Android team at Google thought about that situation, so they made available small workaround. You don’t have to use official authorized certificate for testing, you can create any cert and made its certificate authority trusted with <trust-anchors>.

What’s really cool you can easily make sure that trusting non-official CA will not slip to production by mistake. All you need to do is to nest <trust-anchors> within <debug-overrides>. It ensures that this configuration is active only when your build debuggable property is set to true, which is (hopefully) not the case for your release build.

So your network_security_config.xml might look like this (example shamelessly taken from Android Developers):

<?xml version="1.0" encoding="utf-8"?>
<network-security-config>
    <debug-overrides>
        <trust-anchors>
            <certificates src="@raw/debug_cas"/>
        </trust-anchors>
    </debug-overrides>
</network-security-config>

There you have it - two simple ways to make your life easier after update to Android P and its limitation regarding “CLEARTEXT communication not permitted”. As always, you decide which one suits you better.