Androidアプリを起動する前にUSBデバッグをオフにする

TL;DR

FGOを起動する時にUSBデバッグが入ってたら起動しない上にメーラーが立ち上がるのがイライラするのでなんとかした。

作ったアプリ

https://github.com/consomme/Interceptor

アプリの概要

パッケージ名をIntentで渡すショートカットを作成し、それを受け取ったActivity上でUSBデバッグをオフにして起動したいアプリを起動させています。
アプリのアイコンも取得してショートカットを作成するため、見た目では普通にアプリを起動するのと全く変わりません。

実装のポイント

USBデバッグをオフにする

USBデバッグの状態をコード上から設定するには、Settings.Global.ADB_ENABLEDの値を書き換えればOKです。

Settings.Global.putInt(contentResolver, Settings.Global.ADB_ENABLED, 0)

これを実行するにはWRITE_SECURE_SETTINGSのパーミッションが必要になりますが、これはサードパーティーアプリからは設定できないようになっています。
Manifest.permission | Android Developers

そこで、adbを使って外からパーミッションをつけてあげます。Manifestに記述した上でadb shell pm grantを叩きます。

AndroidManifest.xml
<uses-permission
    android:name="android.permission.WRITE_SECURE_SETTINGS"
    tools:ignore="ProtectedPermissions" />
$ adb shell pm grant ${package_name} android.permission.WRITE_SECURE_SETTINGS

ショートカットを作る

API25(Android 7.1)からApp Shortcutsが追加されたことにより、従来のEXTRA_SHORTCUT_INTENTを使う方法がDeprecatedになり、新しく追加されたShortcutManagerを使うことが推奨されました。
API25未満のバージョンに対応するには、Support LibraryにあるShortcutManagerCompatを使えば問題なく実装できます。

private fun createShortcut(appInfoModel: AppInfoModel) {
    val intent = InterceptActivity.createIntent(this, appInfoModel.packageName);
    intent.action = Intent.ACTION_MAIN
    intent.addCategory(Intent.CATEGORY_LAUNCHER)

    val iconBitmapDrawable = appInfoModel.icon as BitmapDrawable
    val shortcutInfoCompat = ShortcutInfoCompat.Builder(this, "interceptor")
            .setShortLabel(appInfoModel.name)
            .setLongLabel(appInfoModel.name)
            .setIcon(IconCompat.createWithBitmap(iconBitmapDrawable.bitmap))
            .setIntent(intent)
            .build()
    ShortcutManagerCompat.requestPinShortcut(this, shortcutInfoCompat, null)
}

最後に

今回はとりあえずUSBデバッグをオフにしたいだけだったのでシンプルなアプリになりましたが、これ以外にも「起動前にこんな処理を挟みたい」というアイデアがあればいろいろできると思います。
みなさん是非快適なカルデアライフを。