ACTION_IMAGE_CAPTURE:如何在 android-11 及更高版本中将不同的相机应用程序列入白名单?
我的 Android 应用程序使用 ACTION_IMAGE_CAPTURE
要求已安装的相机应用程序为我的应用程序拍照。 如果安装了多个相机应用程序,Android 会显示一个相机选择器,用户可以在其中进行选择 哪个相机应用程序应该拍摄照片。
自 android-11 起,仅预装摄像头可用。
要解决此问题,我需要明确将其他相机应用程序列入白名单。
我的 Android 应用程序已关注 Android 11 (R) 返回查询 ACTION_IMAGE_CAPTURE 的意图时为空列表并且 https://commonsware.com/blog/ 2020/08/16/action-image-capture-android-r.html 将适用于 android-11 及更高版本的附加相机应用 OpenCamera 列入白名单。
在 android-10 设备上执行我的应用程序时,一切都按预期工作。
在 android-11 设备上执行我的应用程序时,我得到 ActivityNotFoundException
知道我缺少什么吗?
这是源代码(来自 GetDocument2CameraActivity )
private static final String[] AO11_ADDITIONAL_KNOWN_CAMERA_APPS = new String[] {
"net.sourceforge.opencamera", // https://sourceforge.net/p/opencamera/code
};
private void onRequestPhoto() {
this.resultPhotoUri = createSharedUri();
Intent intent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE)
.putExtra(MediaStore.EXTRA_OUTPUT, this.resultPhotoUri)
.putExtra(MediaStore.EXTRA_MEDIA_TITLE, getString(R.string.label_select_picture))
.setFlags(Intent.FLAG_GRANT_WRITE_URI_PERMISSION );
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.R) {
addInitialIntents(intent, AO11_ADDITIONAL_KNOWN_CAMERA_APPS);
}
// start the image capture Intent
startActivityForResult(intent, ACTION_REQUEST_IMAGE_CAPTURE);
//!!! startActivityForResult throws ActivityNotFoundException
}
private void addInitialIntents(Intent baseIntent, String... packageIdCandidates) {
PackageManager packageManager = this.getPackageManager();
List<Intent> whitelist = new ArrayList<>();
for (String packageId : packageIdCandidates) {
Intent candidate = new Intent(baseIntent).setPackage(packageId);
List<ResolveInfo> resolveInfos = packageManager.queryIntentActivities(candidate, 0);
if (!resolveInfos.isEmpty()) {
Log.i(TAG, "known camera app added '" + packageId + "' = " + resolveInfos.get(0));
// this code is executed: logcat contains
// known camera app added 'net.sourceforge.opencamera' = ResolveInfo{37e3009 net.sourceforge.opencamera/.MainActivity m=0x108000}
whitelist.add(candidate);
}
}
if (!whitelist.isEmpty()) {
baseIntent.putExtra(Intent.EXTRA_INITIAL_INTENTS, whitelist.toArray(new Intent[0]));
}
}
build.xml 具有compileSdk 31
<queries>
<intent>
<action android:name="android.media.action.IMAGE_CAPTURE" />
</intent>
</queries>
执行 logcat 时 包含包含
03-03 12:47:09.380 14898 14898 I k3b.camerafolder: known camera app added 'net.sourceforge.opencamera' = ResolveInfo{37e3009 net.sourceforge.opencamera/.MainActivity m=0x108000} ... --------- beginning of crash 03-03 12:47:09.388 14898 14898 E AndroidRuntime: FATAL EXCEPTION: main 03-03 12:47:09.388 14898 14898 E AndroidRuntime: Process: de.k3b.android.camerafolder.debug, PID: 14898 03-03 12:47:09.388 14898 14898 E AndroidRuntime: java.lang.RuntimeException: Unable to start activity ComponentInfo{de.k3b.android.camerafolder.debug/de.k3b.android.camerafolder.GetDocument2CameraActivity}: android.content.ActivityNotFoundException: No Activity found to handle Intent { act=android.media.action.IMAGE_CAPTURE flg=0x3 clip={text/uri-list hasLabel(0) {U(content)}} (has extras) } 03-03 12:47:09.388 14898 14898 E AndroidRuntime: at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:3635) ... 03-03 12:47:09.388 14898 14898 E AndroidRuntime: at android.app.Activity.startActivityForResult(Activity.java:5361) 03-03 12:47:09.388 14898 14898 E AndroidRuntime: at de.k3b.android.camerafolder.GetDocument2CameraActivity.onRequestPhoto(GetDocument2CameraActivity.java:126) 03-03 12:47:09.388 14898 14898 E AndroidRuntime: at de.k3b.android.camerafolder.GetDocument2CameraActivity.onCreate(GetDocument2CameraActivity.java:86) 03-03 12:47:09.388 14898 14898 E AndroidRuntime: at android.app.Activity.performCreate(Activity.java:8050) 03-03 12:47:09.388 14898 14898 E AndroidRuntime: at android.app.Activity.performCreate(Activity.java:8030) 03-03 12:47:09.388 14898 14898 E AndroidRuntime: at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1329) 03-03 12:47:09.388 14898 14898 E AndroidRuntime: at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:3608) 03-03 12:47:09.388 14898 14898 E AndroidRuntime: ... 12 more
My android app uses ACTION_IMAGE_CAPTURE
to ask an installed camera-app to take a photo for my app.
If there are more than one camera apps installed android presents a camera chooser where the user can choose
which camera app should take the shot.
Since android-11 only the preinstalled camera is available.
To work around this i need to explicitly whitelist additional camera apps.
My android app followed
Android 11 (R) return empty list when querying intent for ACTION_IMAGE_CAPTURE and
https://commonsware.com/blog/2020/08/16/action-image-capture-android-r.html
to whitelist the additional camera app OpenCamera for android-11 and later.
When executing my app on a android-10 device all works as expected.
When executing my app on a android-11 device i get ActivityNotFoundException
Any idea what i am missing?
Here is the sourcecode (from GetDocument2CameraActivity )
private static final String[] AO11_ADDITIONAL_KNOWN_CAMERA_APPS = new String[] {
"net.sourceforge.opencamera", // https://sourceforge.net/p/opencamera/code
};
private void onRequestPhoto() {
this.resultPhotoUri = createSharedUri();
Intent intent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE)
.putExtra(MediaStore.EXTRA_OUTPUT, this.resultPhotoUri)
.putExtra(MediaStore.EXTRA_MEDIA_TITLE, getString(R.string.label_select_picture))
.setFlags(Intent.FLAG_GRANT_WRITE_URI_PERMISSION );
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.R) {
addInitialIntents(intent, AO11_ADDITIONAL_KNOWN_CAMERA_APPS);
}
// start the image capture Intent
startActivityForResult(intent, ACTION_REQUEST_IMAGE_CAPTURE);
//!!! startActivityForResult throws ActivityNotFoundException
}
private void addInitialIntents(Intent baseIntent, String... packageIdCandidates) {
PackageManager packageManager = this.getPackageManager();
List<Intent> whitelist = new ArrayList<>();
for (String packageId : packageIdCandidates) {
Intent candidate = new Intent(baseIntent).setPackage(packageId);
List<ResolveInfo> resolveInfos = packageManager.queryIntentActivities(candidate, 0);
if (!resolveInfos.isEmpty()) {
Log.i(TAG, "known camera app added '" + packageId + "' = " + resolveInfos.get(0));
// this code is executed: logcat contains
// known camera app added 'net.sourceforge.opencamera' = ResolveInfo{37e3009 net.sourceforge.opencamera/.MainActivity m=0x108000}
whitelist.add(candidate);
}
}
if (!whitelist.isEmpty()) {
baseIntent.putExtra(Intent.EXTRA_INITIAL_INTENTS, whitelist.toArray(new Intent[0]));
}
}
build.xml has compileSdk 31
Manifest contains
<queries>
<intent>
<action android:name="android.media.action.IMAGE_CAPTURE" />
</intent>
</queries>
when executing logcat contains
03-03 12:47:09.380 14898 14898 I k3b.camerafolder: known camera app added 'net.sourceforge.opencamera' = ResolveInfo{37e3009 net.sourceforge.opencamera/.MainActivity m=0x108000} ... --------- beginning of crash 03-03 12:47:09.388 14898 14898 E AndroidRuntime: FATAL EXCEPTION: main 03-03 12:47:09.388 14898 14898 E AndroidRuntime: Process: de.k3b.android.camerafolder.debug, PID: 14898 03-03 12:47:09.388 14898 14898 E AndroidRuntime: java.lang.RuntimeException: Unable to start activity ComponentInfo{de.k3b.android.camerafolder.debug/de.k3b.android.camerafolder.GetDocument2CameraActivity}: android.content.ActivityNotFoundException: No Activity found to handle Intent { act=android.media.action.IMAGE_CAPTURE flg=0x3 clip={text/uri-list hasLabel(0) {U(content)}} (has extras) } 03-03 12:47:09.388 14898 14898 E AndroidRuntime: at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:3635) ... 03-03 12:47:09.388 14898 14898 E AndroidRuntime: at android.app.Activity.startActivityForResult(Activity.java:5361) 03-03 12:47:09.388 14898 14898 E AndroidRuntime: at de.k3b.android.camerafolder.GetDocument2CameraActivity.onRequestPhoto(GetDocument2CameraActivity.java:126) 03-03 12:47:09.388 14898 14898 E AndroidRuntime: at de.k3b.android.camerafolder.GetDocument2CameraActivity.onCreate(GetDocument2CameraActivity.java:86) 03-03 12:47:09.388 14898 14898 E AndroidRuntime: at android.app.Activity.performCreate(Activity.java:8050) 03-03 12:47:09.388 14898 14898 E AndroidRuntime: at android.app.Activity.performCreate(Activity.java:8030) 03-03 12:47:09.388 14898 14898 E AndroidRuntime: at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1329) 03-03 12:47:09.388 14898 14898 E AndroidRuntime: at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:3608) 03-03 12:47:09.388 14898 14898 E AndroidRuntime: ... 12 more
for details see https://github.com/k3b/CameraFolder/issues/5
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论