Android 12 - 前台服务启动限制

24
我正在开发一个SDK,需要在后台启动startForeground服务。因为它使用后台位置和蓝牙相关的任务。如果应用程序被终止,监视将在后台执行。这就是为什么我使用前台服务的原因。有一个条件可以从后台启动前台服务。
目前,我的SDK使用Service来处理此工作。但是从Android 12开始,不支持从后台启动服务。
我正在尝试从后台启动服务,下面的异常会抛出。
ForegroundServiceStartNotAllowedException: Service.startForeground() not allowed due to mAllowStartForeground false

我该如何使用WorkManager来解决这个问题?我的所有处理都由Service类完成,我该如何将Service对象传递给Worker类并在Worker类中启动此作业。
实际上,我的项目基于信标技术。信标信号用于向用户显示不同的推荐内容。
在我的当前实现中,如果应用程序被用户杀死,并且接受前台服务,则SDK将在后台运行。检测信标并提供适当的操作。
我的实现是,如果应用程序使用前台服务“关闭”初始化我的SDK,然后稍后,当应用程序处于后台并尝试从后台启动前台服务时,会引发此异常。前台服务相关的决策由服务器端API进行。我定期检查服务器端值是否更改,如果值更改,则在SDK中反映更改的操作。

2
https://developer.android.com/about/versions/12/foreground-services#java - Majid Ali
https://medium.com/androiddevelopers/using-workmanager-on-android-12-f7d483ca0ecb - tyczj
2
我正在开发一个SDK,需要从后台启动前台服务。为什么需要这样做?为什么需要使用前台服务,并且为什么需要从后台开始? - CommonsWare
因为它使用后台位置和蓝牙相关的功能。如果应用程序被杀死,监控将在后台进行。这就是为什么我正在使用前台服务的原因。有一个条件从后台启动前台服务。 - jerald jacob
1
我只在用户点击按钮时从我的应用程序仪表板启动前台服务并显示通知。而且我在Android 12上也遇到了同样的问题。我只跟踪位置和用户活动。希望这些信息能提供更多帮助。到目前为止,我只有几次崩溃,但仍然让我担心。 - Pieter van der Vyver
你可能希望完全放弃使用 Android Service 构造来处理这些用例。可以查看这里的一种替代方法 - davidgyoung
3个回答

8

世界上没有人能给你答案。所有这些限制的想法是,作为开发人员,我们需要优化我们的应用程序。因此,如果您无法做到这一点,很可能意味着您需要优化工作方式。为了实现这一点,您需要提供更多关于您接收到的事件的详细信息,您的使用情况等。

https://developer.android.com/about/versions/12/foreground-services#cases-fgs-background-starts-allowed

正如您所看到的,关于以下异常信息:

您的应用程序接收到需要 BLUETOOTH_CONNECT 或 BLUETOOTH_SCAN 权限的蓝牙广播。

但是,您的问题中没有提到您的使用情况可能与此有关。

另外,我不明白应用程序如何被终止,但您仍然在后台工作。

如果您想要持续做某些事情,为什么还需要在后台时触发事件。只需在用户打开应用程序时启动服务并保持运行即可。

您也可以“黑客”它,并要求用户将您从电池优化中移除。

https://developer.android.com/training/monitoring-device-state/doze-standby#support_for_other_use_cases


Yavor Mitev谢谢您的回复。我刚刚更新了我的问题,并添加了一些关于我的项目的更多信息,请看一下。 - jerald jacob

6

以前我们使用 Service 来运行后台任务。但由于 Android 12 - 前台服务启动限制,我们将无法在 Android 12+ 上调用 Service 来执行后台任务。

从现在开始,从目标 SDK 31 开始,只有在应用程序处于前台时才能调用 Service。当应用程序关闭或进入后台时,使用 startForegroundService 调用 Service 将导致 ForegroundServiceStartNotAllowedException 异常。

因此,为了执行后台任务,我们需要使用 Worker 而非 Service。请参考这个答案了解其实现方式。希望可以帮助到您。此外,可以参考下面的链接,了解需要进行哪些更改。

  1. Android 12 行为变更

  2. 工作请求


1
谢谢更新。不幸的是,我们不能使用Worker类代替Service。是否有可能使用Service的其他解决方案?请提出建议。 - jerald jacob
没有Worker,我认为没有其他选择。但是作为一种解决方法,您可以将目标SDK设置为30,而不是31,以使用Service。无论如何,在未来,您肯定需要实现Worker而不是Service,以便专注于未来的发布。如果您发现任何其他实现选项,请告诉我们。这对许多人都会有帮助 :) - niranj1997
3
@niranj1997,虽然这可能是许多应用程序的合适解决方法,但有时Worker并不适用(例如长时间运行的不确定任务,如跟踪跑步)。尽管如此,Google记录了豁免情况,却选择忽略它们。这显然是Android 12中的一个错误,从后台启动服务的唯一方法是针对30进行目标设置。 - warbi
@warbi。所以你可能是对的!由于Android 12中的一个错误,他们会将其作为“服务”限制进行提及。因此,正如你所说,目前更好的解决方法是使用Target SDK 30而不是31来利用“服务”。并且在Android团队修复此问题之前,等待他们将目标SDK 31作为在Google Play上发布应用程序的强制要求。希望他们能尽快解决这个问题,让开发人员的生活变得更轻松! :) - niranj1997
我已经在前台模式下使用了Worker,但仍然遇到同样的问题。我的应用程序目标SDK仍为11,计划很快升级,但不确定是否能解决问题。 - Himanshu Mori

2
根据官方文档,如果您的应用程序执行以下操作之一,则应能够启动 FGS:

您的应用程序接收到需要 BLUETOOTH_CONNECT 或 BLUETOOTH_SCAN 权限的蓝牙广播。

或者

您的应用程序接收到与地理围栏或活动识别转换相关的事件。

这两个似乎是您使用情况的不错选择,至少我是这样理解的。

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