Android 11 (R) return 查询 ACTION_IMAGE_CAPTURE 的意图时为空列表
Android 11 (R) return empty list when querying intent for ACTION_IMAGE_CAPTURE
设备:模拟器像素 3a - Android11
代码:
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);
使用时:
targetSdkVersion 30
compileSdkVersion 30
listCam 大小为 0
当更改为:
compileSdkVersion 29
listCam 大小为 1 - 应该是。
使用以下代码:
val captureIntent = Intent(MediaStore.ACTION_IMAGE_CAPTURE)
baseActivity.startActivity(captureIntent)
工作正常并显示相机应用程序。
知道为什么 queryIntentActivities 不返回相机意图吗?
谢谢!
Android 11 改变了应用查询和与其他应用交互的方式。
来自docs:
The PackageManager
methods that return results about other apps,
such as queryIntentActivities()
, are filtered based on the calling
app's <queries>
declaration.
因此您需要在 AndroidManifest.xml
中声明 <queries>
:
<manifest package="com.example">
<queries>
<intent>
<action android:name="android.media.action.IMAGE_CAPTURE" />
</intent>
</queries>
...
</manifest>
我对 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);
}
当然在清单文件中我们应该添加这些行(如接受的答案中所述)
<queries>
<intent>
<action android:name="android.media.action.IMAGE_CAPTURE" />
</intent>
</queries>
如果您的应用在 targetSdkVersion 30
[上 运行,packageManager.queryIntentActivities(intent, 0)
将 return 一个 EMPTY 列表=45=]
要解决此问题,您必须在清单中使用 <queries>
,因为 queryIntentActivities()
会根据调用应用程序的声明进行过滤。
修复图像捕获 + 图像上传以与 Android“范围存储”一起使用
该问题可能与新包可见性 (https://developer.android.com/about/versions/11/privacy/package-visibility) 有关。
在所有更新后(至少 Android Studio 4.1)尝试在您的清单中添加显示您的应用程序需要执行的操作。
就我而言,当我添加时问题就消失了
IMAGE_CAPTURE 用于 CAMERA,GET_CONTENT 用于 GALLERY(如果需要视频,获取文件更改 mimeType),PICK for GALLERY(如果你想要视频,应该改变 mimetype)
画廊的选择(如果有人有其他图片浏览器)
您还可以检查 logcat 您必须添加哪些查询(应包含“已阻止”或“无权限”。
错误是因为 ImagePickerModule
当您在 Intent 中没有 resolveActivity
returns null
的权限时(您可以评论它以检查 startActivityForResult
中更好的错误)
在AndroidManifest.xml
中添加<query>
<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>
@saurabh-thorat 的查询是正确的。但我发现,即使你想要所有,你仍然需要添加一个数据标签才能让它与所有 mime 类型一起工作(或者至少我在我的 react-native 应用程序中是这样)。所以对于 mime 类型的操作应该如下所示(例如:view/send/open):
<manifest package="com.example">
<queries>
<intent>
<action android:name="android.intent.action.VIEW" />
<data android:mimeType="*/*" />
</intent>
</queries>
...
</manifest>
设备:模拟器像素 3a - Android11
代码:
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);
使用时:
targetSdkVersion 30
compileSdkVersion 30
listCam 大小为 0
当更改为:
compileSdkVersion 29
listCam 大小为 1 - 应该是。
使用以下代码:
val captureIntent = Intent(MediaStore.ACTION_IMAGE_CAPTURE)
baseActivity.startActivity(captureIntent)
工作正常并显示相机应用程序。
知道为什么 queryIntentActivities 不返回相机意图吗?
谢谢!
Android 11 改变了应用查询和与其他应用交互的方式。
来自docs:
The
PackageManager
methods that return results about other apps, such asqueryIntentActivities()
, are filtered based on the calling app's<queries>
declaration.
因此您需要在 AndroidManifest.xml
中声明 <queries>
:
<manifest package="com.example">
<queries>
<intent>
<action android:name="android.media.action.IMAGE_CAPTURE" />
</intent>
</queries>
...
</manifest>
我对 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);
}
当然在清单文件中我们应该添加这些行(如接受的答案中所述)
<queries>
<intent>
<action android:name="android.media.action.IMAGE_CAPTURE" />
</intent>
</queries>
targetSdkVersion 30
[上 运行,packageManager.queryIntentActivities(intent, 0)
将 return 一个 EMPTY 列表=45=]
要解决此问题,您必须在清单中使用 <queries>
,因为 queryIntentActivities()
会根据调用应用程序的声明进行过滤。
修复图像捕获 + 图像上传以与 Android“范围存储”一起使用
该问题可能与新包可见性 (https://developer.android.com/about/versions/11/privacy/package-visibility) 有关。 在所有更新后(至少 Android Studio 4.1)尝试在您的清单中添加显示您的应用程序需要执行的操作。
就我而言,当我添加时问题就消失了 IMAGE_CAPTURE 用于 CAMERA,GET_CONTENT 用于 GALLERY(如果需要视频,获取文件更改 mimeType),PICK for GALLERY(如果你想要视频,应该改变 mimetype) 画廊的选择(如果有人有其他图片浏览器)
您还可以检查 logcat 您必须添加哪些查询(应包含“已阻止”或“无权限”。
错误是因为 ImagePickerModule
当您在 Intent 中没有 resolveActivity
returns null
的权限时(您可以评论它以检查 startActivityForResult
中更好的错误)
在AndroidManifest.xml
<query>
<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>
@saurabh-thorat 的查询是正确的。但我发现,即使你想要所有,你仍然需要添加一个数据标签才能让它与所有 mime 类型一起工作(或者至少我在我的 react-native 应用程序中是这样)。所以对于 mime 类型的操作应该如下所示(例如:view/send/open):
<manifest package="com.example">
<queries>
<intent>
<action android:name="android.intent.action.VIEW" />
<data android:mimeType="*/*" />
</intent>
</queries>
...
</manifest>