无法打开相机意图。 queryIntentActivities 在 api 级别 30 返回一个空列表,但在级别 29 中找到结果。发生了啥变化?
Posted
技术标签:
【中文标题】无法打开相机意图。 queryIntentActivities 在 api 级别 30 返回一个空列表,但在级别 29 中找到结果。发生了啥变化?【英文标题】:Can't open camera intent. queryIntentActivities returns an empty list on api level 30 but finds results in level 29. What changed?无法打开相机意图。 queryIntentActivities 在 api 级别 30 返回一个空列表,但在级别 29 中找到结果。发生了什么变化? 【发布时间】:2021-01-23 06:45:24 【问题描述】:我正在使用 queryIntentActivities 查询活动,它在 api 级别 29 中运行良好,但一旦我升级到级别 30,结果总是为空。
这是意图:
val intent = Intent(MediaStore.ACTION_IMAGE_CAPTURE)
intent.putExtra("android.intent.extras.CAMERA_FACING", typeCamera)
uri?.grantWriteForIntent(activity, intent)
intent.putExtra(MediaStore.EXTRA_OUTPUT, uri)
if (intent.isIntentSafe(activity))
activity.__waitResult__ = true
activity.startActivityForResult(intent, requestCode)
然后是isIntentSafe
函数:
fun Intent?.isIntentSafe(context: Context) =
if (this == null)
false
else
context.packageManager.queryIntentActivities(this, PackageManager.MATCH_DEFAULT_ONLY).size > 0
这就是queryIntentActivites
在第 30 级为空而在第 29 级有内容的地方。有谁知道这些级别之间发生了什么变化会产生这种效果?
我应该补充一点,如果我在两个 api 级别中跳过isIntentSafe
检查,那么无论如何活动都可以正常启动。但我想知道为什么 isIntentSafe 在较新的 api 中停止工作。
编辑:我已经尝试改变前置摄像头的意图,就像在这个答案 How to launch front camera with intent? 中一样,这并没有什么不同。
【问题讨论】:
【参考方案1】:我再次经历了Android 11的变化,发现"Media intent actions require default system camera"。
所以我搜索了一下,找到了solution from CommonsGuy。稍微修改一下代码,打开前置摄像头,马上就生效了!
fun enhanceCameraIntent(context: Context, baseIntent: Intent, title: String): Intent
val pm = context.packageManager
val cameraIntents =
CAMERA_CANDIDATES.map Intent(baseIntent).setPackage(it)
.filter pm.queryIntentActivities(it, 0).isNotEmpty()
.toTypedArray()
return if (cameraIntents.isEmpty())
baseIntent
else
Intent
.createChooser(baseIntent, title)
.putExtra(Intent.EXTRA_INITIAL_INTENTS, cameraIntents)
fun openFrontFacingCamera(activity: BaseActivity, uri: Uri?, requestCode: Int)
try
val baseIntent = Intent(MediaStore.ACTION_IMAGE_CAPTURE)
uri?.grantWriteForIntent(activity, baseIntent)
baseIntent.putExtra(MediaStore.EXTRA_OUTPUT, uri)
baseIntent.addFlags(Intent.FLAG_GRANT_WRITE_URI_PERMISSION)
baseIntent.putExtra("android.intent.extra.USE_FRONT_CAMERA", true)
activity.startActivityForResult(
enhanceCameraIntent(activity, baseIntent, MediaStore.ACTION_IMAGE_CAPTURE),
requestCode
)
catch (ex: ActivityNotFoundException)
Log.d("No default camera", "Activity not found!")
和以前一样,向 CommonsGuy 致敬!
【讨论】:
【参考方案2】:在 Android 11 中,有新的rules 用于与设备上安装的应用进行交互。
因此,如果您的应用面向 Android 11 或更高版本,您可能需要在应用的清单文件中添加 <queries>
元素:
<queries>
<intent>
<action android:name="android.media.action.IMAGE_CAPTURE" />
</intent>
</queries>
您还可以在此guide 中找到更多详细信息。
【讨论】:
Android Studio 会抱怨我直接在清单中添加了一个以上是关于无法打开相机意图。 queryIntentActivities 在 api 级别 30 返回一个空列表,但在级别 29 中找到结果。发生了啥变化?的主要内容,如果未能解决你的问题,请参考以下文章