为什么 AltBeacon 库断开电源后显示 ble beacon?

发布于 2025-01-09 18:52:17 字数 3313 浏览 0 评论 0原文

我使用 AltBeacon 库进行简单的 ble 扫描。扫描了大约七八秒然后我停止了。点击按钮重新扫描。我在这个库的先前版本中遇到的问题是,当我扫描然后停止它,然后断开信标电源并重新扫描时,rangenotifier或观察者(观察信标的另一种方法)可以看到断开的信标!断开连接后第一次发生这种情况。之后工作正常,如果我再次执行整个过程,就会发生这种情况。

在以前的库版本中,我每次都必须绑定和取消绑定。(这不是好方法,但我必须这样做)。但在较新的版本中,没有取消绑定或绑定方法。大多数方法和函数已被弃用。 我在片段中使用扫描仪。即使切换到另一个片段也没关系。当我再次返回扫描片段时,在信标电源断开后,它第一次发现断开的信标。我不确定这个库是否适合简单的培根扫描。但它非常强大并且简化了一些复杂的事情。

    class ScanningFragment() : androidx.fragment.app.Fragment(){

    lateinit var beaconManager:BeaconManager
    lateinit var region:Region

    val rangeNotifier =object:RangeNotifier{
        override fun didRangeBeaconsInRegion(beacons: MutableCollection<Beacon>?, region: Region?) {
            Log.d(TAG,"in didRangeBeacon")
            if (beacons!!.size > 0) {
                Log.d(TAG, "didRangeBeaconsInRegion called count:  " + beacons.size + beacons.iterator().next().id1)
                val firstBeacon = beacons.iterator().next()
            }

        override fun onCreate(savedInstanceState: Bundle?)
    {
        Log.d("lifecycl","it is oncreate ")
        super.onCreate(savedInstanceState)

        BeaconManager.setDebug(true)

        beaconManager=BeaconManager.getInstanceForApplication(requireContext()).apply {
            foregroundScanPeriod=7000L
            foregroundBetweenScanPeriod=5000L
            updateScanPeriods()
            beaconParsers.clear()
            beaconParsers.add(BeaconParser().setBeaconLayout("m:2-3=0215,i:4-8,i:4-19,i:20-21,i:22-23,p:24-24"))
            region = Region("prefixRegion", Identifier.parse("0x0000000000"), null, null)

        }
        setupPermissions()
    }
   
       fun rangingButtonTapped() {
       if (beaconManager.rangedRegions.size == 0) {
                beaconManager.addRangeNotifier(rangeNotifier)
                beaconManager.startRangingBeacons(region)
                binding.insideviewmodel?.isScanning?.value = true
             }
        else {
            beaconManager.stopRangingBeacons(region)
            binding.BTNScan.run {
                Handler(Looper.getMainLooper()).postDelayed({ stopAnimation() }, 1000)
                Handler(Looper.getMainLooper()).postDelayed({ revertAnimation() }, 2000)
            }
        }

      override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
           binding.insideviewmodel?.isScanning?.observe(viewLifecycleOwner,Observer{
            currentStatusScan->
            if(currentStatusScan)
            {
                object : CountDownTimer(8500, 1000) {
                    override fun onTick(p0: Long) {

                    }

                    override fun onFinish() {
                        beaconManager.stopRangingBeacons(region)
                        beaconManager.removeRangeNotifier(rangeNotifier)
                        binding.insideviewmodel?.isScanning?.value = false
                    }
                }.start()
            }
        })
}

   }
   }

这是第一次扫描的调试日志。 https://jpst.it/2LVY4

它是用于在断开信标电源后重新扫描的调试日志。 https://jpst.it/2LVZs

分析器: 输入图片此处描述

I use AltBeacon library for simple ble scanning. Scanning for about 7 or 8 seconds then I stop it. tapping button for rescanning. the problem that I have had from the previous version of this library , when I scan then stop it, and disconnect beacon power and I rescan , rangenotifier or observer(another method to watch beacons) could see disconnected beacon! for first time after disconnected it is happened. after that works correctly and if I do the whole process again it is happens.

in the previous library version I had to bind and unbind each time.(not good approach but I had to do) .but in newer version there are no unbind or bind methods. most of methods and functions are deprecated.
I use scanner in fragment. even it is not matter if switch to another fragment. when I come back to scanning fragment again it finds disconnected beacon for fist time after beacon power disconnected. I'm not sure if this library is suitable for a simple bacon scanning. But it is very powerful and simplified some complex thing.

    class ScanningFragment() : androidx.fragment.app.Fragment(){

    lateinit var beaconManager:BeaconManager
    lateinit var region:Region

    val rangeNotifier =object:RangeNotifier{
        override fun didRangeBeaconsInRegion(beacons: MutableCollection<Beacon>?, region: Region?) {
            Log.d(TAG,"in didRangeBeacon")
            if (beacons!!.size > 0) {
                Log.d(TAG, "didRangeBeaconsInRegion called count:  " + beacons.size + beacons.iterator().next().id1)
                val firstBeacon = beacons.iterator().next()
            }

        override fun onCreate(savedInstanceState: Bundle?)
    {
        Log.d("lifecycl","it is oncreate ")
        super.onCreate(savedInstanceState)

        BeaconManager.setDebug(true)

        beaconManager=BeaconManager.getInstanceForApplication(requireContext()).apply {
            foregroundScanPeriod=7000L
            foregroundBetweenScanPeriod=5000L
            updateScanPeriods()
            beaconParsers.clear()
            beaconParsers.add(BeaconParser().setBeaconLayout("m:2-3=0215,i:4-8,i:4-19,i:20-21,i:22-23,p:24-24"))
            region = Region("prefixRegion", Identifier.parse("0x0000000000"), null, null)

        }
        setupPermissions()
    }
   
       fun rangingButtonTapped() {
       if (beaconManager.rangedRegions.size == 0) {
                beaconManager.addRangeNotifier(rangeNotifier)
                beaconManager.startRangingBeacons(region)
                binding.insideviewmodel?.isScanning?.value = true
             }
        else {
            beaconManager.stopRangingBeacons(region)
            binding.BTNScan.run {
                Handler(Looper.getMainLooper()).postDelayed({ stopAnimation() }, 1000)
                Handler(Looper.getMainLooper()).postDelayed({ revertAnimation() }, 2000)
            }
        }

      override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
           binding.insideviewmodel?.isScanning?.observe(viewLifecycleOwner,Observer{
            currentStatusScan->
            if(currentStatusScan)
            {
                object : CountDownTimer(8500, 1000) {
                    override fun onTick(p0: Long) {

                    }

                    override fun onFinish() {
                        beaconManager.stopRangingBeacons(region)
                        beaconManager.removeRangeNotifier(rangeNotifier)
                        binding.insideviewmodel?.isScanning?.value = false
                    }
                }.start()
            }
        })
}

   }
   }

it is a debug log for first time scanning.
https://jpst.it/2LVY4

it is a debug log for rescanning after disconnecting beacon power.
https://jpst.it/2LVZs

Profiler:
enter image description here

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

深海里的那抹蓝 2025-01-16 18:52:17

第二条日志行“断开信标电源后”显示 Android 操作系统 BLE 扫描器确实在 12:53:31 提供 iBeacon 检测:

2022-02-24 12:53:31.117 23528-23528/ D/CycledLeScannerForLollipop :得到记录 ... 处理pdu类型FF: 0201041aff4c000215...

库源代码显示,该日志行是在操作系统回调有关 BLE 广告检测的回调后立即发出的。 请参见此处。

显然,蓝牙扫描仪不可能检测来自已关闭电源的 BLE 设备的广告所以必须有一个替代的解释。几种可能性:

  1. BLE 发射器在 12:53:31.117(或稍早)并未真正关闭
  2. 检测到的广告来自不同的发射器 来自
  3. Android 操作系统的回调被延迟,可能是因为传递的主线程被延迟由于应用程序中大量 CPU 使用而被阻止。
  4. 相关手机的蓝牙堆栈或 UI 线程处理中的一些缺陷会延迟检测的传送。

为了找出原因,我建议如下:

  1. 要消除蓝牙堆栈缺陷,请在不同的 Android 手机上测试相同的代码,最好是由不同的制造商测试。
  2. 为了消除 UI 线程被阻塞的可能性,请在 Android Studio 分析器中运行它,或者简单地删除在看到延迟之前执行的尽可能多的代码。
  3. 要验证发射器是否确实关闭并且周围没有其他发射器,请使用第二部带有现成信标扫描仪的手机来监控实际正在传输的设备。仅当您使用第二台设备确认没有其他可见发射器时才执行测试。

The second log line "after disconnecting beacon power" shows that the Android OS BLE scanner does indeed deliver an iBeacon detection at 12:53:31:

2022-02-24 12:53:31.117 23528-23528/ D/CycledLeScannerForLollipop: got record ... Processing pdu type FF: 0201041aff4c000215....

The library source code shows that this log line is issued immediately upon a callback from the operating system about a BLE advertisement detection. See here.

Clearly it is not possible for a Bluetooth scanner to detect an advertisement from a powered-off BLE device so there must be an alternate explanation. A few possibilities:

  1. The BLE transmitter is not really powered off at (or slightly before) 12:53:31.117
  2. The detected advertisement comes from a different transmitter
  3. The callback from the Android OS is delayed, perhaps because the main thread on which is delivered was blocked by lots of CPU usage in the app.
  4. Some flaw in the bluetooth stack or UI thread handling for the phone in question is delaying delivery of detections.

In order to figure out the cause I would suggest the following:

  1. To eliminate a bluetooth stack flaw, test the same code on a different Android phone, preferably by a different manufacturer.
  2. To eliminate the possibility of the UI thread being blocked, run this in the Android Studio profiler, or simply cut out as much code as possible that executes before the delay is seen.
  3. To verify the transmitter is really off and that there are no other transmitters around, use a second phone with an off the shelf beacon scanner to monitor what devices are actually transmitting. Only perform your test when you confirm with a second device there are no other visible transmitters.
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文