【问题标题】:has startLeScan() a timeout?startLeScan() 有超时吗?
【发布时间】:2018-09-11 18:09:32
【问题描述】:

我想开发一个始终监听 ble 广告的 android 应用程序,对信标很有用。该应用程序具有活动和后台服务。所有的 BLE 操作都在服务中完成,并且该服务在找到特定的 mac 时执行 REST 发布:

... mBluetoothAdapter.startLeScan(this); ...

public void onLeScan(final BluetoothDevice device, final int rssi, byte[] scanRecord) ...

如果我运行应用程序并让智能手机分开,屏幕会关闭,但应用程序会继续工作,因为我可以在 REST 服务日志中看到有一个呼叫。但是,或多或少 3 小时后,android 应用程序停止调用 rest 服务。

由于 android 服务是 Sticky,a 再次盯着应用程序并关闭应用程序。 3 秒后,服务启动,我看到休息呼叫完成。但是,15 分钟后服务停止调用 rest server。

所有逻辑都在 onLeScan() 回调中。所以我可以推断,即使周围有很多 BLE 设备不断地做广告,这个回调也会停止调用......

请问有什么建议吗?

非常感谢

【问题讨论】:

    标签: android bluetooth-lowenergy


    【解决方案1】:

    首先,不要使用旧的扫描 API。使用 Lollipop 中引入的新功能。原因是您需要执行过滤扫描以使其永远持续下去。过滤器需要根据广告数据包含的内容来设置。

    其次,使用前台服务确保您的应用进程在一段时间后不会被杀死。或者使用新的 API,您可以在其中设置匹配发生时执行的 PendingIntent。

    【讨论】:

      【解决方案2】:

      据我了解,扫描过程没有时间框架。开发人员需要调用 stopScan() 来停止扫描过程。一些 BLE 设备需要 scan() 进程后台来获取设备通知。我认为,您的信标属于该类别。我可以和你分享三个常见的建议

      1. 如果您需要继续扫描过程,最好在工作线程中执行扫描过程。

      2. 从 Android 6 开始,服务发生了巨大的变化。因此,不要使用服务,而是使用 Job Service 或 WorkManager。

      3. BLE 扫描方法已弃用。您只能在 Android OS 4.8 中使用此方法。从 Android OS 5 开始,您需要改用 startScan() 方法。

      我的扫描实现如下(Kotlin 版本)

           /**
               * Scan The BLE Device
               * Check the available BLE devices in the Surrounding
               * If the device is Already scanning then stop Scanning
               * Else start Scanning and check 10 seconds
               * Send the available devices as a callback to the system
               * Finish Scanning after 10 Seconds
               */
              fun scanBLEDevice(isContinuesScan: Boolean) {
                  try {
                      mIsContinuesScan = isContinuesScan
      
                      if (mScanThread != null) {
                          /**
                           * Already Running - No need to rescan
                           */
                          return
                      }
      
                      mScanThread = Thread(mScanRunnable)
                      mScanThread.start()
      
                      /**
                       * Stop Scanning after a Period of Time
                       * Set a 10 Sec delay time and Stop Scanning
                       * collect all the available devices in the 10 Second
                       */
                      if (!isContinuesScan) {
                          mHandler?.postDelayed({
                              // Set a delay time to Scanning
                              stopScan(mDeviceObject)
                          }, BLEConstants.SCAN_PERIOD) // Delay Period
                      }
                  } catch (e: Exception) {
                      Log.e(TAG, e.message)
                  }
      
              }
      
         private val mScanRunnable = Runnable {
              if (mBluetoothAdapter != null && mBluetoothAdapter!!.isEnabled) {
                  scan()
              }
          }
      
          private fun scan() {
              if (isLollyPopOrAbove()) {// Start Scanning For Lollipop devices
                  mBluetoothAdapter?.bluetoothLeScanner?.startScan(/*scanFilters(),
                  scanSettings(),*/scanCallback) // Start BLE device Scanning in a separate thread
              } else {
                  mBluetoothAdapter?.startLeScan(mLeScanCallback) // Start Scanning for Below Lollipop device
              }
          }
      

      如果您需要更多信息,可以访问我的博客

      https://medium.com/@nithinjith.p/ble-in-android-kotlin-c485f0e83c16

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2014-06-13
        • 1970-01-01
        • 1970-01-01
        • 2018-05-30
        • 1970-01-01
        • 1970-01-01
        • 2013-08-03
        相关资源
        最近更新 更多