1. ホーム
  2. android

[解決済み] API 30 で intent.resolveActivity は null を返す

2023-04-11 20:20:25

質問

見ていると intent.resolveActivity != null ですが、インテントを起動すると ActivityNotFound 例外をスローします。 ブラウザやDeepリンクのあるアプリケーションを開くと書きました。

private fun openUrl(url: String) {
    val intent = Intent().apply {
        action = Intent.ACTION_VIEW
        data = Uri.parse(url)
//        setDataAndType(Uri.parse(url), "text/html")
//        component = ComponentName("com.android.browser", "com.android.browser.BrowserActivity")
//        flags = Intent.FLAG_ACTIVITY_CLEAR_TOP + Intent.FLAG_GRANT_READ_URI_PERMISSION
    }
    val activityInfo = intent.resolveActivityInfo(packageManager, intent.flags)
    if (activityInfo?.exported == true) {
        startActivity(intent)
    } else {
        Toast.makeText(
            this,
            "No application can handle the link",
            Toast.LENGTH_SHORT
        ).show()
    }
}

うまくいきません。API 30エミュレータではブラウザが見つからず、一方、一般的な 解決策 は動作します。

private fun openUrl(url: String) {
    val intent = Intent(Intent.ACTION_VIEW, Uri.parse(url))
    try {
        startActivity(intent)
    } catch (e: ActivityNotFoundException) {
        Toast.makeText(
            this,
            "No application can handle the link",
            Toast.LENGTH_SHORT
        ).show()
    }
}

最初の方法はうまくいきません。 intent.resolveActivityInfo または intent.resolveActivity を返す null . しかし、PDF-viewer では が動作します。 .

を解除する必要があります。 intent.resolveActivity ?

どのように解決するのですか?

これは、以下の原因によるものと思われます。 Android 11 で導入されたパッケージの可視性に関する新しい制限。 .

基本的に、API レベル 30 から、そのバージョンまたはそれ以上をターゲットにしている場合、アプリは明示的に許容範囲を要求しない限り、ほとんどの外部パッケージを見たり、直接対話したりすることができません(包括的な QUERY_ALL_PACKAGES パーミッション、または適切な <queries> 要素を含めることです。

実際、最初のスニペットはその許可で期待通りに動作し、また適切な <queries> 要素で期待通りに動作します。

<queries>
    <intent>
        <action android:name="android.intent.action.VIEW" />
        <category android:name="android.intent.category.BROWSABLE" />
        <data android:scheme="https" />
    </intent>
</queries>


現在入手可能な情報はひどく具体的なものではありませんが、次のように記載されています。

その PackageManager など、他のアプリに関する結果を返すメソッドもあります。 queryIntentActivities() のように、他のアプリに関する結果を返すメソッドは、呼び出したアプリの <queries> 宣言に基づいてフィルタリングされます。

あなたの例では Intent メソッドを使っています。つまり resolveActivityInfo() - を実際に呼び出しているのは PackageManager query" メソッドを内部で呼び出しています。この変更によって影響を受けるすべてのメソッドと機能を網羅的にリストアップすることは不可能かもしれませんが、おそらく、以下のように仮定するのが安全でしょう。 PackageManager が関与している場合、新しい制限でその動作を確認するのがよいかもしれないと仮定するのはおそらく安全でしょう。