Coo*_*ind 56 android android-manifest android-intent activitynotfoundexception android-11
查看intent.resolveActivity != null 但启动 Intent 会引发 ActivityNotFound 异常,我在打开浏览器或具有深度链接的应用程序时写道:
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()
}
}
Run Code Online (Sandbox Code Playgroud)
它不起作用。在 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()
}
}
Run Code Online (Sandbox Code Playgroud)
第一种方法不起作用,因为intent.resolveActivityInfoorintent.resolveActivity返回null。但对于 PDF 浏览器它有效。
我们应该解雇intent.resolveActivity吗?
Mik*_* M. 76
这似乎是由于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>
Run Code Online (Sandbox Code Playgroud)
当前可用的信息并不是非常具体,但它确实说明了:
PackageManager返回其他应用程序结果的方法,例如queryIntentActivities(),根据调用应用程序的<queries>声明进行过滤
尽管您的示例使用了一种Intent方法——即resolveActivityInfo()——实际上是在PackageManager内部调用“查询”方法。受此更改影响的每个方法和功能的详尽列表可能不可行,但可以安全地假设,如果PackageManager涉及到,您最好使用新限制检查其行为。
Coo*_*ind 48
感谢Mike M。我添加了对Browser,Camera和 的查询Gallery。将它们放在AndroidManifest它的任何部分(<application>标签之前或之后)。
查看MediaStore.ACTION_IMAGE_CAPTURE和Intent.ACTION_GET_CONTENT我得到了两个操作。
<queries>
<!-- Browser -->
<intent>
<action android:name="android.intent.action.VIEW" />
<data android:scheme="http" />
</intent>
<!-- Camera -->
<intent>
<action android:name="android.media.action.IMAGE_CAPTURE" />
</intent>
<!-- Gallery -->
<intent>
<action android:name="android.intent.action.GET_CONTENT" />
</intent>
</queries>
Run Code Online (Sandbox Code Playgroud)
我不需要Dylan 的回答,所以我仍然有
<uses-feature
android:name="android.hardware.camera"
android:required="false"
/>
Run Code Online (Sandbox Code Playgroud)
ful*_*oon 16
对我来说,我试图发送一封电子邮件,所以我需要像这样在 Manifest 中设置查询:
<queries>
<intent>
<action android:name="android.intent.action.SENDTO" />
<data android:scheme="*" />
</intent>
</queries>
Run Code Online (Sandbox Code Playgroud)
然后发送电子邮件并检查电子邮件客户端,如下所示:
private fun sendEmail(to: Array<String>) {
val intent = Intent(Intent.ACTION_SENDTO)
intent.data = Uri.parse("mailto:") // only email apps should handle this
intent.putExtra(Intent.EXTRA_EMAIL, to)
// intent.putExtra(Intent.EXTRA_SUBJECT, subject)
if (intent.resolveActivity(requireContext().packageManager) != null) {
startActivity(intent)
}
}
Run Code Online (Sandbox Code Playgroud)
Avi*_*tal 11
对于需要启动Activity(不仅检查是否存在)的情况,按照这个建议我删除了
if (intent.resolveActivity(packageManager) != null)
startActivity(intent);
Run Code Online (Sandbox Code Playgroud)
并写了instaed
try {
startActivity(intent);
} catch (ActivityNotFoundException e) {
Toast.makeText(getContext(), getString(R.string.error), Toast.LENGTH_SHORT).show();
}
Run Code Online (Sandbox Code Playgroud)
无需<queries>在Manifest. 在 Api 28 和 Api 30 上进行了测试。
要迭代 Avital 的答案,如果您想启动一个意图并了解它是否已启动,则无需声明任何内容:
private fun startIntent(intent: Intent): Boolean {
return try {
context.startActivity(intent)
true
} catch (e: ActivityNotFoundException) {
Logger.error("Can't handle intent $intent")
false
}
}
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
18215 次 |
| 最近记录: |