Altbeacon 在 android 8+ 上找不到信标

Altbeacon not finding beacons on android 8+

我在我的项目中使用 Alt beacon 来检测信标,它在我的三星 s7 (Android 7) 上运行良好,但在三星 s10、Oneplus 6 和 Google Pixel 3 上运行良好XL (Android 9/10) 它根本不起作用。

代码似乎没有找到任何信标。

我的代码以权限检查开始:

if (ContextCompat.checkSelfPermission(view, Manifest.permission.ACCESS_COARSE_LOCATION) != PackageManager.PERMISSION_GRANTED) {
    Log.d(TAG, "Requesting Permission.")
    openPermissionDialog()
} else {
    startBeacon()
}

然后在我的启动信标代码中打开蓝牙并创建我的信标管理器

val mBluetoothAdapter = BluetoothAdapter.getDefaultAdapter()
    if(mBluetoothAdapter != null){
         if (!mBluetoothAdapter.isEnabled) {
                mBluetoothAdapter.enable()
         }

         Log.d(TAG, "Permissions accepted, bluetooth is on.")

         model.beaconManager = BeaconManager.getInstanceForApplication(view)
         BeaconController.startBeacon(model.beaconManager, view)
    }

最后,在 BeaconController 内部,我有一个单例伴随对象,它将每 20 分钟绑定一次信标。这是因为当我找到信标时它会解绑

class BeaconController {

    companion object {

        private val TAG = "HomePresenter"
        private var hasTimerStarted = false

        fun startBeacon(beaconManager: BeaconManager?, view: HomeActivityView) {

            if (!hasTimerStarted) {

                Log.d(TAG, "Timer starting")
                hasTimerStarted = true

                val handler = Handler()
                Thread(object : Runnable {
                    override fun run() {

                        if (beaconManager?.isBound(view) != null) {
                            Log.d(TAG, "Beacon binding")
                            beaconManager.bind(view)
                            beaconManager.beaconParsers.clear()
                            beaconManager.beaconParsers.add(BeaconParser().setBeaconLayout(BeaconParser.EDDYSTONE_UID_LAYOUT))
                        } else {
                            Log.d(TAG, "Beacon is bound")
                        }

                        handler.postDelayed(this, 1200000) // 20 Minutes

                    }
                }).start()

            } else {
                Log.d(TAG, "Timer already started.")
            }

        }

    }

}

绑定信标后,我 运行 我的 onBeaconServiceConnect 中的一些逻辑会在我找到信标时发送分析

  override fun onBeaconServiceConnect() {
        model.beaconManager?.addRangeNotifier { beacons, _ ->
            if (beacons.isNotEmpty()) {
                val firstBeacon = beacons.iterator().next()
                val firstBeaconNameSpace = "${firstBeacon.id1}".replace("0x", "")
                val firstBeaconIdentifier = "${firstBeacon.id2}".replace("0x", "")

                Log.d(TAG, "Beacon $firstBeaconNameSpace - $firstBeaconIdentifier is " + firstBeacon.distance + " meters away.")

            }
        }

        /**
         * Attach
         */

        try {
            model.beaconManager?.startRangingBeaconsInRegion(Region("com.MYAPP.MYAPP", null, null, null))
            Log.d(TAG, "Added Range Notifier")
        } catch (e: RemoteException) {
            Log.d(TAG, "Error adding Range Notifier")
            e.printStackTrace()
        }


    }

该问题可能与 Android 信标库无关,仅与 Android 操作系统在 Android 8+ 上使用计时器的限制有关。

从版本 8 开始,Android 应用程序在后台执行 10 分钟后被操作系统终止,除非 ForegroundService 处于活动状态。因此,除非您保持屏幕打开、解锁并且应用程序在屏幕上可见,否则此计时器永远不会触发:handler.postDelayed(this, 1200000) // 20 Minutes

您可以更改架构以使其在 Android 8+ 上运行,或者您可以将库配置为使用其内置的 ForegroundService 来绕过限制。有关说明,请参阅 here

我知道,因为我在使用 Beacons 时遇到了问题,对于设备 运行 Oreo 和更高版本的后台任务不起作用。

对于那些设备,我使用了 JobScheduler....

这是关于它的教程 https://www.youtube.com/watch?v=3EQWmME-hNA

希望能帮到你;)

祝你好运

这不起作用的原因是因为我在实际添加信标布局之前绑定了信标...

之前:

beaconManager?.bind(view)
beaconManager?.beaconParsers?.clear()
beaconManager?.beaconParsers?.add(BeaconParser().setBeaconLayout(BeaconParser.EDDYSTONE_UID_LAYOUT))

之后:

beaconManager?.beaconParsers?.clear()
beaconManager?.beaconParsers?.add(BeaconParser().setBeaconLayout(BeaconParser.EDDYSTONE_UID_LAYOUT))
beaconManager?.bind(view)