アプリからAPIを正しく実行できているのかどうかを検証するため「Charles(チャールズ)」を導入しました。
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を使う前にやっておくこと
- Android側のセキュリティ設定
- Android 6.0 のエミュレータでCharlesを使いたい
- Android 7.0以降のエミュレータでCharlesを使いたい
Charlesを使う前にやっておくこと
Charlesはプロキシサーバーです。Androidエミュレータから接続したい場合にはプロキシの接続先について調べておかないといけません。CharlesでIPアドレスとポートを調べます。
CharlesのIPアドレスを調べる
接続先を知っておく必要があります。ローカルPCのIPアドレスを調べます。
ツールバーの[Help] -> [Local IP Address]を選択します。
このローカルPCのアドレスは 192.168.68.109 であることがわかりました。
ちなみに192.168.68.109の部分を選択して Command + C でIPアドレスをコピーできます。便利。
Charlesのポートを調べる
接続ポートを知っておく必要があります。Charlesのポートを調べます。
ツールバーの[Proxy] -> [Proxy Settings...]を選択します。
Proxy Settingsダイアログの[Proxies]タブを開きます。HTTP Proxyのポートが 8888 であることがわかりました。
以上の調査で「192.168.68.109」の「8888」に接続すれば良いことがわかりました。
SSL通信のプロキシ対象を追加する
CharlesではSSL通信のリクエストとレスポンスの生テキストが表示できます。指定したアドレス(ロケーション)にマッチした通信だけがプロキシされます。プロキシ対象に追加していない場合、下図のように通信内容を読むことはできません。
ツールバーの[Proxy] -> [SSL Proxying Settings...]を選択する。
「SSL Proxying Settings」ダイアログの[SSL Proxying]タブを選択して、[Enable SSL Proxying]にチェックをつける。その後、Include リストの[Add]ボタンをクリックして、以下の内容のロケーションを追加する。
- Host: *
- Port: *
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のホスト名とポート番号を入力します。
ブラウザで 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も起動しておきます。
ブラウザで 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通信のリクエストとレスポンスを取得することができると思います。