---
title: "How to set up Charles Proxy for the Android Studio emulator"
url: "https://romankryvolapov.com/en/charles-proxy-android-emulator/"
description: "Step-by-step Charles Proxy setup for the Android emulator: proxy via adb, the Charles certificate, a network security config for your app's HTTPS, and rewriting responses."
language: en
published: 2023-03-14
updated: 2026-11-05
---
These steps were tested in early 2023 on Windows 10 with an API 33 emulator, Android Studio 2022.1.1 and Charles Proxy 4.6.3. I wrote them because I could not find up-to-date instructions: the familiar Proxy tab was gone from the settings of the emulator running inside Android Studio, and Charles had reworked its own setup a little. That tab would not help with HTTPS anyway: it sets the [emulator proxy](https://developer.android.com/studio/run/emulator-networking-proxy), which tunnels HTTPS without decrypting it, while Charles needs the Android system proxy, and that is what the steps below configure.

## Proxy

1. Start Charles Proxy.
2. Untick **Proxy → Windows Proxy** (on macOS, **macOS Proxy**) so that Charles does not intercept all of the computer's traffic.
3. Find the computer's local network address: **Help → Local IP Address**, or in the network settings.
4. In **Proxy → Proxy Settings…** make sure the port is 8888.
5. Find the Android SDK: in Android Studio settings, search for "sdk", open **Android SDK** and copy the path from **Android SDK Location**. The `adb` tool is in its `platform-tools` folder.
6. Turn the proxy on in the emulator:

```bash
C:\Users\<user name>\AppData\Local\Android\Sdk\platform-tools\adb.exe shell settings put global http_proxy <local IP>:8888
```

You can `cd` into `platform-tools` first and then call plain `adb`. Instead of the local IP you can give the emulator `10.0.2.2` — its fixed address for the computer it runs on, which does not change along with the network.

7. Charles will show a connection request — accept it.
8. The session tab will start showing requests, including the emulator's. To keep only the domain you need, right-click it and choose **Focus**.

To turn the proxy off when you no longer need it:

```bash
adb shell settings put global http_proxy :0
```

## The certificate and HTTPS

9. Open Chrome in the emulator, go to `http://chls.pro/ssl` and download the certificate.
10. In the emulator's settings, search for "certificate", open **Install certificate** (it sits under different menus in different versions) and install the downloaded certificate.
11. Under **Trusted credentials**, the **User** tab should now list the Charles Proxy certificate.
12. In Charles, select the address you need, right-click it and choose **Copy URL**, then go to **Proxy → SSL Proxying Settings… → Include → Add** and add the copied address; the port is optional. After clearing the history, requests to that address will show up as a tree of REST paths.

**Important: this way you will only see HTTPS from Chrome.** Since Android 7, apps do not trust user-installed certificates by default, so your own app's requests will stay unreadable. To make a debug build trust the Charles certificate, add `res/xml/network_security_config.xml` to the project:

```xml
<?xml version="1.0" encoding="utf-8"?>
<network-security-config>
    <debug-overrides>
        <trust-anchors>
            <certificates src="user" />
        </trust-anchors>
    </debug-overrides>
</network-security-config>
```

and reference it in the manifest:

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

The `debug-overrides` block applies only to debug builds, so this trust does not reach the release. If the app uses certificate pinning, that has to be switched off for debugging too.

## Rewriting requests and responses

There are three ways:

- **Tools → Rewrite…** — add the address, create a rule of type **Body**, tick **Response** and put the reply you want into **Value**.
- **Proxy → Breakpoints** — the request or response pauses, and you can edit it by hand while it is in flight.
- **Tools → Map Local** — a local file is served instead of the server's response.

One last thing: if the router gives the computer a dynamic IP address, it may be different the next time you connect, and the emulator's proxy will need to be set again. The `10.0.2.2` address does not have this problem.
