【问题标题】:iOS8 - BLE wake up appiOS8 - BLE 唤醒应用
【发布时间】:2015-02-20 19:04:20
【问题描述】:

是否可以在准确的时间(或延迟一段时间后)唤醒 iOS 应用并与外围设备进行通信?我的目标是设置警报并在响铃时与外围设备通信。 我能猜到的唯一解决方案是在那个时候发送一个远程(推送)通知,这将唤醒应用程序,然后它可以与 BLE 设备通信。但这种方式是不可接受的,因为无法保证推送会在准确的时间送达或根本送达。
那么是否可以在使用 CoreBluetooth 的确切时间唤醒应用程序?

【问题讨论】:

  • 它可能值得尝试发送一个计划在那个时间发送的本地通知,一个没有警报文本,但有内容可用标志的通知。不知道它是否会起作用,但值得花几分钟来测试。
  • 实际上目前警报已经通过本地通知工作,但问题是我们无法通过本地通知唤醒应用程序,而只能通过远程(推送)通知来唤醒
  • 你可以安排本地通知,但是你还不是很清楚你什么时候想醒来。什么是“响”?提供更多细节。
  • @MarcusAdams 我的意思是跟随。用户打开应用程序并设置他想要醒来的时间。当他设置时间时,它基本上是安排带有警报文本和一些声音的本地通知,它将在用户设置的时间触发。
  • 请再读一遍我的问题。正如我所写,我知道推送通知的解决方案,但就我而言,我不能使用它。

标签: ios objective-c xcode bluetooth-lowenergy core-bluetooth


【解决方案1】:

AFAIK,鉴于您的限制,这是不可能的。您无法随时唤醒后台运行的应用程序。唯一与此相关的事情是,如果 BLE 外围设备是应用程序对其进行区域监控的 iBeacon,并且当您进入该区域时,您的应用程序将被 didEnterRegion 事件唤醒。在您的情况下,它听起来不像是 iBeacon,而且听起来它会一直在附近。

您根本无法在您想要的时候准确地唤醒 iOS 应用。

【讨论】:

    【解决方案2】:

    您可以使用fireDate 属性发送本地通知以在特定时间触发。也就是说,它只会触发本地通知。由于本地(或推送)通知,您无法启动对 BTLE 外围设备的后台搜索。用户必须启动您的应用。

    可以在后台搜索 BTLE 外围设备,但如果您的应用没有在后台运行,那显然是行不通的。如果您的外围设备恰好是 iBeacon,如果您进入 iBeacon 的范围,即使它没有在后台运行,iOS 也会让您的应用程序栩栩如生。您可以使用CLBeaconRegion 来实现此效果。

    【讨论】:

      【解决方案3】:

      Core Bluetooth now supports background restoration。不过,需要做一些工作才能做到正确。如果 iOS 因内存压力而终止您的应用,它会在检测到连接尝试时尝试在后台恢复您的应用,包括您宣传的任何服务和特征。

      首先,您需要在 info.plist 文件中将UIBackgroundModes 设置为bluetooth-peripheral

      然后你需要给你的 CBPeripheralManager 一个唯一的标识符(我在application:didFinishLaunching:withOptionsAppDelegate.m这样做):

       myCentralManager =
              [[CBCentralManager alloc] initWithDelegate:self queue:dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0) options:@{ CBCentralManagerOptionRestoreIdentifierKey:@"myCentralManagerIdentifier" }];
      

      那么你需要实现外设恢复委托方法:

      - (void)peripheralManager:(CBPeripheralManager *)peripheral
               willRestoreState:(NSDictionary *)dict
      {
          NSArray *services = dict[CBPeripheralManagerRestoredStateServicesKey];
      
          // Loop through services
          for (CBMutableService *service in services) {
      
              // Then characteristics
              for (CBCharacteristic *characteristic in service.characteristics) {
      
                  // Then any centrals that were subscribed
                  for (CBCentral* central in characteristic.subscribedCentrals) {
      
                  }
              }
          }
      }
      

      此时您的CBPerpheralManager 再次进行广告宣传,因此如果您将其保存到属性中,请小心再次覆盖这些特征。

      您可以通过调用来模拟内存终止:

      kill(getpid(), SIGKILL);
      

      【讨论】:

      • 这是否也能在设备重启后继续存在?
      • 不,很遗憾没有,因为 iOS 不会在重新启动时自动开始为您的应用程序做广告/扫描。如果你从 App Switcher 强制退出也是一样。
      猜你喜欢
      • 1970-01-01
      • 2016-04-17
      • 1970-01-01
      • 2021-11-14
      • 2016-07-29
      • 1970-01-01
      • 2016-05-14
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多