在 Android 12 上实施 STILL_IMAGE_CAPTURE_SECURE

Implementing STILL_IMAGE_CAPTURE_SECURE on Android 12

我目前正在尝试为我的相机应用实施 STILL_IMAGE_CAPTURE_SECURE 意图。 (在安全模式下双击电源按钮时触发的意图)

我在清单文件中添加了 WAKE_LOCK 和 DISABLE_KEYGUARD 权限,并将 showOnLockScreen 和 showOnLockScreen 设置为 true activity。

<uses-permission android:name="android.permission.WAKE_LOCK" />
<uses-permission android:name="android.permission.DISABLE_KEYGUARD" />

<!-- [...] -->

<activity
            android:name=".ui.activities.SecureMainActivity"
            android:taskAffinity=".ui.activities.SecureMainActivity"
            android:label="@string/app_name"
            android:configChanges="orientation|keyboardHidden|screenSize"
            android:windowSoftInputMode="stateAlwaysHidden|adjustPan"
            android:screenOrientation="nosensor"
            android:showWhenLocked="true"
            android:showOnLockScreen="true"
            android:excludeFromRecents="true"
            android:exported="true">

            <intent-filter>
                <action android:name="android.media.action.STILL_IMAGE_CAMERA_SECURE" />
                <category android:name="android.intent.category.DEFAULT" />
            </intent-filter>

        </activity>

我们已经在 Android 11 (AOSP) 上测试了我们的应用程序,并在锁定屏幕中双击打开相机 fine/as 预计在那里(我们的应用程序与实现此意图的其他应用程序一起可见例如 Intent Chooser 中的 Google Camera)但是 Android 12 (AOSP) Google Camera 直接被触发(这隐含地意味着我们的应用没有被考虑用于 Intent) .

如果 Google 没有安装摄像头,则不会触发任何内容。

什么可能会导致这种意外行为?

根据 'How double-click power launches the camera' guide:

  • Note that starting in Android 12, as required by some OEMs, if the special string resource config_cameraGesturePackage is nonempty, this will be treated as a package name to be added to the insecure camera intent, constraining the invocation to that single app and typically preventing implicit intent resolution. This package must be on the device or the camera gesture will no longer work properly.

commit that added this code 中所述:

Using an implicit intent at the moment of picture-taking usually goes unnoticed. But immediately after installing a new camera, this behavior becomes incredibly frustrating to users as they are presented with a puzzling resolver dialog (or in the case of the secure camera, the authenticator). And if, at this moment, the user chooses to make one of the options a default, it's almost impossible to figure out how to change this setting.

As a result, many OEMs simply hardcode the camera gesture to launch a specific preinstalled camera, but this is poorly supported by AOSP, leading to duplicate implementations and bugs. This patch routes all camera intents in System UI through a single utility class, creating a convenient spot to insert a resource that contains the OEM's default preinstalled camera app.

它继续解释如何确定执行此操作时触发的意图:

Bugreport/dumpsys output to look for:

$ adb shell dumpsys activity service com.android.systemui | grep -C3 'Camera gesture' | tail -3
    Camera gesture intents:
      Insecure camera: Intent { act=android.media.action.STILL_IMAGE_CAMERA }
      Secure camera: Intent { act=android.media.action.STILL_IMAGE_CAMERA_SECURE flg=0x800000 }
      Override package: null

通过查看“覆盖包”,您可以查看特定相机包(例如与 Google 相机应用关联的相机包)是否被定义为唯一可以处理此意图的相机。如果是这种情况,那么预计您的应用将永远无法在该特定设备上处理该意图。

当然,如果您是 OEM 并在您自己的设备上控制资源覆盖,您可能希望更新 config_cameraGesturePackage 字符串资源以指向您的自定义相机应用程序,或者如果需要将其留空允许任何相机应用程序处理此操作。