ACTION_IMAGE_CAPTURE:如何在 android-11 及更高版本中将不同的相机应用程序列入白名单?

发布于 2025-01-11 07:25:21 字数 5594 浏览 0 评论 0原文

我的 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

Manifest

<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

详细信息,请参阅 https://github.com/k3b/CameraFolder/issues/5

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 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。
列表为空,暂无数据
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文