我可以在前台服务中使用 Android Beacon Library,即使是在 Android 8 (Oreo) 上吗?

Can I use Android Beacon Library in foreground service, even on Android 8 (Oreo)?

我想达到的目标

我正在为一个购物中心开发一个应用程序,其中安装了大量的信标,彼此之间的距离不太远(假设距离约为 20 米)。
当用户走进这个商场时,即使没有打开应用程序,应用程序也需要不断扫描信标。当检测到信标时,我将查询服务器以询问我是否需要以及向用户推送什么本地通知。

我打算做什么

我最初的计划是在 onStartCommand() 中创建一个 Service、returns START_STICKY,以确保即使应用程序被终止,服务也会自行重启由任务管理器。

Service 将继续扫描信标。

其实这是我同事现有的做法。根据这位同事的说法,该服务几乎是在应用程序被任务管理器杀死后立即启动的。

问题

但是很快我发现这种做法是有问题的
上述方法现在有 2 个主要问题:

我的下一个计划

虽然我知道JobScheduler可以用来代替Service,也是existing approach of Android Beacon Library,但是每15-25分钟扫描一次绝对不能满足我的要求,beacon离得很近因此需要经常扫描信标。

于是我想出了另一个方案:

  1. 使用Android信标库运行背景检测
  2. 曾经 已检测到过滤器列表中的第一个信标,启动前台 服务(即使在 Android 8 中也不会被杀死) 持续扫描信标
  3. 当filter中的所有beacon都退出后,停止上述前台服务。 Android信标 图书馆应恢复其背景检测状态。

这种方法的目的是:

  1. 根据他们的 documentation
  2. ,利用 Android Beacon Library 的后台检测可以节省电量
  3. 放弃 Android Beacon Library 对 Android 8 的处理,因为其内置的长扫描间隔限制
  4. 扫描甚至在 Android 8 上继续,因为我要使用前台服务

我的主要问题

通过阅读文档,我已经知道如何在后台扫描信标。
但是如何在前台服务中使用 Android Beacon Library 进行扫描呢?
另外,您在上述做法中有没有发现什么问题/您有更好的建议来实现这样的要求吗?

我的另一个问题

事实上,根据 ,后台服务会在应用程序被终止后 5 分钟 启动。
但是通过在 ServiceonStartCommand() 中返回 START_STICKY,它几乎立即重新启动。
那么,为什么pre-Oreo也会有5分钟的延迟呢?

这种方法是合理的。 Android Beacon Library 2.15+ 原生支持前台服务作为扫描机制,以支持 Android 8 上的此类案例。See here 了解更多信息。

棘手的部分是在使用 Job Scheduler 和服务进行扫描之间来回切换。我没有对此进行测试,但我的建议是在自定义应用程序 class 中手动绑定到 BeaconManager。 然后:

  1. 进入区域后,停止监听,然后解绑BeaconManager

  2. 启动自定义前台服务

  3. 在前台服务中,禁用扫描作业,然后绑定到 BeaconManager 并开始测距

  4. 一旦一段时间内没有信标被测距,停止测距,与 BeaconManager 解除绑定,启用扫描作业,再次绑定,然后开始监控。

  5. 最后退出前台服务

关于第二个问题,是的,START_STICKY 将很快在大多数平台上重新启动服务。该库使用一个 5 分钟的计时器和 AlarmManager 作为 备份 ,如果 START_STICKY 重新启动失败,它将重新启动服务。实际上,在典型使用中,扫描服务的重启速度比五分钟快得多。