Androidのデフォルトアプリ選択をリクエストする

Android端末でFirefoxをデフォルトブラウザにしていると、Chromeが嫉妬して、以下のようなダイアログが表示されます。

![](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/155171/4dfcfea4-d12a-1480-b865-c8c863b6d1fa.png)

アプリから自分をデフォルトアプリにしてくれとリクエストすることができるのか！
ということでやり方を調べました。

# RoleManager

結論からいうと、RoleManagerを使います。
https://developer.android.com/reference/android/app/role/RoleManager

API Level 29です。Android10以上で使える機能ですね。

# デフォルトブラウザアプリの設定をリクエストする

Chromeと同様にブラウザアプリをつくって、自分をデフォルトアプリにしてくれるようにリクエストしてみましょう。

## ブラウザアプリを作る

デフォルトブラウザをリクエストするには、当然ながらブラウザアプリを作る必要があります。
ブラウザ機能を作ろうと思うと大変ですが、「システムからブラウザアプリとして認識されるアプリ」を作るのは簡単です。

Activityに以下のintent-filterを設定します。
これだけでシステムからブラウザアプリとして認識されるようになります。

```xml:AndroidManifest.xml
<intent-filter>
    <action android:name="android.intent.action.VIEW" />

    <category android:name="android.intent.category.BROWSABLE" />
    <category android:name="android.intent.category.DEFAULT" />

    <data android:scheme="http" />
    <data android:scheme="https" />
</intent-filter>
```

「設定」→「アプリと通知」→「デフォルトのアプリ」→「ブラウザアプリ」を開いてみましょう。
上記Intentを設定したアプリがブラウザアプリとしてリストされるようになっています。
![](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/155171/41810af7-adae-acef-ccff-c9cdd4acbf6b.png)


## デフォルトブラウザアプリの設定をリクエストする

デフォルトブラウザアプリの設定をリクエストするにはIntentを投げるのですが、`startActivityForResult`を使う必要があります。
結果は、成功すれば`Activity.RESULT_OK`、それ以外では`Activity.RESULT_CANCELED`が返ってきます。
`startActivityForResult`はDeprecatedなのでactivity result contractを使いましょう。
結果はトーストで表示するようにしておきます。

```kotlin
private val launcher = registerForActivityResult(StartActivityForResult()) {
    val result = if (it.resultCode == Activity.RESULT_OK) "SUCCESS" else "FAILURE"
    Toast.makeText(this, result, Toast.LENGTH_LONG).show()
}
```

RoleManagerのインスタンスは`getSystemService`で取得します。
RoleManagerのインスタンスが取得できたら`createRequestRoleIntent`を使ってIntentを作成します。
引数にはデフォルトアプリのカテゴリーを示すROLEを指定します。
ブラウザアプリの場合は`ROLE_BROWSER`ですね。
他のROLEもRoleManagerに定義されています。

```kotlin
getSystemService<RoleManager>()
    ?.createRequestRoleIntent(RoleManager.ROLE_BROWSER)
    ?.let { 
        launcher.launch(it)
    }
```

これだけです。実行すると以下のように表示されます。

![](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/155171/d4883760-d129-96c8-9116-148c72ec158a.png)

デフォルトアプリとして選択されると

![](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/155171/45fe91ee-4a70-c48d-1f05-5cc9e386e582.png)

成功です。
なお、自身がすでにデフォルトアプリになっている場合、ダイアログが表示されず即座に成功が返ってきます。
また、他のアプリが選ばれたりすると、「次回から表示しない」チェックボックスが現れます。

![](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/155171/3fac17b4-b07f-599d-5d40-9ccd410c6515.png)

当然、チェックボックス付きでキャンセルされると次からはダイアログは表示されず失敗するようになります。


# デフォルトホームアプリの設定をリクエストする

今度はデフォルトホームアプリの設定をリクエストしてみましょう。

## ホームアプリを作る

「システムからホームアプリとして認識されるアプリ」を作ります。
以下のintent-filterを設定するだけです。

```AndroidManifest.xml
<intent-filter>
    <action android:name="android.intent.action.MAIN"/>

    <category android:name="android.intent.category.HOME"/>
    <category android:name="android.intent.category.DEFAULT"/>
</intent-filter>
```

「設定」→「アプリと通知」→「デフォルトのアプリ」→「ホームアプリ」に表示されるようになります。

![](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/155171/a69f3cac-5e24-8b1d-c393-4fc4016d3ed5.png)

## デフォルトホームアプリの設定をリクエストする

ブラウザと同じく、今度は`ROLE_HOME`を指定します。

```kotlin
getSystemService<RoleManager>()
    ?.createRequestRoleIntent(RoleManager.ROLE_HOME)
    ?.let { 
        launcher.launch(it)
    }
```

実行すると以下のように表示されます。

![](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/155171/ceda0482-899a-96cc-7a01-71190cd38a6c.png)

以上です。