24

当应用程序未运行时,我很难让它工作。我已经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...
}
4

5 回答 5

11

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

CLBeaconRegion监控启动您的应用程序的关键是在您的: r 上设置这个记录不充分的标志egion.notifyEntryStateOnDisplay = YES; 即使在完全重启手机后,这也可以在区域转换时启动您的应用程序。但有几点需要注意:

  1. 您的应用程序仅在几秒钟内启动到后台。(尝试在 AppDelegate 中添加NSLog语句applicationDidEnterBackground和其他方法,看看发生了什么。)
  2. iOS 可以自行决定是否进入CLBeaconRegion. 我看到它最多需要四分钟。

就测距而言,即使您不能让测距唤醒您的应用程序,您也可以让您的应用程序同时进行监控和测距。如果监控唤醒您的应用程序并将其置于后台几秒钟,则测距回调会立即启动。这使您有机会在您的应用程序仍在运行时执行任何快速测距操作。

编辑:进一步调查证明这notifyEntryStateOnDisplay对后台监控没有影响,因此无论您是否有此标志,上述内容都应该有效。请参阅您可能遇到的延迟的详细说明和讨论

于 2013-10-03T01:19:29.213 回答
8

iOS 9 使用Location Updates在后台定位信标的代码:

  1. 打开项目设置 -> 功能 -> 后台模式 ->切换Location Updates到.Uses Bluetooth LE accessoriesON

  2. 创建一个CLLocationManager, 请求Always监控授权(不要忘记在应用程序Application does not run in background中添加NO和)并设置以下属性:NSLocationAlwaysUsageDescriptioninfo.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在你的didEnterRegion发送startRangingBeaconsInRegion()和消息中实现and startUpdatingLocation()(也可以发送通知)并设置stopRangingBeaconsInRegion()and stopUpdatingLocation()indidExitRegion

请注意,此解决方案有效,但由于电池消耗和客户隐私,Apple 不推荐它!

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

于 2015-10-01T13:48:21.390 回答
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];
    }

}

我希望这有帮助。

于 2013-10-03T07:02:19.933 回答
2

您在此处执行两项单独的操作 - “测距”信标和监视区域。您可以在后台监控区域,但不能监控范围信标。

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

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

这些将在后台调用。您可以在此时触发本地通知,就像在您的原始代码中一样。

于 2013-11-19T22:36:46.303 回答
1

如果您只是想在进入信标区域时收到通知,您的应用程序当前应该唤醒。我知道的唯一背景限制实际上是在 iOS 设备上托管 iBeacon。在这种情况下,应用程序需要在前台物理打开。对于这种情况,最好直接执行 CoreBluetoothCBPeripheralManager实现。这样你就可以在后台拥有一些广告能力。

于 2013-10-02T16:28:09.763 回答