AppForceps に Android のアプリデータ編集を追加した
はじめに
macOS アプリ AppForceps に Android のアプリデータを編集する機能を追加しました。 この記事では AppForceps が Android のデータディレクトリをどう取得し、どう書き戻しているかを整理します。
内部ストレージと run-as
Android では、アプリのデータは内部ストレージ (Android 公式には app-specific storage と呼ばれる領域、実体は /data/data/<package>/) に置かれます。
実機・エミュレータを問わず Mac 側からこのディレクトリに直接アクセスすることはできません。
取得には adb が必要です。
adb には root 権限でシェルを起動する adb root というコマンドがあります。
これが使えれば /data/data/ 配下を直接読み書きできますが、実機では動きません。
そこで使うのが run-as です。
adb -s <serial> shell run-as <package> <command>
run-as は、指定したパッケージが android:debuggable="true" になっている場合に限り、そのパッケージの権限でコマンドを実行できるようにする仕組みです。
Android Studio でビルドした debug ビルドは基本的にこのフラグが立つので、実機でもエミュレータでも同じ経路でデータディレクトリにアクセスできます。
AppForceps はパッケージ一覧を取得する際に、あらかじめ run-as <package> true を実行してみて、成功したものだけを編集可能なアプリとして表示します。
ダウンロードとアップロードの流れ
AppForceps の Android 対応は、ダウンロードしてローカルで編集し、アップロードで書き戻す設計です。
ダウンロードでは、デバイス上に実在するディレクトリを動的に列挙してからまとめて取得し、ローカルに展開します。
アップロードは、ローカルの各ディレクトリを丸ごとデバイスに送り、ディレクトリ単位でアトミックに差し替える設計です。 途中で失敗しても本番のディレクトリには触れません。 ディレクトリごと置き換わるので、ローカルで削除したファイルも自然にリモートから消えます。
実際に開くと、次のように databases 配下の SQLite ファイルがテーブルエディタで見えます。
このアプリは Room でデータを持つ Todo アプリで todos テーブルのセルを編集すると、右側のエミュレータ画面にもその内容が反映されます。

databases 以外の files 配下も同様に開けます。
たとえば Firebase Remote Config のキャッシュファイルのような、テーブル形式を持たない生の JSON も編集できます。
test_abtest と test_variant の値を書き換えてアップロードすると、エミュレータ側の Remote Config 画面にもその変更が反映されます。


デバイス列挙とエミュレータの起動
adb devices -l の出力を解析して、実機とエミュレータを区別しています。
停止中の AVD も一覧に表示していて、そこから起動できます。
まとめ
Android のアプリデータをいじる機会があれば、よければ使ってみてください。