Android 11 (R) return empty list when querying intent for ACTION_IMAGE_CAPTURE

柔情痞子 提交于 2021-02-07 11:55:40

问题


Device: Emulator pixel 3a - Android 11

Code:

    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);

When using:

targetSdkVersion 30
compileSdkVersion 30

listCam size is 0

and when changing to:

compileSdkVersion 29

listCam size is 1 - as it should be.

Using the following code:

    val captureIntent = Intent(MediaStore.ACTION_IMAGE_CAPTURE)
    baseActivity.startActivity(captureIntent)

Works fine and shows the camera app.

Any idea why queryIntentActivities is not returning the camera intent?

Thanks!


回答1:


Android 11 changes how apps can query and interact with other apps.

From the docs:

The PackageManager methods that return results about other apps, such as queryIntentActivities(), are filtered based on the calling app's <queries> declaration.

So you need to declare <queries> in your AndroidManifest.xml:

<manifest package="com.example">
    <queries>
        <intent>
            <action android:name="android.media.action.IMAGE_CAPTURE" />
        </intent>
    </queries>
    ...
</manifest>



回答2:


My solution for Android 11, for getting ResolveInfo list.

  • When we scan only by MediaStore.ACTION_IMAGE_CAPTURE filter then we will get only One! application record - System default camera app.
  • For using additional camera apps we need to specify each application by package name, and provide it with setPackage() call - and then queryIntentActivities works correctly, even in Android R

The full solution is below:

/**
 * 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);
}

Of course in manifest file we should add these lines (as described in accepted answer)

<queries>
        <intent>
            <action android:name="android.media.action.IMAGE_CAPTURE" />
        </intent>
</queries>


来源:https://stackoverflow.com/questions/63246442/android-11-r-return-empty-list-when-querying-intent-for-action-image-capture

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!