14
13

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 5 years have passed since last update.

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

Posted at

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

// 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が起動します。

UninstallerActivity

UninstallerActivityの定義は以下のようになっています。
http://tools.oesf.biz/android-4.4.4_r1.0/xref/packages/apps/PackageInstaller/AndroidManifest.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で確認

// 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がonActivityResultのresultCodeに返ってきてるような気がします。
UninstallerActivityの実装を見てみると、setResultしている箇所があるんですが、なぜか思った値が返ってこないなー。
私の実装が悪い可能性がありますが、onActivityResultでアンインストールの成功等の結果を判定するのは難しいのかなーという結果になりました。

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

UninstallerActivityは残念だ!

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

まとめ

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

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

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

14
13
1

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
14
13

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?