I’m writing an app using the Turbo Native library to wrap a website and run inside an app window for mobile. I’ve just had a day of fun trying to work out why I can use the remote staging service as the URL endpoint but not the localhost one.

To an old hand like me it seems obvious that there’s some kind of policy in place that bars the http connection to localhost. I did some digging and discovered the following steps.

Add the line

android:networkSecurityConfig="@xml/network_security_config"

to the application tag in AndroidManifest.xml and then also add the file to the res/xml directory and put this in it

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

This did not work, I tried all sorts of combinations of things and it still didn’t work.

I then started researching how to get my docker dev environment to run with https. It’s not hard to do this, but a little tricky. I noticed at the end of one of the comments about using Android emulator specifically, the poster said you need to set up a reverse proxy from the emulator to your local machine.

alias adb=~/Library/Android/sdk/platform-tools/adb
adb reverse tcp:3000 tcp:80

Note that the alias command is if you’re on a Mac. It’s unnecessary but it means I can find adb again if and when I need it from my shell command history. Google the adb reverse command if you want to know how to remove or create different proxies.

What this does is say port 3000 on the emulator gets proxied to port 80 on my local machine. I told the emulator to use port 3000 for the connection and all works now. If you were running Rails on port 3000 then you’d proxy 3000 to 3000. 80 to 80 won’t work, I think it’s reserved for something, which is probably the source of this trauma.

So, in summary, you need to enable http and you need to set up the reverse proxy. I don’t know enough about Android internals to know why you need the proxy but you do. If you’ve stumbled on the first part then you need to be aware of the second.

Note, also, that I didn’t just enable plain text everywhere like you can with a blanket allow plain text. Just for localhost. At least as far as my current knowledge of Android tells me, anyway.