pm install-create
端末を変えるインストールセッションを開き、base とその split をまとめて 1 つの操作としてインストールします。
- コマンド
- adb shell pm install-create
- コマンド
- パッケージ(pm)
- リスク
- 端末を変える
構文
pm install-create [-r] [-g] [-d] [-t] [-S <total bytes>]
pm install-write [-S <bytes>] <session> <name> <path or ->
pm install-commit <session>
pm install-abandon <session>フラグと引数
| トークン | 意味 |
|---|---|
| -S <bytes> | `install-create` では全体の合計サイズで、インストーラが領域を確保して早めに失敗できるようにします。`install-write` ではそのファイルの正確なサイズで、バイト列が標準入力から来る場合は必須です。読み手には終わりを知る他の手段がありません。 |
| - | `install-write` のパス引数として、APK のバイト列を標準入力から読みます。 |
| -r -g -d -t | インストールオプション。これらは `install-create` に付けます。`install-commit` はインストールパラメータを一切取らないので、commit に付けたフラグは黙って捨てられます。 |
使用例
pm install-create -r -S 8234567882 MB のセット用にセッションを開きます。応答にセッション id が入っています。
pm install-write -S 41000000 1234567 base.apk /data/local/tmp/base.apkpush 済みのファイルを 1 つセッションに追加します。
pm install-commit 1234567セッションの中身を 1 回の操作としてインストールします。
pm install-abandon 1234567セッションを捨てて、staging したバイト列を解放します。
出力の読み方
出力例
Success: created install session [1234567]`install-create` はセッション id を角括弧で返し、その番号が以降すべての引数になります。各 `install-write` は `Success` か `Failure [INSTALL_FAILED_…]` を返し、いちばん重要なのは `install-commit` の失敗です。署名、分割セットの整合性、検証の問題はそこで初めて表に出ます。それまではインストール済みのアプリと何も突き合わせていないからです。
出力フィールド
| フィールド | 意味 |
|---|---|
| Success: created install session [<id>] | install-write と install-commit に渡すセッション id。 |
| Success | その書き込み、または commit が受け付けられました。 |
| Error: must specify a APK size | 標準入力から読む `install-write` に -S がありません。 |
| INSTALL_FAILED_INVALID_APK | セットが整合していません。split の重複、base の不一致など。 |
| INSTALL_FAILED_ABORTED | セッションが abandon された、または端末側の確認に応答しなかった。 |
必要な権限
`pm install` と同じ認可済みの `adb` 接続、そして staging したファイルを端末が読めることという同じ条件です。セッションが追加するのは「自分が持ち主になり、返さなければならないリソース」です。作成したセッションは、commit されるか abandon されるか `PackageInstallerService` に期限切れにされるまで、途中のバイト列を `/data/app/vmdl<id>.tmp` に置いたままにします。つまり `install-abandon` と対になっていない試行は、1 回ごとにゴミを 1 つ残します。権限エラーも告げず、ダイアログも触れない、ゆっくりした容量の漏れです。`install-write ... -` で標準入力から流し込む場合も追加のアクセスは要りませんが、`-S <bytes>` は必須です。転送路は、結果を運ぶ応答ごと落とさずに end-of-file を伝えられないからです。`pm install` が出し得る端末側のダイアログはここでも出ます。しかも出るのは create のときではなく commit のときなので、無人で回した実行は最初ではなく最後の段で死にがちです。
エラーメッセージの読み解き
| メッセージ | 意味 |
|---|---|
| Error: must specify a APK size | 標準入力から読む `install-write` に `-S` がありません。文言はプラットフォームのもので、typo もそのままです。注意したいのは、この時点でセッションはまだ開いているということです。自動的に巻き戻る失敗ではなく、`install-abandon` で後片付けが必要な失敗です。 |
| Failure [INSTALL_FAILED_INVALID_APK: Split lib_a was defined multiple times] | セットが整合していません。ここでは 2 つのファイルが同じ split 名を名乗りました。これは commit 時の判定で、セッションという仕組みの形そのものでもあります。すべての部品が書き終わるまでインストール済みのアプリと突き合わせないので、write のときの間違いが最後になって表に出ます。 |
| Failure [INSTALL_FAILED_ABORTED: Failed to commit install session 731045162 with command cmd package install-commit 731045162. Error: INSTALL_FAILED_ABORTED: Session was abandoned] | 入れ子になった形です。この行に出てくる 2 つのトークンはどちらも表で説明できるものなので、認識器はフレームワーク自身が選んだ最初のコードを報告します。それでも括弧の終わりまで読んでください。その id に対して abandon がすでに走ったと教えてくれているのは `Session was abandoned` の部分で、そのセッションを再 commit しても永久に通りません。 |
何が変わるか、そして戻る道
インストール自体は `pm install` と同じく既存のアプリを置き換えます。セッション固有の危険は「開いたまま放置すること」です。作成したセッションは commit か abandon まで端末上に staging したバイト列を保持するので、`pm install-abandon <session>` は任意の後片付けではなく必須の手順です。
バージョンとメーカーに関する注意
- `install-write` の split 名はセッション内のラベルでパスではありません。デスクトップの adb も単にファイルの basename を渡しています。
- Android 7 以降は `cmd package install-create` が同じコマンドへの短い経路で、`pm` はそのラッパースクリプトです。
- 標準入力からのストリーミングに `-S` が要るのは、応答も一緒に落とさずに end-of-file を伝えられないからです。読み取りを終わらせるのは EOF ではなくサイズです。
これには UI があります
APK Installer はこのコマンドを USB 経由で実行し、返ってきたものを解析します。Chromium 系ブラウザだけで、SDK も不要、どこにもアップロードしません。
関連コマンド
pm install-create と同じ作業で出てくるコマンド。
| コマンド | 何をするか |
|---|---|
| pm install | すでに端末上にある APK を 1 つインストールします。`adb install` が内部でやっていることです。 |
| pm path | インストール済みパッケージを構成する APK ファイルの絶対パスを表示します。 |
| pm uninstall | パッケージを削除します。ユーザー単位の削除なら、root なしでプリインストールアプリを片付けられます。 |
他のパッケージ(pm)コマンド
| コマンド | 何をするか |
|---|---|
| pm list packages | インストール済みパッケージを一覧表示します。APK パス、uid、バージョンコード、インストーラも同時に取得できます。 |
| pm disable-user | パッケージを削除せずに、指定した Android ユーザーで無効にします。アンインストールより安全で、確実に戻せます。 |
| pm clear | アプリのデータを消去します。Android 13 以降ならキャッシュだけを消すこともできます。 |
| pm trim-caches | 指定した空き容量に達するまで、システムにキャッシュファイルを捨てさせます。 |
Web ADB ツール群のパーサを書きながら、AOSP・toybox・カーネルのソースに突き合わせて確認しています。バージョンやメーカーで本当に挙動が変わるところは、世界の半分の端末で間違いになる数値を出す代わりに、そう書いてあります。