mcpField
I
installing-and-managing-apps

installing-and-managing-apps

github.com/skydoves開発33975 回インストール22 週間前に更新
リポジトリ

installing-and-managing-apps について

adb と pm で Android の APK、パッケージ、アプリ状態を管理するスキルガイドです。テストや Android CI を扱う開発者向けに、pm clear による状態分離、インストール設定、権限管理、失敗原因の調査を説明します。

主な機能

  1. 01APK のインストールと更新
  2. 02pm clear によるアプリデータのリセット
  3. 03インストール済みパッケージの確認
  4. 04ランタイム権限の付与と取り消し
  5. 05アプリの有効化、無効化、削除
  6. 06インストール失敗の原因調査

活用シーン

  1. 01繰り返しテスト前のアプリデータ消去
  2. 02テスト APK や分割 APK のインストール
  3. 03テスト用ランタイム権限の設定
  4. 04バージョンダウンや署名エラーの調査

インストール

コマンドをコピーしてターミナルで実行します。

$npx skills add https://github.com/skydoves/android-testing-skills --skill installing-and-managing-apps

インストール後、Claude Code で/installing-and-managing-appsを入力して読み込まれたか確認します。

詳細

アプリのインストールと管理 — adb install と pm

ホストからアプリのライフサイクルを管理します。adb install は APK を転送し、pm は端末上の PackageManager フロントエンドとして、アプリの一覧表示、パスの確認、データの消去、有効化/無効化、権限の付与を行います。テスト用の環境構築でよくある微妙なバグは、テスト間でアプリを「リセット」するために am force-stop を使ってしまうことです。このコマンドはプロセスを終了しますが、SharedPreferences、Room データベース、ディスク上のファイルは残ります。同等のクリーンな状態を確実に得るには pm clear を使います。

このスキルを使う場面

  • ホストから APK をインストールしたい、またはテストを実行するたびにデバッグビルドを転送したい場合。
  • 「テスト間でアプリの状態をリセットするにはどうすればよいですか?」と尋ねる場合や、テスト間で古いデータが引き継がれる場合。
  • INSTALL_FAILED_VERSION_DOWNGRADE、INSTALL_FAILED_USER_RESTRICTED、署名の不一致エラーが発生した場合。
  • インストール時にすべてのランタイム権限を付与(-g)したい場合、またはインストール後に特定の権限を付与/取り消ししたい場合。
  • サードパーティ製パッケージだけを一覧表示したい場合、ディスク上の APK を見つけたい場合、または Baseline Profile をダンプしたい場合。

このスキルを使わない場面

  • インストール済みアプリに対してインストゥルメンテーションテストを実際に実行したい場合は、../../tests/running-instrumented-tests-via-adb/SKILL.md を使ってください。
  • デバイスを選択したい場合、または起動を待ちたい場合は、../../devices/connecting-to-devices/SKILL.md を使ってください。
  • アーキテクチャ、環境、認証の全体像を把握したい場合は、../../architecture/understanding-adb-architecture/SKILL.md を使ってください。

前提条件

  • 状態が device の接続済みデバイス(../../devices/connecting-to-devices/SKILL.md を参照)。
  • 開発者が管理するデバッグキーまたはリリースキーで署名された APK。
  • テスト APK の場合、マニフェストに android:testOnly="true" が設定されていること(Gradle は androidTest ビルドでこの設定を行います)。インストールには -t が必要です。
  • ランタイム権限を使用する場合、デバイスが API 23 以降で動作していること。

ワークフロー

  • 1. 適切なフラグを指定してインストールします。 pm install(およびそのラッパーである adb install)のオプション表:

    フラグ意味
    -r「既存のアプリを再インストールし、データは保持します。」パッケージがすでにインストールされている場合は必須です。指定しないと adb install は INSTALL_FAILED_ALREADY_EXISTS を返します。CI スクリプトでは、繰り返し実行する際に必ず -r を指定してください。
    -d「バージョンコードのダウングレードを許可します。」新しい APK の versionCode が低い場合に必要です。注:adb help によると、標準ビルドではデバッグ可能なパッケージに限られます。
    -t「テスト APK のインストールを許可します。」マニフェストに android:testOnly="true" が設定された APK(つまり、すべての Gradle androidTest ビルド)に必要です。
    -g「アプリのマニフェストに記載されたすべての権限を付与します。」クリーンな状態を確実にするテスト実行に最適です。
    -lアプリをフォワードロックします(旧式の DRM)。現在はほとんど必要ありません。
    -sSD カード/外部ストレージにインストールします(デバイスが対応している場合)。
    --user <id>特定のユーザープロファイルにインストールします。デフォルトはすべてのユーザーです。current はフォアグラウンドユーザーに解決されます。
    `--install-location 01
    -f内部システムメモリにインストールします。
    -i <installer_pkg>インストーラーパッケージ名を指定してインストールにタグを付けます。
    --fastdeploy差分のみのインストール(APK の変更部分のみ)。
    --incremental / --no-incrementalストリーミングインストールです。APK Signature Scheme v4 のサイドカーファイル .idsig が必要です。--wait を指定すると、APK 全体が利用可能になるまで待機します。

    よく使われる例:

    adb install -r app-debug.apk                       # 通常の再インストール
    adb install -r -d app-debug.apk                    # ダウングレードを許可
    adb install -r -t -g app-androidTest.apk           # すべての権限を付与してテスト APK をインストール
    adb install -r -d --user current app-debug.apk     # フォアグラウンドユーザーに強制的にインストール
    
  • 2. 分割 APK には adb install-multiple を使用します。 最新の App Bundle では、ベース APK と機能/構成ごとの分割 APK が生成されるため、1 つだけを adb install でインストールすると失敗します。

    adb install-multiple -r -t -g \
      base-master.apk base-arm64_v8a.apk base-xxhdpi.apk
    
  • 3. テスト間でアプリの状態をリセットするには pm clear を使用します。分離を確実にするために am force-stop を使用しないでください。

    • am force-stop <pkg>:「package に関連付けられたすべてのものを強制停止します。」プロセスのみを終了します。SharedPreferences、Room/SQLite データベース、/data/data/<pkg> 内のファイル、キャッシュは保持されます。
    • pm clear <pkg>:「パッケージに関連付けられたすべてのデータを削除します。」ユーザーデータとキャッシュを消去します。次回の起動時には、新規インストール直後の状態になります。 テスト間で真に分離するには(インストルメント化テストスイートのデフォルト)、pm clear を使用します。am force-stop は、状態を保持したままプロセスを終了することが明確な目的である場合(例:「強制終了後に再開」する経路のテスト)にのみ適しています。
    adb shell pm clear com.example.app
    

    多くのパイプラインでは、Test Orchestrator の clearPackageData インストルメンテーション引数を使ってこれを設定します。詳しくは ../../tests/running-instrumented-tests-via-adb/SKILL.md を参照してください。

  • 4. pm list packages と pm path でパッケージを一覧表示、検索、確認します。

    pm list packages [-f] [-d] [-e] [-s] [-3] [-i] [-u] [--user <id>] [<filter>]
    
    フラグ意味
    -f「関連付けられたファイルを表示します。」
    -d「無効なパッケージのみを表示するよう絞り込みます。」
    -e「有効なパッケージのみを表示するよう絞り込みます。」
    -s「システムパッケージのみを表示するよう絞り込みます。」
    -3「サードパーティ製パッケージのみを表示するよう絞り込みます。」
    -i「パッケージのインストーラーを表示します。」
    -u「アンインストール済みのパッケージも含めます。」
    --user <id>「照会するユーザー領域です。」

    使用例:

    adb shell pm list packages -3 | sort                   # すべてのサイドロードアプリ
    adb shell pm list packages -f com.example              # 一致するパッケージの APK パス
    adb shell pm path com.example.app                      # package:/data/app/.../base.apk
    adb shell dumpsys package com.example.app | head -200  # インストール/権限の詳細情報
    
  • 5. pm grant/pm revoke で実行時権限を管理します(API 23 以降)。

    「アプリに権限を付与します。Android 6.0(API レベル 23)以降を搭載したデバイスでは、アプリのマニフェストで宣言されている任意の権限を指定できます。」

    adb shell pm grant  com.example.app android.permission.CAMERA
    adb shell pm revoke com.example.app android.permission.CAMERA
    adb shell pm reset-permissions                         # すべてのアプリの権限をデフォルトにリセット
    

    インストール時に -g フラグを指定すると、マニフェストで宣言されているすべての実行時権限が一度に付与されます。分離を確実にしたテスト実行では、この方法を推奨します。

  • 6. パッケージまたは特定のコンポーネントを有効化/無効化します。

    adb shell pm disable com.example.app                       # パッケージ全体
    adb shell pm disable-user --user 0 com.example.app         # ユーザーごとの無効化(データは保持)
    adb shell pm enable  com.example.app
    adb shell pm enable  com.example.app/.MyTestActivity       # 特定のコンポーネント
    

    テストで既知のアクセシビリティサービス/IME の状態を強制したり、競合するアプリを無効にして A/B 比較を準備したりする際に便利です。

  • 7. 正しくアンインストールします。

    pm uninstall [-k] [--user <id>] [--versionCode <vc>] <package>
    
    • -k:「パッケージの削除後もデータディレクトリとキャッシュディレクトリを保持します。」ユーザーデータを既存のインストール状態に見立てる、クリーン状態からのアップグレードテストに便利です。
    • --user <id> ユーザーごとの削除です。
    • --versionCode <vc>:「アプリのバージョンコードが指定した値の場合にのみアンインストールします。」CI スクリプトで冪等なアンインストールを行えます。
    adb uninstall com.example.app                       # 同等のコマンド:pm uninstall <pkg>
    adb shell pm uninstall -k com.example.app           # データを保持してアンインストール
    adb shell pm uninstall --user 0 com.example.app     # メインユーザーからのみアンインストール
    
  • 8. 必要に応じてベースラインプロファイルをダンプします。

    「Android 7.0(API レベル 24)以降、Android Runtime(ART)はインストール済みアプリの実行プロファイルを収集します…… adb shell cmd package dump-profiles <package> を実行し、その後 adb pull /data/misc/profman/<package>.prof.txt を実行します。」 ドキュメントでは、「実行プロファイルのファイル名を取得できるのは、たとえばエミュレーターのように、ファイルシステムへの root アクセス権がある場合に限られます」と警告されています。root 権限のないユーザービルドでは、androidx.benchmark Macrobenchmark を使ってプログラムからプロファイルを抽出します。

  • 9. よくあるインストールエラーを診断します。

    エラー原因対処方法
    INSTALL_FAILED_VERSION_DOWNGRADE新しい APK の versionCode がインストール済みのものより小さいです。-d を追加します。
    INSTALL_FAILED_USER_RESTRICTEDマルチユーザーデバイスで、インストールユーザー(通常はセカンダリユーザーまたは仕事用プロファイル)がインストールをブロックしています。--user 0 または --user current を指定するか、ユーザーにプロファイルの「USB 経由のインストール」制限を無効にしてもらいます。
    INSTALL_FAILED_UPDATE_INCOMPATIBLE(署名の不一致)新しい APK が、インストール済みのものとは異なるキーで署名されています。先にアンインストールします(adb uninstall <pkg>)。同じキーで再署名します。
    INSTALL_FAILED_TEST_ONLYAPK に android:testOnly="true" が設定されていますが、-t が省略されています。-t を追加します(通常は app-androidTest.apk に使用します)。
    INSTALL_FAILED_INVALID_APK(分割 APK のみ)分割セットの APK を 1 つだけインストールしようとしました。adb install-multiple を使用します。
    INSTALL_FAILED_INSUFFICIENT_STORAGE空き容量がありません。adb shell df /data を実行し、不要なデータを削除します。
  • 10. シェルの適切な引用符の付け方(Platform Tools 23 以降のルール)。 adb のページからの引用:

    「Android Platform Tools 23 以降では、adb は ssh(1) コマンドと同じ方法で引数を処理します。…… adb shell setprop key 'two words' はエラーになります……コマンドを機能させるには、ssh(1) の場合と同じように、ローカルシェル用とリモートシェル用の 2 回、引用符で囲みます。たとえば、adb shell setprop key \"'two words'\" は、ローカルシェルが外側の引用符を処理し、デバイス側には内側の引用符がそのまま渡されるため、機能します。」 同じルールは、スペース、特殊文字、またはシェルのメタ文字を含む pm の引数にも適用されます。

パターン

パターン:誤った例と正しい例 — テスト間でアプリの状態をリセットする
# WRONG
adb shell am force-stop com.example.app
# Run next test...
# WRONG because: force-stop kills the process but leaves SharedPreferences,
# Room DB, files in /data/data/<pkg>, and cache. Tests that read any of those
# carry stale state into the next case. Flake follows.
# RIGHT
adb shell pm clear com.example.app
# Run next test against fresh-install state.

テスト実行では、ランナー自体が行う同等の処理は、AndroidX Test Orchestrator に対する -e clearPackageData true です。詳しくは ../../tests/running-instrumented-tests-via-adb/SKILL.md をご覧ください。

パターン:誤った例と正しい例 — androidTest APK をインストールする
# WRONG
adb install app-androidTest.apk
# adb: failed to install app-androidTest.apk: Failure [INSTALL_FAILED_TEST_ONLY:
#   installPackageLI]
# WRONG because: any APK with android:testOnly="true" (every Gradle-built test
# APK) requires `-t`.
# RIGHT
adb install -r -t -g app-androidTest.apk
# -r: reinstall keeping data (or overwriting); -t: allow test packages;
# -g:  grant all runtime permissions for hermetic tests.
パターン:誤った例と正しい例 — デバッグインストール後にバージョンをダウングレードする
# WRONG
adb install -r app-release.apk
# adb: failed to install app-release.apk: Failure [INSTALL_FAILED_VERSION_DOWNGRADE]
# WRONG because: the installed debug APK has a higher versionCode than the
# release APK being installed.
# RIGHT
adb install -r -d app-release.apk     # allow downgrade
# Or, when signature also changes:
adb uninstall com.example.app
adb install     app-release.apk
パターン:誤った例と正しい例 — サードパーティ製パッケージのみを一覧表示する
# WRONG
adb shell pm list packages | grep -v 'com.android'
# WRONG because: many third-party packages also have names containing
# "com.android" (e.g. third-party Android library demos), and Google's own
# pre-installed apps carry varied prefixes (com.google.android.*).
# RIGHT
adb shell pm list packages -3
# `-3` filters to third-party (non-system) packages only.

必須ルール

  • MUST テスト間でアプリの状態をリセットするには、am force-stop ではデータが消去されないため、pm clear <pkg> を使用してください。
  • MUST テスト APK(android:testOnly="true")をインストールする際は -t を追加してください。ダウングレードする際は -d を追加し、マニフェストに記載されたすべてのランタイム権限を付与するには -g を追加してください。
  • MUST 分割 APK(App Bundle)には adb install-multiple を使用してください。分割 APK のうち1つだけをインストールすると、INSTALL_FAILED_INVALID_APK で失敗します。
  • MUST NOT 新しくビルドしたデバッグ APK の adb install によって、リリース署名済みのインストールが置き換えられると想定しないでください。署名の競合エラーが発生した場合は、先にアンインストールする必要があります。
  • MUST NOT pm list packages | grep による推測に頼らず、ドキュメントに記載されたフィルター(-3、-s、-d、-e、-u)を使用してください。
  • PREFERRED: テストのたびに手動で pm clear を実行するのではなく、Test Orchestrator を通じて clearPackageData true を設定してください(../../tests/running-instrumented-tests-via-adb/SKILL.md)。
  • PREFERRED: 空白やシェルのメタ文字を含む文字列引数は二重に引用符で囲んでください。Platform Tools 23 以降ではこれが必要です(ssh 形式の引用符付け)。

検証

  • adb install -r -t -g app-androidTest.apk が Success を返します。
  • adb shell pm path com.example.app を実行すると、インストール直後のパッケージに対して package:/data/app/...base.apk の行が表示されます。
  • adb shell pm clear com.example.app が Success を返し、adb shell run-as com.example.app ls /data/data/com.example.app を実行すると、新しく作成された cache/ と code_cache/ の項目だけが表示されます。
  • インストール後に adb shell pm list packages -3 | grep com.example.app を実行すると、パッケージが表示されます。
  • adb shell pm grant com.example.app android.permission.CAMERA を実行した後、adb shell dumpsys package com.example.app | grep CAMERA に権限が付与済みとして表示されます。
  • adb uninstall com.example.app が Success を返し、pm list packages com.example を実行してもアプリが表示されなくなります。
  • CI の実行では、Orchestrator(-e clearPackageData true)または @Before/@After の明示的な pm clear 手順によって、テスト間でアプリの状態が消去されます。

参考資料

  • ADB ユーザーガイド(pm install、pm uninstall、pm clear、pm grant、pm list packages):https://developer.android.com/tools/adb#pm
  • AGP/Studio のコマンドラインテスト(am instrument と Orchestrator の設定):https://developer.android.com/studio/test/command-line
  • cmd package dump-profiles によるベースラインプロファイルのダンプ:https://developer.android.com/topic/performance/baselineprofiles
  • App Bundle/分割 APK のインストール:https://developer.android.com/studio/build/build-variants
  • tasks/research/A2-adb-shell-commands.md — pm install/pm list/pm clear のフラグ一覧(原文)、force-stop と pm clear の違い、Platform Tools 23 以降の ssh 形式の二重シェル引用符付け。
  • docs/CORPUS.md §I.10 — 「force-stop ではデータは消去されません。完全に分離された状態にリセットするには pm clear を併用してください。」
  • 関連スキル:
    • 高水準アーキテクチャ:../../architecture/understanding-adb-architecture/SKILL.md
    • デバイスの接続:../../devices/connecting-to-devices/SKILL.md
    • ワイヤレス ADB:../../devices/connecting-over-wifi/SKILL.md
    • am instrument によるテストの実行(および Orchestrator の clearPackageData):../../tests/running-instrumented-tests-via-adb/SKILL.md
  • セット間の関連項目:
    • AndroidJUnit4 を使用したインストルメンテーションテストの実行:../../../instrumentation/runner/running-instrumented-tests-with-androidjunit4/SKILL.md
    • Android での JUnit4 の設定:../../../jvm-tests/runner/configuring-junit4-on-android/SKILL.md
    • ソースセットの方針:../../../fundamentals/strategies/organizing-test-source-sets/SKILL.md

コメント