问题
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 asqueryIntentActivities()
, 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