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()
}
}
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()
}
}
The first method doesn't work, because intent.resolveActivityInfo or intent.resolveActivity returns null. But for PDF-viewer it works.
Should we dismiss intent.resolveActivity?
This appears to be due to the new restrictions on "package visibility" introduced in Android 11.
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_PACKAGESpermission, or by including an appropriate<queries>element in your manifest.Indeed, your first snippet works as expected with that permission, or with an appropriate
<queries>element in the manifest; for example:The information currently available isn't terribly specific, but it does state:
Though your example is using an
Intentmethod – i.e.,resolveActivityInfo()– that's actually callingPackageManager"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 ifPackageManageris involved, you might do well to check its behavior with the new restrictions.