安卓altbeacon在应用程序在后台的时间间隔范围内

问题描述 投票:3回答:1

我正在开发一个应用程序,它运行后台服务,以间隔范围内的蓝牙信标。

我启动带有计时器的ForegroundService,每分钟启动测距信标10秒,间隔为200毫秒,计算最强的信标并将其提交给后端API。

当应用程序处于前台时,这可以很好地工作,并且当屏幕关闭时,只要我使用adb logcat连接即可。一旦我将其取下,就不会再将任何内容提交给服务器了,这意味着任何信标都不再存在。

以下是相关的代码片段,我希望我没有简化太多:

class BeaconService : Service(), BeaconConsumer {
    private var beaconManager: BeaconManager? = null
    private var rangingTimer = Timer("rangingTimer", true)
    private val region = Region("com.beacon.test", Identifier.parse("f7826da6-4fa2-4e98-8024-bc5b71e0893e"), null, null)

    override fun onStartCommand(intent: Intent?, flags: Int, startId: Int): Int {
        return Service.START_STICKY
    }

    override fun onCreate() {
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
            val notificationManager = MyNotificationManager.getInstance()
            val notification = notificationManager.buildBeaconServiceNotification(this, "iBeacon service", null)
            startForeground(NOTIFICATION_ID, notification)
        }

        initBeaconManager()
    }

    private fun initBeaconManager() {
        BeaconManager.setDebug(true)
        beaconManager = BeaconManager.getInstanceForApplication(this)
        beaconManager?.foregroundScanPeriod = 200L
        beaconManager?.beaconParsers?.add(BeaconParser().setBeaconLayout("m:2-3=0215,i:4-19,i:20-21,i:22-23,p:24-24"))
        beaconManager?.bind(this)
    }

    override fun onBeaconServiceConnect() {
        beaconManager?.addRangeNotifier { beacons, _ ->
            if (beacons.isNotEmpty()) {
                //code add ranged beacons to list
            }
        }
        startRanging()
    }

    private fun startRanging() {

        //code to reset the list of ranged beacons

        beaconManager?.startRangingBeaconsInRegion(region)

        rangingTimer.schedule(10000L) {
            stopRanging(50000L)
        }

    }

    private fun stopRanging(restartRangingAfter: Long? = null) {
        beaconManager?.stopRangingBeaconsInRegion(region)

        //code calcuate the strongest beacon and submit to server

        if (restartRangingAfter != null) {
            rangingTimer.schedule(restartRangingAfter) {
                startRanging()
            }
        }
    }
}
android bluetooth altbeacon
1个回答
2
投票

在操作系统版本8+上,Android限制后台处理,除非它是前台服务或JobScheduler发起的作业的一部分。由于此限制,Android Beacon Library默认使用Android 8+上的JobScheduler。在前台,“立即”ScanJob将不断运行以进行扫描。在后台(意味着当屏幕解锁时没有活动可见),Android不允许这样做。每15分钟最多可安排一次工作。这就是您看到扫描停止的原因。

您拥有自己的前台服务并不重要。 Android仍然对在该前台服务之外执行的任何后台处理强制执行这些限制。

两种选择:

  1. 适应工作限制(每15分钟扫描一次)。使用BackgroundPowerSaver在前景/后台模式之间自动切换并设置beaconManager.setBackgroundScanPeriod(5000)(每15分钟进行5秒扫描。)为清楚起见,您还应设置beaconManager.setBackgroundBetweenScanPeriod(15*60*1000)(15分钟),尽管您可以设置较低的值,但不允许Android 8+上的操作系统。
  2. 设置库以使用自己的前台服务进行扫描(是第二个前台服务),如here所述。然后,您可以停止使用自己的前台服务,或保留它。如果保留它,您将看到两个关于正在运行的前台服务的通知图标。如果您想保留两个前台服务并只显示一个通知,则可以使用combine those two notifications
© www.soinside.com 2019 - 2024. All rights reserved.