Sunday 16 December 2018

Http and Https request from Android Pie onwards

Recently I faced a weird situation where my app was working fine in all Android versions except Android Pie.

java.io.IOException: Cleartext HTTP traffic to * not permitted

After lots of debugging I came to know it was because my server was not secure ie it was using HTTP (not HTTPS). Android P uses HTTPS by default. What this means is that if you are using unencrypted HTTP requests in your app, the app will work fine in all versions of Android except Android P.

Let’s consider two situations where your app won’t work properly in Android P. 

1. If your server is on HTTP obviously it won’t work in Android P. 

2. When your server is on HTTPS but it is returning something like an image URL which is HTTP, you won’t be able to load the image in Android P.

From Android 9 Pie now, requests without encryption will never work. The System will expect you to use TLS by default.

The easy way to implement this is to use this attribute to your AndroidManifest.xml where you allow all http for all the requests.

android:usesCleartextTraffic=”true”

We have to add these lines to the application tag like below.

<application android:usesCleartextTraffic="true" />

Cleartext is any transmitted or stored information that is not encrypted or meant to be encrypted.

When an app communicates with servers using a cleartext network traffic, such as HTTP, it could raise a risk of eavesdropping and tampering of content. Third parties can inject unauthorized data or leak information about the users. That is why developers are encouraged to a secure traffic only, such as HTTPS.  Hence the cleartext is inevitable, but we can fix the error at the application end

Going with general fix is not the good solution, We have to fix it on our backend by making the request to support for https, but there is some exceptional cases i.e. If we are allowing http for some domains but not other domains, then we have to do some configurations to make this to work.

We have to create a new file inside our XML folder network_security_config.xml now paste the below code snippet inside the file.

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

You can add the domain of your choice in place of abc.com / pqr.com

To make this work, we have to define a networkSecurityConfig in the application of our Manifest file tag like this:

<application android:networkSecurityConfig="@xml/network_security_config" />

Thatz It... Happy Coding :-)