在android 11中使用intet.resolveActivity时,请考虑在调用此方法时向清单中添加查询声明



我有一个扩展函数,用于打开我的活动的意图:

fun Activity.openIntent(action: String?, type: String?, uri: Uri?) {
Intent()
.apply {
action?.let { this.action = it }
uri?.let { this.data = it }
type?.let { this.type = it }
}
.also { intent ->
packageManager?.let {
if (intent.resolveActivity(it) != null)
startActivity(intent)
else
showToast(R.string.application_not_found)
}
}
}

我的targetSdkVersion30。它在intent.resolveActivity(it):中给我一个警告

调用此方法时,请考虑将查询声明添加到清单中。

那么我应该如何解决此警告?

最简单的解决方案是去掉resolveActivity()。替换:

packageManager?.let {
if (intent.resolveActivity(it) != null)
startActivity(intent)
else
showToast(R.string.application_not_found)
}

带有:

try {
startActivity(intent)
} catch (ex: ActivityNotFoundException) {
showToast(R.string.application_not_found)
}

这会给您带来相同的结果,但性能会稍好一些,并且它将消除警告。

另一种选择是添加QUERY_ALL_PACKAGES权限。这可能会禁止您进入Play商店。

否则,您将需要:

  • 建立应用程序可能进行的每个可能的openIntent()调用的列表

  • 向清单中添加一个<queries>元素,该元素列出了您希望能够与resolveActivity()一起使用的所有可能的Intent结构

  • 定期重复此过程,以防为openIntent()添加新场景

因此,启动安卓11(即,如果您的应用程序以安卓11为目标(,并不是所有应用程序都对应用程序可见。某些应用程序在默认情况下是可见的,但为了通过应用程序访问其他应用程序,您必须在清单中声明queries,否则您的应用程序将无法访问它们。你可以在这里阅读。

因此,如果你的应用程序以Android 11为目标,并且要访问一个默认情况下可能不可见的应用程序,你会希望在清单文件中为它们添加queries

在您的情况下,此警告不适用,因为我认为您正在使用隐式意图打开其他应用程序。使用隐式意图,可以访问其他应用程序,而不考虑应用程序的可见性。如果你的应用程序目标是Android 10或更低版本,你可以取消警告,因为默认情况下所有应用程序都是可见的。

要抑制皮棉警告,您可以:

  1. 添加抑制注释,如下所示:
@SuppressLint("QueryPermissionsNeeded")
fun Activity.openIntent(action: String?, type: String?, uri: Uri?): Activity {
  1. 将以下内容添加到应用模块构建渐变文件中的android块中:
lintOptions {
ignore "QueryPermissionsNeeded"
}

更换

if (intent.resolveActivity(it) != null)

带有

if (it.resolveActivity(intent, 0) != null)

警告就会消失。

来自API的30级程序包可见性受到限制。因此,在<application>标记之外的AndroidManifest文件中添加适当的query

<queries>
<intent>
<action android:name="android.intent.action.VIEW" />
<data android:scheme="http" />
</intent>
</queries>

最新更新