【Android】悪用厳禁！アンインストールのIntentについて


特定のアプリをアンインストールしたい場合、以下のIntentを飛ばすことでアンインストール画面が起動する。
※Intent Filterを見るとこれ以外の方法でもできる。UNINSTALL_PACKAGEとか。

```java
// String packageName = アンインストールするアプリのPackage名
Uri uri = Uri.fromParts("package", packageName, null);
Intent intent = new Intent(Intent.ACTION_DELETE, uri);
context.startActivity(intent);
```

Intentを実行することで、[com.android.packageinstaller.UninstallerActivity](http://tools.oesf.biz/android-4.4.4_r1.0/xref/packages/apps/PackageInstaller/src/com/android/packageinstaller/UninstallerActivity.java)が起動します。

## [UninstallerActivity](http://tools.oesf.biz/android-4.4.4_r1.0/xref/packages/apps/PackageInstaller/src/com/android/packageinstaller/UninstallerActivity.java)

UninstallerActivityの定義は以下のようになっています。
※[http://tools.oesf.biz/android-4.4.4_r1.0/xref/packages/apps/PackageInstaller/AndroidManifest.xml](http://tools.oesf.biz/android-4.4.4_r1.0/xref/packages/apps/PackageInstaller/AndroidManifest.xml)

```xml
<activity android:name=".UninstallerActivity"
        android:configChanges="orientation|keyboardHidden|screenSize"
        android:excludeFromRecents="true"
        android:theme="@android:style/Theme.DeviceDefault.Dialog.NoActionBar">
    <intent-filter>
        <action android:name="android.intent.action.DELETE" />
        <action android:name="android.intent.action.UNINSTALL_PACKAGE" />
        <category android:name="android.intent.category.DEFAULT" />
        <data android:scheme="package" />
    </intent-filter>
</activity>

```

## startActivityForResultでIntetn投げても無駄？
自分のアプリ側からstartActivityForResultでIntentを投げて、アンインストール成功したらResultの結果を見て、正常にアンインストールされたかチェックしたいなー。と思いました。

ということで、以下のような感じで動作確認したのですが・・・残念な結果になりました。
※Xperia acro HDとNexus5で確認

```java
// String packageName = アンインストールするアプリのPackage名
// requestCode = 1
Uri uri = Uri.fromParts("package", packageName, null);
Intent intent = new Intent(Intent.ACTION_DELETE, uri);
activity.startActivityForResult(intent, requestCode);

@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
    super.onActivityResult(requestCode, resultCode, data);
    Log.d("onActivityResult", "requestCode : " + requestCode);
    Log.d("onActivityResult", "resultCode : " + (RESULT_OK == resultCode));
    Log.d("onActivityResult", "resultCode : " + resultCode);
    Log.d("onActivityResult", "onActivityResult");
}
```

**アンインストールに成功・失敗・キャンセル**した場合でもLogの結果は以下になります。

```
D/onActivityResult(24263): requestCode : 1
D/onActivityResult(24263): resultCode : false
D/onActivityResult(24263): resultCode : 0
// resultCode = 0 = RESULT_CANCELED??
```

常に[RESULT_CANCELED](http://developer.android.com/reference/android/app/Activity.html#RESULT_CANCELED)がonActivityResultのresultCodeに返ってきてるような気がします。
UninstallerActivityの実装を見てみると、setResultしている箇所があるんですが、なぜか思った値が返ってこないなー。
私の実装が悪い可能性がありますが、onActivityResultでアンインストールの成功等の結果を判定するのは難しいのかなーという結果になりました。

なので、アンインストールが成功したかどうかはIntentで飛ばしたPackage名を一旦フィールドで保持し、onActivityResultで再度PackageManager等を使用して、Package名が存在するかどうかみたいな実装が必要なのかなーと思います。

## UninstallerActivityは残念だ！

このActivityは、AndroidのバージョンによってUIが画面だったりDialogっぽかったりします。
Android4.4.4のUninstallerActivityの実装を見て残念な気持ちになるんですが、[onCreateDialogメソッド](http://developer.android.com/reference/android/app/Activity.html#onCreateDialog%28int%29)を使って、アンインストールのDialogを出してます。
**DialogFragment使えや、コラ！**という気持ちが抑えきれない。
というか、**deprecatedになったメソッド使うんじゃねー!**
UIを変えるなら実装もしっかりそのバージョンに合わせて欲しいなー。
startActivityForResultの件もあるので、ちょっと残念な感じです。

## まとめ
悪用厳禁と書いたけど、悪用できる方法があれば知りたいねー。
Intent飛ばして、勝手にタッチイベント走らせるとかとか。。。

まあ気に食わないアプリがある場合、**画面を開くといきなりとあるアプリ(気に食わないアプリ)をアンインストールしてもいいかな？という画面が出てくる！**みたいな実装ができるわけです。
あ、面白い面白い！！

というくだらないことを書くために書いた記事です。。。