【Android】プリインストールアプリのアップデートの削除(アンインストール)時のイベント

Androidの開発に携わって、ぶつかった問題。

 

Androidアプリは自分で自分がアンインストールされることを検知できません。

 

パッケージが削除されるときに通知されるPACKAGE_REMOVEDというイベントがありますが、これを受信できるのは他のアプリです。

 

Javaで作るのでデストラクタがある訳でもなく、アンインストール時に解放したい値、初期化したい値があっても何もできないのです。

 

ただし、プリインストールアプリのアップデートの削除(アンインストール)を行う場合は、プリインストールアプリ側(古い方)でMY_PACKAGE_REPLACEDを受信できることがありました。仕事でこの挙動を何度も実機検証した結果、体感では9割くらいの確率でした。

 

方法はマニフェストファイルにMY_PACKAGE_REPLACEDを登録して、BroadcastReceiverを継承したクラスで受信するだけです。

 

これは、Android DevelopersのAPIリファレンスでは「既存のアプリケーションの上に新しいバージョンがインストールされた」と説明されているため、当時はアップデートを削除した時にも受信する理由が分かりませんでした。

2026年追記: なぜアップデート削除でもMY_PACKAGE_REPLACEDが来るのか

改めてAndroid Open Source Project(AOSP)のPackageManagerの実装を確認すると、これは偶然の挙動ではありませんでした。

アップデート済みのシステムアプリ(プリインストールアプリ)の更新版を削除すると、システム領域に残っている旧バージョンが再び有効になります。AOSPのPackageManagerServiceでは、この場合にPACKAGE_ADDED、PACKAGE_REPLACEDに続いてMY_PACKAGE_REPLACEDを対象アプリへ送る処理が明示的に入っています。つまりAndroid内部では、更新版の削除によって旧システムアプリへ戻る処理も「パッケージの置き換え」として扱われています。

・Android Developers: ACTION_MY_PACKAGE_REPLACED
・AOSP: PackageManagerService

一方、仕事で何度も実機検証した結果としての「体感9割くらい」という再現率のばらつきまでは、この実装だけでは説明し切れません。Androidのバージョン、端末メーカー側の実装、プロセスやパッケージの状態など、コードから一意に特定できない条件が関係していた可能性があります。少なくとも、MY_PACKAGE_REPLACEDが送信されること自体には実装上の根拠がありますが、端末上の実際の受信まで100%保証できる挙動として扱うべきではありません。だからこそ「必ずこれを受信して後処理できる」という前提で仕様を組むのは避けた方がよい、という当時の結論は変わりません。

 

アプリのアンインストール時に何かしようというのは基本的に諦めましょう。

 

代替方法としては、

・アンインストール時は諦めて、プリインストールアプリの場合はアプリ更新時に通知されるMY_PACKAGE_REPLACEDを受け取るか、普通のアプリの場合はPACKAGE_ADDEDを受け取る。

・アンインストール時は諦めて、プリインストールアプリの場合はアンインストール後に再起動する手順を含めることとして、起動時に通知されるBOOT_COMPLETEDを受信する。

・どうしてもアンインストール時に行いたいのであれば、他のアプリを用意してアンインストール時に通知されるPACKAGE_REMOVEDを受信する。

 

くれぐれもAndroidアプリでアンインストール時に何かしようなんて仕様を書かないように!!(ダジャレじゃない!!)

この記事を評価

星をクリックしてください

まだ評価はありません

TakKa

TakKa(たっか)といいます。ITエンジニア約10年していて、趣味としてドラムやギターの演奏や作編曲をしています。

音楽とものつむぎと人というテーマで、自分で経験・検証・調査したことを中心に、ここに生きた証として書き記します。

TakKaをフォローする
ソフトウェア開発
シェアする
TakKaをフォローする

コメント

タイトルとURLをコピーしました