ページ

2014/03/18

[Android]アプリがアップデートしたことを検知するBroadcastReceiver

自分のアプリをアップデートした際に Service や AlarmManager が止まるので
再起動するために Broadcast Intent を受信したいと思います。

パッケージ関連の BroadcastIntent は
以下の操作でそれぞれのアクションが入った Intent が飛ぶようです。
Google Play から新規にアプリをインストール
android.intent.action.ACTION_PACKAGE_ADDED

アプリをアンインストール
android.intent.action.ACTION_PACKAGE_REMOVED

アプリをアップデート
android.intent.action.PACKAGE_REMOVED
android.intent.action.PACKAGE_ADDED
android.intent.action.PACKAGE_REPLACED

アプリデータを消去
(設定->アプリケーション->アプリケーションの管理->アプリを選択->データを消去)
android.intent.action.PACKAGE_RESTARTED
android.intent.action.PACKAGE_DATA_CLEARED

(プリインアプリの)アップデートのアンインストール
android.intent.action.PACKAGE_REMOVED
android.intent.action.PACKAGE_ADDED
android.intent.action.PACKAGE_REPLACED


ACTION_MY_PACKAGE_REPLACED (API Level 12)は更新したアプリ自体に飛んでくるもののようなので、他のものとはちょっと扱いが違いますが便利そうなIntentですね。アプリ更新したときの更新情報を表示したりするのに使えそう。
ITで何かできないかを考えてみる Android PACKAGE関連のbroadcast intentを試してみた

アップデートの場合は android.intent.action.PACKAGE_REPLACED を捕まえてあげればいいのですが、
自分のアプリだけでなく他のアプリのアップデートなども飛んできてしまいますので
以下のようにチェックする必要があります。
public class UpdateBroadcastReceiver extends BroadcastReceiver {
    @Override
    public void onReceive(Context context, Intent intent){
        String action = intent.getAction();
        String packagePath = intent.getDataString(); // package:app.package.name
        if(Intent.ACTION_PACKAGE_REPLACED.equals(action)
            && packagePath.equals("package:" + context.getPackageName())){
            // App updated!
        }
    }
}
<receiver android:name=".UpdateBroadcastReceiver">
    <intent-filter>
        <action android:name="android.intent.action.PACKAGE_REPLACED" />
        <data android:scheme="package" />
    </intent-filter>
</receiver>

もう少し未来になると API Level 12 以上の端末ばかりになって
自分のアプリのアップデートだけで飛んでくる
ACTION_MY_PACKAGE_REPLACED が使えるようになると思います。
public class UpdateBroadcastReceiver extends BroadcastReceiver {
    @Override
    public void onReceive(Context context, Intent intent){
        String action = intent.getAction();
        String packagePath = intent.getDataString(); // package:app.package.name
        if(Intent.ACTION_MY_PACKAGE_REPLACED.equals(action)){
            // App updated!
        }
    }
}
<receiver android:name=".UpdateBroadcastReceiver">
    <intent-filter>
        <action android:name="android.intent.action.ACTION_MY_PACKAGE_REPLACED" />
    </intent-filter>
</receiver>

アプリの更新って Google Play で自動に実行されたりするので、
コレで拾って更新通知のダイアログ風な Activity を開いたらリテンションに繋がりそう。
まぁ意図せず画面を奪うことになるからイラッと来て
アンインストールされそうだからやめたほうがいいだろうけど。