查询 ACTION_IMAGE_CAPTURE 的意图时,Android 11 (R) 返回空列表

Udi*_*shi 23 android android-intent android-camera android-camera-intent android-intent-chooser

设备:模拟器像素 3a - Android 11

代码:

    final List<Intent> cameraIntents = new ArrayList<Intent>();
    final Intent captureIntent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
    final List<ResolveInfo> listCam = 
    context.getPackageManager().queryIntentActivities(captureIntent, 0);
Run Code Online (Sandbox Code Playgroud)

使用时:

targetSdkVersion 30
compileSdkVersion 30
Run Code Online (Sandbox Code Playgroud)

listCam 大小为 0

当更改为:

compileSdkVersion 29
Run Code Online (Sandbox Code Playgroud)

listCam 大小为 1 - 应该如此。

使用以下代码:

    val captureIntent = Intent(MediaStore.ACTION_IMAGE_CAPTURE)
    baseActivity.startActivity(captureIntent)
Run Code Online (Sandbox Code Playgroud)

工作正常并显示相机应用程序。

知道为什么 queryIntentActivities 不返回相机意图吗?

谢谢!

Sau*_*rat 57

Android 11 改变了应用查询其他应用并与之交互的方式。

文档

PackageManager返回有关其他应用程序的结果的方法,例如queryIntentActivities(),根据调用应用程序的<queries>声明进行过滤。

所以你需要<queries>在你的声明中声明AndroidManifest.xml

<manifest package="com.example">
    <queries>
        <intent>
            <action android:name="android.media.action.IMAGE_CAPTURE" />
        </intent>
    </queries>
    ...
</manifest>
Run Code Online (Sandbox Code Playgroud)

  • 是的,但是:从 Android 11 开始,只有预装的系统相机应用程序可以响应以下 Intent 操作: android.media.action.VIDEO_CAPTURE android.media.action.IMAGE_CAPTURE android.media.action.IMAGE_CAPTURE_SECURE 所以即使我们声明&lt;queries&gt; 标签 - queryIntentActivities 函数始终仅返回一个系统相机应用程序 (6认同)

ND1*_*10_ 11

packageManager.queryIntentActivities(intent, 0) 如果您的应用程序正在运行,将返回一个 EMPTY 列表 targetSdkVersion 30

要解决此问题,您必须<queries>在清单中使用queryIntentActivities()根据调用应用程序的声明进行过滤。

修复图像捕获 + 图像上传以使用 Android“范围存储”

该问题可能与新的包可见性(https://developer.android.com/about/versions/11/privacy/package-visibility)有关。在所有更新(至少 Android Studio 4.1)之后,尝试在您的清单中添加显示您的应用程序需要执行哪些操作的清单。

在我的情况下,问题就消失了,当我添加 IMAGE_CAPTURE对于摄像机,GET_CONTENT图库(获取文件夹改变mime类型,如果你想视频),PICK图库(应该改变MIME类型如果u想视频) CHOOSER图库(如果有人有其他图像浏览器)

您还可以在 logcat 中检查您必须添加哪些查询(应包含“BLOCKED”或“无权限”。错误是因为ImagePickerModule当您在 Intent 中没有权限并resolveActivity返回时null(您可以对其进行评论以检查更好的错误startActivityForResult

添加<query>AndroidManifest.xml

<manifest>
.....
.....
<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" />
        <data android:mimeType="image/*" />
    </intent>
    <intent>
        <action android:name="android.intent.action.PICK" />
        <data android:mimeType="image/*" />
    </intent>
    <intent>
        <action android:name="android.intent.action.CHOOSER" />
     </intent>
</queries>
.....
.....
</manifest>
Run Code Online (Sandbox Code Playgroud)


Rus*_*hts 8

我的 Android 11 解决方案,用于获取 ResolveInfo 列表。

  • 当我们仅通过 MediaStore.ACTION_IMAGE_CAPTURE 过滤器扫描时,我们只会得到一张!应用记录 - 系统默认相机应用。
  • 为了使用其他相机应用程序,我们需要通过包名称指定每个应用程序,并为其提供 setPackage() 调用 - 然后 queryIntentActivities 可以正常工作,即使在 Android R 中也是如此

完整的解决方案如下:

/**
 * Return all camera possible apps
 * @param context
 * @return
 */
public static List<ResolveInfo> getCameraAppsResolveInfo(Context context){
    List<ResolveInfo> resolveInfo = new ArrayList<>();
    if (Utils.isNull(context)){
        return resolveInfo;
    }
    final Intent capturePhoto = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
    PackageManager pm = context.getPackageManager();
    resolveInfo = pm.queryIntentActivities(capturePhoto, 0);
    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.R){
        // For Android 11 we need to add specific camera apps
        // due them are not added during ACTION_IMAGE_CAPTURE scanning...
        resolveInfo.addAll(getCameraSpecificAppsInfo(context));
    }
    return resolveInfo;
}

/**
 * For Android 11
 * Return camera possible apps
 */
static final String[] CAMERA_SPECIFIC_APPS =  new String[]{
        "best.camera",
        "net.sourceforge.opencamera",
        "com.google.android.GoogleCamera",
        "tools.photo.hd.camera",
};
private static List<ResolveInfo> getCameraSpecificAppsInfo(Context context){
    List<ResolveInfo> resolveInfo = new ArrayList<>();
    if (Utils.isNull(context)){
        return resolveInfo;
    }
    PackageManager pm = context.getPackageManager();
    for (String packageName : CAMERA_SPECIFIC_APPS) {
        resolveInfo.addAll(getCameraSpecificAppInfo(packageName, pm));
    }
    return resolveInfo;
}
private static List<ResolveInfo> getCameraSpecificAppInfo(String packageName, PackageManager pm){
    Intent specificCameraApp = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
    specificCameraApp.setPackage(packageName);
    return pm.queryIntentActivities(specificCameraApp, 0);
}
Run Code Online (Sandbox Code Playgroud)

当然,在清单文件中,我们应该添加这些行(如接受的答案中所述)

<queries>
        <intent>
            <action android:name="android.media.action.IMAGE_CAPTURE" />
        </intent>
</queries>
Run Code Online (Sandbox Code Playgroud)