在 android 11 中使用 intent.resolveActivity 时调用此方法时,请考虑在清单中添加查询声明
Posted
技术标签:
【中文标题】在 android 11 中使用 intent.resolveActivity 时调用此方法时,请考虑在清单中添加查询声明【英文标题】:Consider adding a queries declaration to your manifest when calling this method when using intent.resolveActivity in android 11 【发布时间】:2021-03-04 19:47:54 【问题描述】:我有一个扩展功能,用于为我的活动打开意图:
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)
我的targetSdkVersion
是 30。它在intent.resolveActivity(it)
中给了我一个警告:
考虑在调用此方法时向您的清单添加查询声明。
那么我应该怎么做才能解决这个警告呢?
【问题讨论】:
【参考方案1】:最简单的解决方案是去掉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()
调用建立一个列表
Add a <queries>
element to your manifest 列出了您希望能够与resolveActivity()
一起使用的所有可能的Intent
结构
定期重复此过程,以防您为 openIntent()
添加新场景
【讨论】:
The application could not be installed: INSTALL_PARSE_FAILED_MANIFEST_MALFORMED
。如果我将查询元素添加到清单中,我会收到此错误。 gist.github.com/sudhirkhanger/fbb613b38f25c44ad0342a237a2d06e6
@SudhirSinghKhanger:none
不是有效的 MIME 类型,因此该元素没有帮助。尝试删除它。【参考方案2】:
因此,从 android 11 开始(即,如果您的应用以 Android 11 为目标平台)并非所有应用都对您的应用可见。有些应用程序是visible by default,但为了通过您的应用程序访问其他应用程序,您必须在清单中声明queries
,否则您的应用程序将无法访问它们。你可以阅读here。
因此,如果您的应用程序以 Android 11 为目标并且要访问默认情况下可能不可见的应用程序,您需要在清单文件中为它们添加 queries
。
在您的情况下,此警告不适用,因为我相信您正在使用隐式意图打开其他应用程序。使用隐式意图,无论应用程序可见性如何,都可以访问其他应用程序。如果您的应用面向 Android 10 或更低版本,您可以隐藏警告,因为默认情况下所有应用都可见。
要抑制 lint 警告,您可以:
-
添加抑制注释,如下所示:
@SuppressLint("QueryPermissionsNeeded")
fun Activity.openIntent(action: String?, type: String?, uri: Uri?): Activity
-
将以下内容添加到应用模块构建 gradle 文件中的 android 块中:
lintOptions
ignore "QueryPermissionsNeeded"
【讨论】:
似乎只有 lintOptions 块可以完成这项工作。谢谢! 两者都能胜任。您可以使用两者中的任何一个。 “此警告不适用,因为我认为您正在使用隐式意图打开其他应用程序”- 警告来自resolveActivity()
调用,它需要 <queries>
元素才能工作。
是的,这就是我写的。尽管只有在官方 android 文档中指定的针对 API 30 的显式意图和应用程序才会出现这种情况。我在我的回答中提供了相同的恰当参考
假设您制作了一个针对 Android 11 的应用程序,并且您想明确打开 WhatsApp 应用程序,但您没有在 Manifest 中为其添加 query
。如果我们将startActivity
调用包装在try-catch
块中,那么即使设备安装了WhatsApp
应用程序,控件也将始终落在Android 11 设备上的catch 块上。【参考方案3】:
替换
if (intent.resolveActivity(it) != null)
与
if (it.resolveActivity(intent, 0) != null)
警告就会消失。
【讨论】:
it
是什么对象?
it
是PackageManager
。以上是关于在 android 11 中使用 intent.resolveActivity 时调用此方法时,请考虑在清单中添加查询声明的主要内容,如果未能解决你的问题,请参考以下文章
Android 相机意图在 Android 11 中没有响应
Android入门第11天-Android中RadioButton的使用
在 android 11 中使用 intent.resolveActivity 时调用此方法时,请考虑在清单中添加查询声明