如果为应用授予 START_ACTIVITIES_FROM_BACKGROUND(Android 11+),则从前台服务启动相机

Start camera from foreground service if START_ACTIVITIES_FROM_BACKGROUND granted for the app (Android 11+)

我的应用程序进程在收到 BOOT_COMPLETED 操作时启动前台服务

该服务用于使用摄像头和微型视频录制(仪表板摄像头应用程序)phone。

要在 Android 11+ 上从前台服务启动相机,必须满足其中一个条件(免除从前台服务启动 camera/micro 的限制)https://developer.android.com/guide/components/foreground-services#bg-access-restriction-exemptions

我可以使用的唯一例外是:

The service is started by an app that has the START_ACTIVITIES_FROM_BACKGROUND privileged permission.

这个不需要用户进行任何交互,用户只希望在他开始开车时自动开始录制视频,他不希望手动使应用可见或从通知开始录制,他不关心这一切,没关系,现在是 2021 年,可以自动完成这些事情,但是感谢 Google 在 2021 年有这样的限制,是的,我们应该关心私人个人数据的安全一个用户,但他们可以添加 BACKGROUND_CAMERABACKGROUND_RECORD_AUDIO 权限并在 Google Play 控制台上进行人工审核,就像他们对 ACCESS_BACKGROUND_LOCATION

所做的那样

如果我理解正确以获得START_ACTIVITIES_FROM_BACKGROUND许可,我必须满足其中一个条件(免除从后台启动活动的限制)https://developer.android.com/guide/components/activities/background-starts#exceptions

所以我选择了 SYSTEM_ALERT_WINDOW 权限,因为如果它之前被用户授予,则不需要用户进行任何交互,应用程序可以从后台启动 activity。这个可以授予 Intent(Settings.ACTION_MANAGE_OVERLAY_PERMISSION)

那么我现在是否获得 START_ACTIVITIES_FROM_BACKGROUND 许可?我不明白...

如果是,那么我可以在从某些后台操作启动的前台服务中使用摄像头

但还是

fun isCameraAllowedForPackage(context: Context): Boolean {
    return if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q) {
        val manager = context.getSystemService(Context.APP_OPS_SERVICE) as AppOpsManager
        val res = manager.unsafeCheckOpNoThrow(
            AppOpsManager.OPSTR_CAMERA,
            Process.myUid(),
            context.packageName
        )
         res == AppOpsManager.MODE_ALLOWED
    } else {
        true
    }
}

returns false 我的三星 S10 (Android 11) 在我尝试使用相机之前处于前台服务

为什么?

如果我至少让应用程序可见一次(启动一个 activity f 应用程序),那么前台服务可以启动相机(这种方法 returns true),即使屏幕phone 的已关闭

我也尝试使用 Pixel Emulator (Android 11),这个有不同的行为 - 应用程序可以通过在后台启动的前台服务开始使用相机,即使没有 SYSTEM_ALERT_WINDOW 允许。所以我不需要任何 https://developer.android.com/guide/components/activities/background-starts#exceptions

我不明白。模拟器基本上不遵循这些规则。

有关行车记录仪应用问题的更多信息

最近我收到了来自我的应用程序用户的下一条消息的报告

android.hardware.camera2.CameraAccessException: CAMERA_DISABLED (1): validateClientPermissionsLocked:1426: Caller "MY_APP_PACKAGE_NAME" (PID 10300, UID 29860) cannot open camera "0" when sensor privacy is enabled

Error happened during using Camera. android.hardware.camera2.CameraAccessException: CAMERA_DISABLED (1): connectHelper:2198: Camera "2" disabled by policy

android.hardware.camera2.CameraAccessException: CAMERA_DISABLED (1): validateClientPermissionsLocked:1416: Caller "MY_APP_PACKAGE_NAME" (PID 10376, UID 25653) cannot open camera "0" from background (calling UID 10376 proc state 8) App catches such errors when it tries to open the camera

用户可以从 activity/notification/widget/floating window 手动开始录制,或者可以根据 charging/Bluetooth/etc 事件(在前台服务中注册广播事件进行录制)自动开始录制

如果isCameraAllowedForPackage() returns false,前台服务不会开始录制,没办法,所以在这种情况下returns true然后应用程序无法打开相机并出现 CAMERA_DISABLED 错误,我不明白。

我向用户询问了这个问题,他们回答说在 charging/Bluetooth 事件上自动录制 starts/stops 时,有时可能会发生这种情况(并非总是如此,他们没有为相机设置任何政策)。所以当然他们phones上的应用程序通常可以打开相机,它是允许使用的,似乎有时愚蠢的操作系统会阻止应用程序使用相机,我不明白为什么,没有我之前提到的限制中有关此案例的任何信息。因此,对于应用程序可以正常运行一段时间的用户,他们至少打开了应用程序的 activity 一次(在三星 Android 11+ 上,他们必须这样做),因此前台服务 100%使用相机的许可,但过了一段时间后他们仍然发生了这个错误。

这是一个不同的问题。如果我的应用程序进程不允许这样做,那么我会收到这样的错误

https://developer.android.com/guide/components/foreground-services#test-restrictions

无论如何,正如我之前提到的,我有一种方法可以在打开应用程序之前检查是否允许将相机用于我的应用程序

这有很多问题。 (不同制造商的)电话表现不同。 使用相机过程中的一些意外异常。

所以基本上即使考虑了所有因素,例如,用户启动了应用程序的启动 activity,这启动了前台服务,在这种情况下,前台现在可以使用相机,但是当相同的前台服务 运行 一段时间

时,打开相机仍然会出现一些问题

So do I have now START_ACTIVITIES_FROM_BACKGROUND permission granted or not?

没有。该权限在框架中定义为:

    <permission android:name="android.permission.START_ACTIVITIES_FROM_BACKGROUND"
        android:protectionLevel="signature|privileged|vendorPrivileged|oem|verifier" />

要保留它,您需要在您的应用程序清单中请求它,并且您的应用程序需要是固件构建的一部分(或者由已获得 root 权限的设备的用户安装在特权分区上)。

If I understood correctly to get START_ACTIVITIES_FROM_BACKGROUND permission I must have one of the conditions must be met (Exemptions from the restrictions to starting activities from the background) https://developer.android.com/guide/components/activities/background-starts#exceptions

该页面未引用该权限。