Intent.resolveActivity 在 API 30 中返回 null [英] intent.resolveActivity returns null in API 30

查看:59
本文介绍了Intent.resolveActivity 在 API 30 中返回 null的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

看着 intent.resolveActivity != null 但是启动 Intent 会引发 ActivityNotFound 异常我写过打开浏览器或具有深层链接的应用程序:

Looking at intent.resolveActivity != null but launching the intent throws an ActivityNotFound exception I wrote opening a browser or an application with Deep linking:

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 模拟器中找不到浏览器,而常见的 解决方案有效:

It doesn't work. No browser found in API 30 emulator, while a common solution works:

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.resolveActivityInfointent.resolveActivity 返回null.但是对于 PDF 查看器它有效.

The first method doesn't work, because intent.resolveActivityInfo or intent.resolveActivity returns null. But for PDF-viewer it works.

我们应该关闭intent.resolveActivity吗?

推荐答案

这似乎是由于 对包裹可见性"的新限制;在 Android 11 中引入.

基本上,从 API 级别 30 开始,如果您的目标是该版本或更高版本,则您的应用无法看到或直接与大多数外部包交互,而无需明确请求许可,无论是通过一揽子QUERY_ALL_PACKAGES 许可,或通过在清单中包含适当的 元素.

Basically, starting with API level 30, if you're targeting that version or higher, your app cannot see, or directly interact with, most external packages without explicitly requesting allowance, either through a blanket QUERY_ALL_PACKAGES permission, or by including an appropriate <queries> element in your manifest.

确实,您的第一个代码段在具有该权限或清单中适当的 <queries> 元素的情况下按预期工作;例如:

Indeed, your first snippet works as expected with that permission, or with an appropriate <queries> element in the manifest; for example:

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


目前可用的信息不是很具体,但确实说明了:


The information currently available isn't terribly specific, but it does state:

返回其他应用程序结果的 PackageManager 方法,例如 queryIntentActivities(),根据调用应用的声明进行过滤

The PackageManager methods that return results about other apps, such as queryIntentActivities(), are filtered based on the calling app's <queries> declaration

尽管您的示例使用了 Intent 方法 - 即 resolveActivityInfo() - 这实际上是在调用 PackageManager query"内部方法.列出受此更改影响的所有方法和功能的详尽列表可能不可行,但可以安全地假设,如果涉及 PackageManager,您最好使用新限制检查其行为.

Though your example is using an Intent method – i.e., resolveActivityInfo() – that's actually calling PackageManager "query" methods internally. An exhaustive list of every method and functionality affected by this change might not be feasible, but it's probably safe to assume that if PackageManager is involved, you might do well to check its behavior with the new restrictions.

这篇关于Intent.resolveActivity 在 API 30 中返回 null的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆