如何在Android 11中使用前台服务从另一个前台服务打开相机?

4

我现在正在测试Android 11中前台服务下的相机开启,但是我遇到了新的Android 11限制问题:https://developer.android.com/guide/components/foreground-services

伪代码:

//Service1 is started by JobScheduler.
class Service1 extends Service {
    ...
    startForeground(ID_OF_SERVICE1_NOTIFICATION, getService1Notification())
    ...
    //Run another foreground service with open camera
    Intent i = new Intent(getApplicationContext(), Service2.class)
    ContextCompat.startForegroundService(context, i)
    ...
}

class Service2 extends Service {
    ...
    startForeground(ID_OF_SERVICE2_NOTIFICATION, getService2Notification(), ServiceInfo.FOREGROUND_SERVICE_TYPE_MANIFEST);
    openCamera() // <-- Policy exception
    ...
}

使用 JobScheduler 启动 Service1,并使用 startForeground() 显示通知给用户。Service1 可以使用 ContextCompat.startForegroundService() 启动 Service2,也可以向用户显示通知。 Service2 打开相机。用户始终可以看到通知。

清单文件已编辑:

<service android:name=".service.Service2"
    android:foregroundServiceType="camera|microphone"
    android:stopWithTask="false"/> 

使用 FOREGROUND_SERVICE_TYPE_MANIFEST 标志在 Service2 中编辑 starForeground() 方法,它是一个特殊的值,表示使用清单文件中设置的所有类型。

Logcat 的结果:

后台启动的前台服务无法访问位置/相机/麦克风:服务 com.example.test/.service.Service2

还尝试了 FOREGROUND_SERVICE_TYPE_CAMERA|FOREGROUND_SERVICE_TYPE_MICROPHONE

我希望保留用户自动启动相机的功能,有什么办法吗?


你真的需要两个服务吗?“有没有其他方法?”——除了使用FOREGROUND_SERVICE_TYPE_MANIFEST,你尝试过使用FOREGROUND_SERVICE_TYPE_CAMERA|FOREGROUND_SERVICE_TYPE_MICROPHONE吗? - CommonsWare
是的。第一个服务检查用户定义的条件,只有在满足条件时才启动第二个服务。FOREGROUND_SERVICE_TYPE_CAMERA|FOREGROUND_SERVICE_TYPE_MICROPHONE 的行为与 FOREGROUND_SERVICE_TYPE_MANIFEST 相同。我已经尝试过了。 - t0m
首先,服务会检查用户定义的条件,只有当这些条件得到满足时才会启动第二个服务。就我而言,这似乎可以是一个服务,而不是两个。 - CommonsWare
这会有助于解决问题吗?(还有很多其他逻辑。)最好将其分开。 - t0m
这会有助于解决问题吗?很可能。你的问题似乎源于服务A试图启动服务B。如果确实没有服务B,也许你的问题就解决了。 - CommonsWare
显示剩余2条评论
1个回答

1
据我所知,自从 Android 11 开始,如果应用程序在启动过程中对用户不可见,则无法通过前台服务 自动 启动相机。用户必须与应用程序进行交互才能使用相机。根据文档,以下是被认为是与应用程序交互的方式,而不需要打开活动:
  • 系统组件启动服务。
  • 通过与应用小部件交互启动服务。
  • 通过与通知交互启动服务。[注意:必须要有交互!仅显示通知是不够的]
  • 作为来自不同可见应用程序的 PendingIntent 启动服务。
  • 由运行在设备所有者模式下的设备策略控制器的应用程序启动服务。
  • 由提供 VoiceInteractionService 的应用程序启动服务。由具有 START_ACTIVITIES_FROM_BACKGROUND 特权权限的应用程序启动服务。

如果应用程序自应用程序进程启动以来对用户不可见,该如何检查?在Android 11中是否有任何新方法来检查是否有用户交互?附:在我的情况下需要 https://stackoverflow.com/questions/67572259/widget-cant-start-a-service-on-device-boot-on-android-11-until-some-activity-is - user924
1
有一种方法是通过AppOpsManager类。我在另一个帖子中详细回答了你的问题,希望能有所帮助! - Balazs Banyai
1
嗨@BalazsBanyai,你能分享一下这个线程吗? - Shashank Srivastava
https://stackoverflow.com/a/67590163/2764357 - Balazs Banyai

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接