1

I have an application that works fine on below Android9 phones. Recently I start testing my application on android 9 and facing a strange problem that simple https/http post-call is not working and library(com.loopj.android) giving an exception that fails to connect. I know that there is a change related to network and I tried all the things which I find on the internet but still no luck. Here is my configuration:

Manifest.xml:

  <uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED"/>
        <uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE"/>
        <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
        <uses-permission android:name="android.permission.INTERNET"/>
        <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE"/>

  <application
         tools:targetApi="28"
         android:networkSecurityConfig="@xml/network_security_config"
         android:usesCleartextTraffic="true">
  </application>

network_security_config.xml in res/xml:

<?xml version="1.0" encoding="utf-8"?>
<network-security-config>
    <domain-config cleartextTrafficPermitted="true">
        <domain includeSubdomains="true">my-backend.hostname.dk</domain>
        <trust-anchors>
            <certificates src="system" />
            <certificates src="user" />
        </trust-anchors>
    </domain-config>
</network-security-config>

I am signing the app with proper Keystore: build.gradle:

signingConfigs {
        release {
            storeFile file("../myApp-release.keystore")
            storePassword "abcd1234"
            keyAlias "myApp-release"
            keyPassword "abcd1234"
        }
    }

Also tried to use proper SSLFactory for httpclient:

AsyncHttpClient client = new AsyncHttpClient();
    try {
            KeyStore trustStore = MySSLSocketFactory.getKeystore();
            MySSLSocketFactory sf = new MySSLSocketFactory(trustStore);
            sf.setHostnameVerifier(MySSLSocketFactory.ALLOW_ALL_HOSTNAME_VERIFIER);
           // MyCustomSSLFactory socketFactory = new MyCustomSSLFactory(trustStore);

            client.setSSLSocketFactory(sf);
            client.setTimeout(600000);
            client.setConnectTimeout(10000);
        } catch (Exception e) {

        }

Also tried to use SSL mentioned in this post but nothing is working for me and still getting an exception whenever my program try to call backend REST API. exception:

07-12 13:49:08.435 5111-5129/com.myapp.cherinstall W/System.err: java.net.SocketTimeoutException: failed to connect to my-backend.hostname.dk/192.168.4.24 (port 8182) from /192.168.3.246 (port 48880) after 10000ms

I have rooted the phone and running this code in an App that has no activity but the only intent service. I did some tests and figure out that if I run my HTTP request through activity(Create new Activity within the same Application for testing purpose) only once, then sending intent to this InteneService also start works but without invoking any Activity when application installed and sending IntentService call is failing. I know that there are more restrictions Google added in Android 9 and I don't know which one I am missing now. Can someone please give me a clue.

Kaushal Panchal
  • 1,785
  • 1
  • 11
  • 27
user565
  • 871
  • 1
  • 22
  • 47

3 Answers3

5

You have to add an attribute of android:usesCleartextTraffic="true" on application tag in AndroidManifes.xml file.

And also add this.

<uses-library
    android:name="org.apache.http.legacy"
    android:required="false" />

Set

android:usesCleartextTraffic="true"

in manifest file like below.

<application
        android:allowBackup="true"
        android:hardwareAccelerated="true"
        android:icon="@mipmap/ic_launcher"
        android:label="@string/app_name"
        android:theme="@style/AppTheme"
        android:usesCleartextTraffic="true"
        tools:targetApi="m">

Check this official blog on why this happens and we have to add in the manifest file.

Kaushal Panchal
  • 1,785
  • 1
  • 11
  • 27
0

Have you tried to run the app on or above API 26(I know on API 28 you tested) But as per the official android document,

Android 8.0 places limitations on what apps can do while users aren't directly interacting with them. Apps are restricted in two ways:

Background Service Limitations: While an app is idle, there are limits to its use of background services. This does not apply to foreground services, which are more noticeable to the user.

Broadcast Limitations: With limited exceptions, apps cannot use their manifest to register for implicit broadcasts. They can still register for these broadcasts at runtime, and they can use the manifest to register for explicit broadcasts targeted specifically at their app.

Note: By default, these restrictions only apply to apps that target Android 8.0 (API level 26) or higher. However, users can enable most of these restrictions for any app from the Settings screen, even if the app targets an API level lower than 26.

May Be this will solve your problem as per documentation

In most cases, apps can work around these limitations by using JobScheduler jobs. This approach lets an app arrange to perform work when the app isn't actively running but still gives the system the leeway to schedule these jobs in a way that doesn't affect the user experience. Android 8.0 offers several improvements to JobScheduler that make it easier to replace services and broadcast receivers with scheduled jobs; for more information, see JobScheduler improvements.

niks
  • 173
  • 10
  • Well as I mentioned that my application is working fine on all other phones which are below android 9 version. There is a some sort of restriction which i am facing on android9. I will give a try to use JobScheduler. Is there any other way to i can remove these restriction through shell command ? – user565 Jul 12 '19 at 14:22
  • Sorry, don't know about removing restrictions through shell command. – niks Jul 12 '19 at 14:24
  • I also tried to use this StrictMode but it can't help. if (android.os.Build.VERSION.SDK_INT > 9) { StrictMode.ThreadPolicy policy = new StrictMode.ThreadPolicy.Builder().permitAll().build(); StrictMode.setThreadPolicy(policy); } – user565 Jul 12 '19 at 14:24
  • @user565 Never do that with strict mode. But that isn't your problem, if you had a threading violation you'd get a NetworkOnMainThreadException instead. – Gabe Sechan Jul 15 '19 at 14:39
  • Well actually I figured out this, It was due to restriction of Network call from background running App as in the latest version of android is not allowed to do this unless user interaction. I did a trick(Not best way to resolve this kind of issue) by sending rest call by hidden activity only once when the app start and then everything works fine. – user565 Jul 17 '19 at 07:38
0

Adding: android:usesCleartextTraffic="true" in main androidManifest.xml worked for me, like below:

<application
  android:name=".MainApplication"
  android:label="@string/app_name"
  android:icon="@mipmap/ic_launcher"
  android:roundIcon="@mipmap/ic_launcher_round"
  android:allowBackup="false"
  android:theme="@style/AppTheme"
  android:usesCleartextTraffic="true"
  >
  <activity {....}
Taslim Oseni
  • 6,086
  • 10
  • 44
  • 69
Braven
  • 484
  • 1
  • 6
  • 27