ios 测距信标仅在应用程序运行时有效?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/19141779/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Ranging Beacons only works when app running?
提问by Aaron Bratcher
I am having difficulties getting this to work for when the app is not running. I have locationManager:didRangeBeacons:inRegion:
implemented and it is called when the app is running in the foreground or background, however it doesn't seem to do anything when I quit the app and lock the screen. The location services icon goes away and I never know that I entered a beacon range. Should the LocalNotification still work?
当应用程序没有运行时,我很难让它工作。我已经locationManager:didRangeBeacons:inRegion:
实现并在应用程序在前台或后台运行时调用它,但是当我退出应用程序并锁定屏幕时它似乎没有做任何事情。定位服务图标消失了,我不知道我进入了信标范围。LocalNotification 还应该工作吗?
I have Location updates and Uses Bluetooth LE accessories selected in Background Modes (XCode 5) I didn't think I needed them.
我在后台模式 (XCode 5) 中选择了位置更新和使用蓝牙 LE 配件,我认为我不需要它们。
Any help greatly appreciated.
非常感谢任何帮助。
-(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...
}
回答by davidgyoung
Monitoring can launch an app that isn't running. Ranging cannot.
监控可以启动未运行的应用程序。测距不能。
The key to having monitoring launch your app is to set this poorly documented flag on your This can launch your app on a region transition even after completely rebooting your phone. But there are a couple of caveats:CLBeaconRegion
: region.notifyEntryStateOnDisplay = YES;
监控启动您的应用程序的关键是在您的即使在完全重新启动手机后,这也可以在区域转换时启动您的应用程序。但有几个警告:CLBeaconRegion
:r上设置这个记录不佳的标志egion.notifyEntryStateOnDisplay = YES;
- Your app launches into the background only for a few seconds. (Try adding
NSLog
statements toapplicationDidEnterBackground
and other methods in your AppDelegate to see what is going on.) - iOS can take its own sweet time to decide you entered a
CLBeaconRegion
. I have seen it take up to four minutes.
- 您的应用程序仅在几秒钟内启动到后台。(尝试在 AppDelegate 中添加
NSLog
语句applicationDidEnterBackground
和其他方法以查看发生了什么。) - iOS 可以花自己的时间来决定您是否输入了
CLBeaconRegion
. 我看到最多需要四分钟。
As far as ranging goes, even though you can't have ranging wake up your app, you can make your app do both monitoring and ranging simultaneously. If monitoring wakes up your app and puts it into the background for a few seconds, ranging callbacks start up immediately. This gives you a chance to do any quick ranging actions while your app is still running.
就测距而言,即使你不能让测距唤醒你的应用,你也可以让你的应用同时进行监测和测距。如果监控唤醒您的应用程序并将其置于后台几秒钟,则范围回调会立即启动。这使您有机会在您的应用程序仍在运行时执行任何快速测距操作。
EDIT: Further investigation proves that notifyEntryStateOnDisplay
has no effect on background monitoring, so the above should work regardless of whether you have this flag. See this detailed explanation and discussion of delays you may experience
编辑:进一步调查证明这notifyEntryStateOnDisplay
对后台监控没有影响,因此无论您是否拥有此标志,上述内容都应该有效。请参阅有关您可能遇到的延迟的详细说明和讨论
回答by Teodor Ciuraru
Code for iOS 9 to range beacons in the background, by using Location Updates:
通过使用位置更新,iOS 9 的代码在后台对信标进行测距:
Open Project Settings -> Capabilities -> Background Modes -> Toggle
Location Updates
andUses Bluetooth LE accessories
toON
.Create a
CLLocationManager
, requestAlways
monitoring authorization (don't forget to add theApplication does not run in background
toNO
andNSLocationAlwaysUsageDescription
in the app'sinfo.plist
) and set the following properties:locationManager!.delegate = self locationManager!.pausesLocationUpdatesAutomatically = false locationManager!.allowsBackgroundLocationUpdates = true
Start ranging for beacons and monitoring region:
locationManager!.startMonitoringForRegion(yourBeaconRegion) locationManager!.startRangingBeaconsInRegion(yourBeaconRegion) locationManager!.startUpdatingLocation() // Optionally for notifications UIApplication.sharedApplication().registerUserNotificationSettings( UIUserNotificationSettings(forTypes: .Alert, categories: nil))
Implement the
CLLocationManagerDelegate
and in yourdidEnterRegion
send bothstartRangingBeaconsInRegion()
andstartUpdatingLocation()
messages (optionally send the notification as well) and set thestopRangingBeaconsInRegion()
andstopUpdatingLocation()
indidExitRegion
打开 Project Settings -> Capabilities -> Background Modes -> Toggle
Location Updates
andUses Bluetooth LE accessories
toON
。创建
CLLocationManager
,请求Always
监控授权(不要忘记添加Application does not run in background
到NO
,并NSLocationAlwaysUsageDescription
在应用程序的info.plist
),并设置以下属性:locationManager!.delegate = self locationManager!.pausesLocationUpdatesAutomatically = false locationManager!.allowsBackgroundLocationUpdates = true
开始测距信标和监测区域:
locationManager!.startMonitoringForRegion(yourBeaconRegion) locationManager!.startRangingBeaconsInRegion(yourBeaconRegion) locationManager!.startUpdatingLocation() // Optionally for notifications UIApplication.sharedApplication().registerUserNotificationSettings( UIUserNotificationSettings(forTypes: .Alert, categories: nil))
落实
CLLocationManagerDelegate
并在didEnterRegion
同时发送startRangingBeaconsInRegion()
和startUpdatingLocation()
消息(可选发送通知为好),并设置stopRangingBeaconsInRegion()
和stopUpdatingLocation()
在didExitRegion
Be aware that this solution works but it is not recommended by Apple due to battery consumption and customer privacy!
请注意,此解决方案有效,但由于电池消耗和客户隐私,Apple 不建议这样做!
更多信息:https: //community.estimote.com/hc/en-us/articles/203914068-Is-it-possible-to-use-beacon-ranging-in-the-background-
回答by manishnath
Here is the process you need to follow to range in background:
以下是您需要遵循的过程以在后台进行范围调整:
- For any
CLBeaconRegion
always keep monitoring on, in background or foreground and keepnotifyEntryStateOnDisplay = YES
notifyEntryStateOnDisplay
callslocationManager:didDetermineState:forRegion:
in background, so implement this delegate call...
- 对于任何
CLBeaconRegion
始终在后台或前台进行监控并保持notifyEntryStateOnDisplay = YES
notifyEntryStateOnDisplay
locationManager:didDetermineState:forRegion:
在后台调用,所以实现这个委托调用...
...like this:
...像这样:
- (void)locationManager:(CLLocationManager *)manager didDetermineState:(CLRegionState)state forRegion:(CLRegion *)region{
if (state == CLRegionStateInside) {
//Start Ranging
[manager startRangingBeaconsInRegion:region];
}
else{
//Stop Ranging
[manager stopRangingBeaconsInRegion:region];
}
}
I hope this helps.
我希望这有帮助。
回答by James Frost
You are doing two separate operations here - 'ranging' beacons and monitoring for a region. You can monitor for a region in the background, but not range beacons.
您在这里执行两个单独的操作 - “测距”信标和监视一个区域。您可以在后台监控某个区域,但不能监控距离信标。
Therefore, your implementation of locationManager:didRangeBeacons:inRegion:
won't get called in the background. Instead, your call to startMonitoringForRegion
will result in one / some of the following methods being called:
因此,您的实现locationManager:didRangeBeacons:inRegion:
不会在后台调用。相反,您的调用startMonitoringForRegion
将导致调用以下一个/某些方法:
– locationManager:didEnterRegion:
– locationManager:didExitRegion:
– locationManager:didDetermineState:forRegion:
These will get called in the background. You can at that point trigger a local notification, as in your original code.
这些将在后台调用。您可以在那时触发本地通知,就像在您的原始代码中一样。
回答by Tommy Devoy
Your app should currently wake up if you're just wanting to be notified when you enter a beacon region. The only background restriction I know of concerns actually hosting an iBeacon on an iOS device. In that case, the app would need to be physically open in the foreground. For that situation, you'd be better off just doing the straight CoreBluetooth CBPeripheralManager
implementation. That way you'd have some advertising abilities in the background.
如果您只想在进入信标区域时收到通知,您的应用当前应该会被唤醒。我所知道的唯一背景限制是在 iOS 设备上实际托管 iBeacon。在这种情况下,应用程序需要在前台物理打开。对于这种情况,您最好直接CBPeripheralManager
执行CoreBluetooth实现。这样你就会在后台有一些广告能力。