酢ろぐ!

カレーが嫌いなスマートフォンアプリプログラマのブログ。

Android エミュレータでCharlesを使いたい (Android 6.0 / Android 7.0 以降の両対応)

アプリからAPIを正しく実行できているのかどうかを検証するため「Charles(チャールズ)」を導入しました。

www.charlesproxy.com

Charlesはデスクトップで動くプロキシツールで、リクエストを書き換えてサーバーに送ったり、ステータスコードが400で返ってきたレスポンスを200に変えて適当なJSON Textを差し込んだりと、UIが初見者にとって使いにくい反面慣れると便利に使えます。

試用期間中は30分以内であればフル機能が使えるので十分だと思っていましたが、デバッグをしていると30分は一瞬で過ぎてしまいCharlesが毎回終了してしまいました。1日に何度もCharlesを起動していると次第にイライラしてきてしまい、作業が捗らなくなってしまったのでCharlesのライセンスを購入しました。

本エントリで紹介すること

さくさんはAndroidアプリのminSdkVersionはジャンジャン上げていけば良いと考えている派閥の人間です。

しかし、お仕事の内容やAmazon App Store*1に対応したい場合にはAPIレベル 23(Android 6.0)以上の縛りでサポートする必要があるかもしれません。

本エントリでは Android 6.0 と Android 7.0以降の両方のAndroidエミュレータでCharlesを使う方法を紹介します。

Charlesを使う前にやっておくこと

Charlesはプロキシサーバーです。Androidエミュレータから接続したい場合にはプロキシの接続先について調べておかないといけません。CharlesでIPアドレスとポートを調べます。

CharlesのIPアドレスを調べる

接続先を知っておく必要があります。ローカルPCのIPアドレスを調べます。

ツールバーの[Help] -> [Local IP Address]を選択します。

f:id:ch3cooh393:20210715103813p:plain

このローカルPCのアドレスは 192.168.68.109 であることがわかりました。

f:id:ch3cooh393:20210715103828p:plain

ちなみに192.168.68.109の部分を選択して Command + C でIPアドレスをコピーできます。便利。

Charlesのポートを調べる

接続ポートを知っておく必要があります。Charlesのポートを調べます。

ツールバーの[Proxy] -> [Proxy Settings...]を選択します。

f:id:ch3cooh393:20210715104033p:plain

Proxy Settingsダイアログの[Proxies]タブを開きます。HTTP Proxyのポートが 8888 であることがわかりました。

f:id:ch3cooh393:20210715104226p:plain

以上の調査で「192.168.68.109」の「8888」に接続すれば良いことがわかりました。

SSL通信のプロキシ対象を追加する

CharlesではSSL通信のリクエストとレスポンスの生テキストが表示できます。指定したアドレス(ロケーション)にマッチした通信だけがプロキシされます。プロキシ対象に追加していない場合、下図のように通信内容を読むことはできません。

f:id:ch3cooh393:20210715105837p:plain

ツールバーの[Proxy] -> [SSL Proxying Settings...]を選択する。

f:id:ch3cooh393:20210715111033p:plain

「SSL Proxying Settings」ダイアログの[SSL Proxying]タブを選択して、[Enable SSL Proxying]にチェックをつける。その後、Include リストの[Add]ボタンをクリックして、以下の内容のロケーションを追加する。

  • Host: *
  • Port: *

f:id:ch3cooh393:20210715111621p:plain

Android側のセキュリティ設定

Android N (Android 7.0 / API 24)以降、ネットワークセキュリティがより厳しくなりました。「Android N 以降で Google Mobile Ads SDK 用に Charles プロキシを設定する」を参考にして、デバッグ時のみセキュリティレベルを下げるようにします。

AndroidManifest.xml を追加する

FourCropper/app/src/debug/AndroidManifest.xml にファイルを追加する。

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    package="jp.ch3cooh.fourcropper">

    <application
        android:networkSecurityConfig="@xml/network_security_config"
        tools:targetApi="n" />

</manifest>

network_security_config.xml を追加する

FourCropper/app/src/debug/res/xml/network_security_config.xml にファイルを追加する。

<?xml version="1.0" encoding="utf-8"?>
<network-security-config>
    <debug-overrides>
        <trust-anchors>
            <!-- Trust user added CAs while debuggable only -->
            <certificates src="user" />
        </trust-anchors>
    </debug-overrides>
</network-security-config>

Android 6.0 のエミュレータでCharlesを使いたい

Pixel 2 API 23 のAVD*2を新規に作成して動かしてみましょう。Charlesも起動しておきます。

Androidエミュレータの設定ダイアログを開き、[Settings]ページの[Proxy]タブを開きます。[Manual proxy configuration]に先ほど調べたCharlesのホスト名とポート番号を入力します。

f:id:ch3cooh393:20210715105348p:plain

ブラウザで http://charlesproxy.com/getssl にアクセスすると証明書をダウンロードされます。証明書がダウンロードできない場合はここまでの設定になんらかの問題があることが考えられます。

証明書の名前(Certificate name)は適当に「Charles」としておきます。

以上で、SSL通信のリクエストとレスポンスを取得することができると思います。

Android 7.0以降のエミュレータでCharlesを使いたい

大抵のアプリの場合はAPIからデータを取得してDB内のマスタデータを更新します。Android StudioでDatabase Inspectorを使えるのはAPI26以上です。

ここでは Pixel 2 API 30 のAVDを新規に作成して動かしてみましょう。Charlesも起動しておきます。

f:id:ch3cooh393:20210715144223p:plain

ブラウザで http://charlesproxy.com/getssl にアクセスすると証明書をダウンロードされます。証明書がダウンロードできない場合はここまでの設定になんらかの問題があることが考えられます。

Install CA certificates in Settings
This certificate from null must be installed in Settings. Only install CA certificates from organizations you trust.

Android 6.0ではダウンロードしたらそのまま証明書をインストールできていましたが、API 30 (Android 10)ではダウンロードまでしかできません。下図のようなメッセージダイアログが表示されます。

証明書を自分でインストールする必要があります。OSの設定アプリを開き[Security] -> [Encryption & credentials] -> [Install a certificate] -> [CA certificate] の順にタップします。さきほどダウンロードした証明書を選択してインストールします。

以上で、SSL通信のリクエストとレスポンスを取得することができると思います。

*1:Windows 11 と統合されるので今後は対応が必須になることが想定される

*2:Android Virtual Device / Android仮想デバイス