Fetch does not work on Android 9 with SDK 28

This simple fetch always worked fine on my published app (SDK 26), since I rebuilt the app using SDK 28 (32bit). Since then it does not work on devices with Android 9 and it reports “connection error”. On other versions of Android (6, 7, 8) it works perfectly.
Unfortunately I don’t have a Android 9 device to do any test.

I’m getting a lot of 1 star reviews because of this issue…

fetch(http://www.mindteq.com/api/cityfun/v2/api.php?category=home&debug)
    .then(function(response) {
        if (response.ok) {
            return response.json(); 
        } else {    
            throw Error(response.status);
        }
    })
    .then(function(json) {
        
        datas.replaceAll(json.settings);

        // Debug
        //datas.forEach(function(items) {
        //    console.log(items);
        //});

    }).catch(function(error) {
        console.log(error);
    });

Could be that Android starting from SDK 28 wants HTTPS and not HTTP?

Hmm, I also don’t have an Android 9 Device at the mo but you could try a simulator?

Then you could try testing SSL by fetching here: https://jsonplaceholder.typicode.com: https://jsonplaceholder.typicode.com/todos/1

Oh wait, my one device can get a Pie update, will upgrade and let y’all know asap…

I’m getting the same issue! The fetch on Android is broken! The XMLHttpRequest also with errors

I change the url to HTTPS and problem solved

1 Like

Yep, its the SSL(https) connections in Pie, it looks like you can specify non-secure domains for “clear text traffic” through adding Network Security Config to your manifest:

<network-security-config>
    <domain-config cleartextTrafficPermitted="true">
        <domain includeSubdomains="true">insecure.example.com</domain>
        <domain includeSubdomains="true">insecure.cdn.example.com</domain>
    </domain-config>
</network-security-config>

Manifest Ref: Add values to AndroidManifest?

Great! Thanks for the info!

Yes, I may confirm that now Google wants HTTPS connections. I purchased and installed a SSL certificate for my VPS, published a updated version of the app and now it works. Unfortunately in three days I got more negative reviews regarding this “network error” than all the other positive reviews.

To add cleartextTrafficPermitted to Android Manifest I created a file named domain.uno with the following content

using Uno.Compiler.ExportTargetInterop;
 
[Require("AndroidManifest.RootElement", "<network-security-config>")]
[Require("AndroidManifest.RootElement", "   <domain-config cleartextTrafficPermitted=\"true\">")]
[Require("AndroidManifest.RootElement", "       <domain includeSubdomains=\"true\">triestenascosta.it</domain>")]
[Require("AndroidManifest.RootElement", "   </domain-config>")]
[Require("AndroidManifest.RootElement", "</network-security-config>")]

but when I compile I get the error

dominio.uno(7.71): E0000: Expected type or block following ']' -- found <EOF> (unexpected end-of-file)

@Enrico I solve the issue adding a uxl with:

	<Require Condition="Android" Gradle.BuildFile.End>
	    <![CDATA[
	      // define the task
	      task updateManifest(type: UpdateManifestTask)

	      // implement the task
	      class UpdateManifestTask extends DefaultTask {
	        @TaskAction
	        def update() {

	          // find the manifest and get the contents
	          // TODO: use gradle to find manifest path based on variant/flavor
	          def manifestPath = "app/src/main/AndroidManifest.xml"
	          def manifestFile = new File(manifestPath)
	          def content = manifestFile.getText()

	          // update content, in our case, find and replace some string
	          def updatedContent = content.replaceAll("<application ", "<application android:networkSecurityConfig=\"@xml/network_security_config\" ")
	          manifestFile.write(updatedContent)
	        }
	      }

	      // make processDebugManifest task depend on our new task to ensure the manifest is updated when it's needed
	      afterEvaluate {
	        processDebugManifest.dependsOn updateManifest
	      }
	    ]]>
	  </Require>
</Extensions>

To add android:networkSecurityConfig="@xml/network_security_config" to the manifest.
And a network_security_config.xml file (you can edit this file as your demand):

<?xml version="1.0" encoding="utf-8"?>
<network-security-config>
    <base-config cleartextTrafficPermitted="true">
        <trust-anchors>
            <certificates src="system" />
        </trust-anchors>
    </base-config>
</network-security-config>

Thank you Cristian.
Do you mean that I have to create a empty .UXL file and simply add the above <Require> condition and then create a .XML in the same folder of the .UXL file?

No, the uxl must contain this to add android:networkSecurityConfig="@xml/network_security_config" to the manifest:

and create the .xml file with the config in the same folder as the uxl file