如何使用 Android Beacon 库重新配置区域?

问题描述

我正在尝试制作一个可以动态更改监控的信标区域的应用程序。 特别是,我需要使用基于 MAC 地址的区域。用例实际上不是信标,而是我们正在研究使用 BLE 广告来传输物联网数据。然而,信标用例非常接近,因此使用 Android 信标库非常有意义。

静态配置时一切正常,但如果我尝试在运行时编辑该区域,它绝对不会改变任何内容,结果就像请求更改之前一样。

我有这样的方法来更改区域(这一次只有一个,但是当我开始工作时我需要一个 MAC 列表):

  fun disableMonitoring() {
        if (regionBootstrap != null) {
            regionBootstrap.disable()
        }
    }

   fun enableMonitoring() {
        
        regionBootstrap.removeRegion(region)
        region = Region("wildcard-region",null,null)
        regionBootstrap.addRegion(region)
        regionBootstrap = RegionBootstrap(this,region)
    }

   fun enableListening(mac: String) {
        
        regionBootstrap.removeRegion(region)
        region = Region("regionForMacAddress",mac)
        regionBootstrap.addRegion(region)
        regionBootstrap = RegionBootstrap(this,region)
    }

我检查过使用 disable 方法没有区别,还尝试只使用 add/removeRegion 方法而不重新运行引导程序。没有运气。

我在三星 S9 Android 10 上运行它,使用 2.18-beta 库。我只是从 GitHub 上破解 Kotlin 示例代码开始。

解决方法

一般而言,RegionBootstrap 类每个应用程序的实例不应超过一个。它应该在您第一次开始寻找信标时构造一次。之后,您可以在单个实例上调用 addRegion(…)removeRegion(…)

编辑:每次创建不同的区域时,请注意更改区域的字符串 uniqueId(第一个参数)。共享相同 uniqueId 的两个不同区域定义将被视为单个区域。它将无法更改区域。您也可以将 MAC 地址用作此参数,以简化您的用例。

另外,请注意如果您曾经调用过 regionBootstrap.disable() 方法,则唯一需要创建 RegionBootstrap 的新实例。在这种情况下,您确实需要构建一个新实例以使其再次运行。在这种情况下不这样做会给你一个关于消费者没有被绑定的错误。 (除非你有充分的理由,否则不要调用 regionBootstrap.disable()

虽然上述用法应该有效,但 RegionBootstrap 构造确实是为更多静态监控而设计的,这就是为什么这看起来如此尴尬的原因。如果您经常想更改受监控的区域,最好不要使用 RegionBootstrap,而是使用这些 API:

beaconManager.bind(this)  // call just one time at app start then wait for  the onBeaconServiceConnected callback
beaconManager.startMonitoringBeaconsInRegion(region) // add a new region
//then later
beaconManager.startMonitoringBeaconsInRegion(newRegion) // add a new region
beaconManager.stopMonitoringBeaconsInRegion(region) 

还是太别扭?图书馆还有更简单的 autobind APIs 在最新的 2.19-beta4 版本中。这些消除了手动调用 bind 并等待回调的需要。这些仍然是测试版,因为我没有在您的区域频繁更改的情况下彻底测试它们。如果您愿意,请随时尝试并报告任何问题:

beaconManager.startMonitoringBeacons(region) // add a first region
//then later
beaconManager.startMonitoringBeacons(newRegion) // start monitoring second region
beaconManager.stopMonitoringBeacons(region) // remove original  region

通常在删除旧区域之前添加新区域总是更好,因为它让图书馆知道您还没有完全完成对信标的扫描。

相关问答

Selenium Web驱动程序和Java。元素在(x,y)点处不可单击。其...
Python-如何使用点“。” 访问字典成员?
Java 字符串是不可变的。到底是什么意思?
Java中的“ final”关键字如何工作?(我仍然可以修改对象。...
“loop:”在Java代码中。这是什么,为什么要编译?
java.lang.ClassNotFoundException:sun.jdbc.odbc.JdbcOdbc...