2013-10-02 54 views
23

当我的应用没有运行时,我很难解决这个问题。我已经实现了locationManager:didRangeBeacons:inRegion:,它在应用程序在前台或后台运行时调用,但是当我退出应用程序并锁定屏幕时,它似乎没有任何操作。位置服务图标消失,我永远不知道我进入了一个灯塔范围。 LocalNotification是否仍然有效?测距信标只适用于应用程序运行?

我有位置更新和使用在背景模式(XCode 5)中选择的蓝牙LE配件我不认为我需要它们。

任何帮助非常感谢。

-(void)watchForEvents { // this is called from application:didFinishLaunchingWithOptions 
    id class = NSClassFromString(@"CLBeaconRegion"); 
    if (!class) { 
     return; 
    } 

    CLBeaconRegion * rflBeacon = [[CLBeaconRegion alloc] initWithProximityUUID:kBeaconUUID identifier:kBeaconString]; 
    rflBeacon.notifyOnEntry = YES; 
    rflBeacon.notifyOnExit = NO; 
    self.locationManager = [[CLLocationManager alloc] init]; 
    self.locationManager.delegate = self; 
    [self.locationManager startRangingBeaconsInRegion:rflBeacon]; 
    [self.locationManager startMonitoringForRegion:rflBeacon]; 
} 

-(void)locationManager:(CLLocationManager *)manager didRangeBeacons:(NSArray *)beacons inRegion:(CLBeaconRegion *)region { 
    if (beacons.count == 0 || eventRanged) { // breakpoint set here for testing 
     return; 
    } 

    eventRanged = YES; 
    if (backgroundMode) { // this is set in the EnterBackground/Foreground delegate calls 
     UILocalNotification *notification = [[UILocalNotification alloc] init]; 
     notification.alertBody = [NSString stringWithFormat:@"Welcome to the %@ event.",region.identifier]; 
     notification.soundName = UILocalNotificationDefaultSoundName; 
     [[UIApplication sharedApplication] presentLocalNotificationNow:notification]; 
    } 

    // normal processing here... 
} 
+0

“(。我也有在此之前的工作,它会给锁定屏幕上的通知,现在不工作)” ......你有什么改变? –

+0

行..我确实了解了如何在后台和上面的问题已更新时再次使我的徽章出现在锁定屏幕上:[self.locationManager startMonitoringForRegion:rflBeacon]; –

+0

这可能会帮助你:http://stackoverflow.com/questions/19127282/ibeacon-notification-when-the-app-is-not-running – random

回答

1

如果您只是想在您进入灯塔区域时收到通知,那么您的应用应当醒来。我知道的唯一背景限制实际上是在iOS设备上托管一个iBeacon。在这种情况下,应用程序需要在前台实际打开。对于这种情况,你最好只做直线CoreBluetooth CBPeripheralManager实施。这样你就可以在后台获得一些广告能力。

+0

我弄清楚,如果我启动监视区域使用该信标作为区域,然后如果应用程序在后台运行,我会在锁定屏幕上收到通知。我认为startMonitoringForRegion会在应用程序尚未运行时启动。 –

+0

每个Apple的AirLocate示例代码: “didDetermineState():用户可以当应用程序没有运行时在区域内或区域外转换。发生这种情况时,CoreLocation会立即启动应用程序,调用此委托方法,并让用户知道v ia当地通知。“ – barbazoo

+0

是的,我没有阅读正确的问题。我只是指在后台托管iBeacon。即如果您运行的是托管iBeacon的应用程序,则该应用程序需要在前台运行以供其他人进入该区域。我会编辑。 –

11

监控可以启动未运行的应用程序。测距不能。

的关键,其监测启动您的应用程序是设置此不良记录标志您CLBeaconRegion,R egion.notifyEntryStateOnDisplay = YES; 这甚至完全后,重新启动您的手机可以启动你的上一个区域过渡的应用程序。但有几个注意事项:

  1. 您的应用程序仅在几秒钟内启动到后台。 (尝试将NSLog语句添加到applicationDidEnterBackground和其他AppDelegate中的方法以查看正在进行的操作。)
  2. iOS可以自己花时间决定是否输入CLBeaconRegion。我已经看到它需要长达四分钟。

尽管您不能有范围唤醒您的应用程序,但您可以使您的应用程序同时执行监视和测距。如果监控唤醒您的应用程序并将其放入后台几秒钟,则会立即启动各种回调。这使您有机会在应用程序仍在运行时执行任何快速测距操作。

编辑:进一步的调查证明,notifyEntryStateOnDisplay对背景监测没有影响,所以无论你是否有这个标志,上述都应该工作。见this detailed explanation and discussion of delays you may experience

+0

的缺陷是否是受制裁的iBeacons的四分钟范围特性还是可能试图模仿iBeacon的限制?四分钟就是我们希望用户看到的东西的几个街区。 –

+0

我的猜测是,只是一个猜测,就是iOS试图通过每4分钟左右进行一次蓝牙扫描来节省电量,因为没有应用程序处于前景测距或监控状态时。 – davidgyoung

+0

我不确定'notifiyEntryStateOnDisplay'是否具有您认为它具有的效果。我的理解是,当设置为YES时,iOS会推迟通知您的区域条目通知应用,直到用户唤醒设备的显示,而不是立即发送。苹果公司在WWDC演示中给出的例子是一个会员卡应用程序,你不想在有人走过商店时ping通电话,但是当用户主动开始使用他们的电话时,它。 – Defragged

7

以下是你需要遵循的范围在后台进程:

  1. 对于任何CLBeaconRegion始终保持监控上,在背景或前景,并保持notifyEntryStateOnDisplay = YES
  2. notifyEntryStateOnDisplay电话locationManager:didDetermineState:forRegion:的背景下,所以实行这个代表电话...

...像这样:

- (void)locationManager:(CLLocationManager *)manager didDetermineState:(CLRegionState)state forRegion:(CLRegion *)region{ 

    if (state == CLRegionStateInside) { 


     //Start Ranging 
     [manager startRangingBeaconsInRegion:region]; 
    } 

    else{ 

     //Stop Ranging 
     [manager stopRangingBeaconsInRegion:region]; 
    } 

} 

我希望这有助于。

+0

位置管理器的代表可以是任何对象还是应该由appdelegate执行?对我而言,只有在appdelegate是位置管理员的代表时才能工作......您是否看到任何原因? – rops

+2

是的,它可以使用任何对象 - 请参阅此示例https://github.com/manishnath/iBeaconCenter – manishnath

+1

小评论:您需要使用(CLBeaconRegion *)对类型进行类型转换,因为startRangingBeaconsInRegion需要CLBeaconRegion *,didDetermineState会传递一个CLRegion * – CharlesA

-2

您可以在后台进行测量。但是,有一个问题。用户必须将应用程序放到前台,这是您开始测量的时间。然后,即使用户锁定了屏幕并且该应用程序在后台运行,它也会继续保持范围,并且永远每1秒调用一次didRangeBeacons回调。

要打开背景位置更新,请选择您的项目,转到信息并添加一行称为“所需的背景模式”。然后添加相关项目:位置更新,通过核心蓝牙通信/共享数据等。

现在,一旦您在进入该区域时得到回调,您的应用将在后台唤醒并通知用户。用户打开应用程序将应用程序放在前台。此时,您可以拨打startRangingBeaconsInRegion开始测距过程。另外,请调用方法startUpdatingLocation,它将在后台更新位置。

2

您正在这里做两个独立的操作 - “测距”信标和监测区域。您可以监视背景中的某个区域,但不监测距离信标。

因此,您的实施locationManager:didRangeBeacons:inRegion:不会在后台调用。相反,你要startMonitoringForRegion调用将导致一个/下面的一些方法被称为:

– locationManager:didEnterRegion: 
– locationManager:didExitRegion: 
– locationManager:didDetermineState:forRegion: 

这些将被调用的背景。您可以在这一点触发本地通知,就像在您的原始代码中一样。

6

代码为iOS 9范围的信标中的背景下,通过使用位置更新

  1. 打开项目设置 - >功能 - >背景模式 - >切换Location UpdatesUses Bluetooth LE accessoriesON

  2. 创建CLLocationManager,要求Always监控授权(不要忘记添加Application does not run in backgroundNONSLocationAlwaysUsageDescription在应用程序的info.plist),并设置以下属性:

    locationManager!.delegate = self 
    locationManager!.pausesLocationUpdatesAutomatically = false 
    locationManager!.allowsBackgroundLocationUpdates = true; 
    
  3. 开始为信标和监测区域:

    locationManager!.startMonitoringForRegion(yourBeaconRegion) 
    locationManager!.startRangingBeaconsInRegion(yourBeaconRegion) 
    locationManager!.startUpdatingLocation() 
    
    // Optionally for notifications 
    UIApplication.sharedApplication().registerUserNotificationSettings(
        UIUserNotificationSettings(forTypes: .Alert, categories: nil)) 
    
  4. 执行CLLocationManagerDelegate d在didEnterRegiondidExitRegion

同时发送startRangingBeaconsInRegion()startUpdatingLocation()消息(可选发送通知为好),并设置stopRangingBeaconsInRegion()stopUpdatingLocation()请注意,此解决方案,但不建议由苹果由于电池消费和客户隐私!

这里更多:https://community.estimote.com/hc/en-us/articles/203914068-Is-it-possible-to-use-beacon-ranging-in-the-background-

+0

。谢谢你,兄弟! – rmvz3

+1

我建议采取大胆的“注意”部分,这是相当严重的;)感谢您的答案,尤其是链接! – mojuba

相关问题