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

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

问题描述

查看 intent.resolveActivity!=为空,但启动该意图会引发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吗?

推荐答案

这似乎是由于.

基本上,从API级别30开始,如果您定位到该版本或更高版本,则您的应用无法在未明确请求许可的情况下(通过总的QUERY_ALL_PACKAGES权限或通过在清单中包含适当的<queries>元素.

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方法,例如

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天全站免登陆