はじめに
コンシューマアプリだとあまり需要があるように思えませんが,アプリケーションからアプリケーションのデータを削除したいと思うことがたまにあります.
基本的にはAndroidの設定からアプリを選択してデータを消去するのと変わりませんが,例えば ネットゲームでキャッシュが影響して不具合を起こしている場合,ユーザからの問い合わせに対してその手順を提供するよりも,アプリ内のヘルプ組み込んだ方がUXを向上できるかもしれません.
はたまたAndroidで独自プラットフォームを開発している場合,エンドユーザにはAndroid標準の設定にアクセスしてもらいたくないかもしれません.
そんなときにちょっとだけ手が届く「プログラムからアプリケーションのデータを削除」する方法の紹介です.
なお,下で紹介するメソッドを呼び出すと,その瞬間アプリが終了します.
実際にユーザに操作してもらう場合は「再起動します」などの案内を行い,呼び出す前にAlarmManagerなどで数秒後にアプリの起動処理も行うようにした方が良さそうです.
Android 4.4(API Level 19)以上の場合
ActivityManager#clearApplicationUserData() を呼び出すだけです.
簡単ですね
ActivityManager am = (ActivityManager) context.getSystemService(Service.ACTIVITY_SERVICE);
am.clearApplicationUserData();
Android 4.4未満の場合
ActivityManager#clearApplicationUserData()はAPI Level 19未満では呼び出せません.
リフレクションを用いて ActivityManager#clearApplicationUserData() を呼び出します.
しかし,clearApplicationUserData()の引数は Stringでパッケージ名と IPackageDataObserverなるインターフェースを渡す必要があります.
このインターフェースは通常のSDKのみではリンクできないので,Androidのリポジトリ からAIDLをダウンロードし,ソースディレクトリに配置します.
プロジェクトをリビルドすると,genディレクトリに IPackageDataObserver.java というインターフェースが自動生成されます.
あとはリフレクションで呼び出すだけです.
IPackageDataObserver observer = new IPackageDataObserver() {
@Override
public IBinder asBinder() {
return null;
}
@Override
public void onRemoveCompleted(String packageName, boolean succeeded)
throws RemoteException {
Log.i(TAG, "application data cleared!");
}
};
Method method = null;
try {
method = am.getClass().getMethod("clearApplicationUserData", String.class,
IPackageDataObserver.class);
method.invoke(am, context.getPackageName(), observer);
} catch (Exception e) {
Log.e(TAG, "Cannot reflection.", e);
}
番外編:自分自身以外のアプリケーションのデータを消去したい場合
上の方法はどれも自分自身のデータを消去する方法です.
API Level 19以上でも,当然ですが他のアプリケーションのデータを消すことはできません.
呼び出すメソッドは下と同じくリフレクションを用い,消去したいアプリケーションのパッケージ名を指定します.
ただし,Systemと同じ権限(android.uid.system)を持ち,プラットフォーム署名が必要です.
また, <uses-permission android:name="android.permission.CLEAR_APP_USER_DATA"/>
のパーミッションを指定する必要があります.