The Android Emulator and Charles Proxy: A Love Story

Android Emulators have come a long way over the years. Once they were the bane of every developer’s life, representing the most basic failure of the Android development environment; a painfully slow tool that had the maddeningly unrealized potential to make developer lives infinitely easier. But over the last couple years, Google has wised-up and made the emulator one of the best things about developing for Android — a fast, fluid, and endlessly useful tool for exercising and debugging apps.

The Android Emulator can also be made into a super-tool for testing API edge and failure cases by employing an http proxy — a go between that can intercept, display and even re-map your API calls. My personal choice for this job is Charles Proxy. It has slick interface, easy to use mapping options and great support, with new releases being published all the time. Today I’ll show you how to set up your Emulator to proxy calls, and later, what you can do with it.

Setup

Get Charles

The first thing you want to do is download and run Charles Proxy. Start it up and you’ll see all the network traffic from your machine start to show up in the side bar. Charles, by default, has local proxying turned on, but since we’re going to use it to proxy an emulator, you can go to the Proxy menu and uncheck the OS proxy option:

Then click the little yellow broom icon to clear out all the traffic. You can also modify Charles’ preferences so that this option is not enabled by default.

Setup your Emulator to Proxy

Next, start up your emulator. Any old emulator will do, but depending on the Android version, your emulator’s settings might be different then mine. For this tutorial, I’m using a Pixel XL emulator running running Android 8.0, Oreo. The first thing we need to do is set up the emulator’s proxy settings, so that all the network traffic goes through Charles. To do that, we need your machine’s IP address. Charles actually has a little utility in the Help menu for this:

Click that, and then copy the IP address from the dialog that comes up.

Next, in your emulator, in the Setting bar, click the three little dots:

And then in the resulting dialog, click Settings, and then select the Proxy tab.

Paste in your IP address, and set the port to 8888. Charles will now prompt you that a device is trying to connect to the proxy, and ask you to allow it. Just click allow and you’ll start seeing IP addresses show up in the side bar

Don’t worry, we’re going to make that a whole lot prettier.

Install the Charles SSL Cert

Charles does some specific SSL magic, which we won’t go over here, but the bottom line it that you need to install the Charles SSL Certificate on your emulator. To do that, just open up a browser on the emulator, and navigate to http://chls.pro/ssl. The browser may prompt you to allow it to save the cert to disk, and then you can click to install it.

To Proxy your application on Android N or above, you also need to install a config file in your app’s resources. From the Charles Website:

“Android

As of Android N, you need to add configuration to your app in order to have it trust the SSL certificates generated by Charles SSL Proxying. This means that you can only use SSL Proxying with apps that you control.

In order to configure your app to trust Charles, you need to add a Network Security Configuration File to your app. This file can override the system default, enabling your app to trust user installed CA certificates (e.g. the Charles Root Certificate). You can specify that this only applies in debug builds of your application, so that production builds use the default trust profile.

Add a file res/xml/network_security_config.xml to your app:

<network-security-config> 
<debug-overrides>
<trust-anchors>
<!-- Trust user added CAs while debuggable only -->
<certificates src="user" />
</trust-anchors>
</debug-overrides>
</network-security-config>

Then add a reference to this file in your app’s manifest, as follows:

<?xml version="1.0" encoding="utf-8"?>
<manifest ... >
<applicationandroid:networkSecurityConfig="@xml/network_security_config" ... >
...
</application>
</manifest>

Phew. Your setup is now complete. Almost.

Urls instead of IP Addresses

Remember how we said we were gonna make Charles look all pretty? This is how we do it. In the setup, you probably noticed that all we get in the sidebar are IP addresses. But we can do better. To see the actual URLs those IPs represent, we can tweak our emulators settings to play nice with Charles.

To do this, go to your Emulator’s device settings, then go to (on Android 8.0, anyway) Network & Internet → Mobile network → Access Point Names. There should only be one, click on it. Now you should see this:

Now you can edit the Proxy and Port settings to match what we entered earlier in the Emulator’s settings. When you’re done that, don’t forget to click the three dots in the toolbar and Save your changes. Now, take a look at Charles again. If you’ve set up your app to trust the Charles cert, you should start to see some api urls in there.

Wow, that was a ton of work. But now it’s done, and you never have to do it ever again (unless your machines IP address changes, womp). In the next article, we’ll discover all the magical things you can do with Charles, including mapping responses to remote and local resources.