[LocationManager didEnterRegion] 可以获取 Beacon 的 Major & Minor 吗?
Posted
技术标签:
【中文标题】[LocationManager didEnterRegion] 可以获取 Beacon 的 Major & Minor 吗?【英文标题】:Can [LocationManager didEnterRegion] Get a Beacon's Major & Minor? 【发布时间】:2014-01-20 22:10:58 【问题描述】:我从 Roximity 获得了一些信标,根据我收集的信息,所有 Roximity 信标都具有相同的 UUID。我知道我可以使用 [locationManager: didRangeBeacons: inRegion:]
获取主要和次要值,但如果我设置 [locationManager didEnterRegion]
发送推送通知,并且我的用户经过与其他人的应用程序相关联的不同 Roximity 信标,我该如何确定这个在[locationManager didEnterRegion]
?
【问题讨论】:
【参考方案1】:你基本上有两个选择。
定义您正在监控的区域,以便它们包含您的特定主要和次要编号。主要限制是 ios 只能让您同时监控 20 个区域,这意味着您只能对 20 个不同的 iBeacon 执行此操作:
CLBeaconRegion *region1 = [[CLBeaconRegion alloc] initWithProximityUUID:[[NSUUID alloc] initWithUUIDString:@"8deefbb9-f738-4297-8040-96668bb44281"] major:1201 minor:3211 identifier:@"beacon1"];
[_locationManager startRangingBeaconsInRegion:region1];
CLBeaconRegion *region1 = [[CLBeaconRegion alloc] initWithProximityUUID:[[NSUUID alloc] initWithUUIDString:@"8deefbb9-f738-4297-8040-96668bb44281"] major:1798 minor:2122 identifier:@"beacon2"];
[_locationManager startRangingBeaconsInRegion:region2];
...
仅基于 UUID 监控一个区域,但同时也对同一区域进行测距。您将获得针对您看到的每个特定 iBeacon 的 Ranging 回调。 (即使在后台,您会在进入区域后大约 5 秒内收到此信息。)在测距回调中,您检查您看到的信标的主要/次要编号,并将它们与您拥有的信标列表进行比较。只有当您看到匹配项时,您才会执行特定操作。如果您不断添加信标,在您的应用程序中保持此列表是最新的可能会很困难,因此您可能希望使用像 ProximityKit 这样的网络服务,它可以让您将 iBeacon 标识符列表存储在云中。
-(void)locationManager:(CLLocationManager *)manager didRangeBeacons:(NSArray *)beacons inRegion:(CLBeaconRegion *)region
for (CLBeacon *beacon in beacons)
if ([self isMyBeaconWithMajor: beacon.major minor: beacon.minor])
// Yes, this is my beacon! Do something special here
-(BOOL)isMyBeaconWithMajor: (NSNumber *)major minor: (NSNumber *)minor
// TODO: write code here that returns YES if the major and minor belong to you
另一种最终可能性(诚然有点超出您的要求)是使用带有自定义 UUID 的信标,这会使事情变得更容易。全面披露:我是一家销售具有可定制标识符的 iBeacons 的公司的员工。
【讨论】:
感谢您的出色回答。昨天我试图做选项#2,但不太奏效。会再看一遍。 为每个信标使用唯一的 UUID 会不会限制您一次最多只能监控 20 个? 没错,但这并不是我所提议的。如果您定义自己的唯一 ProximityUUID 并为您自己的所有 iBeacon 使用相同的 ProximityUUID,您将非常确定当您看到 ProximityUUID 时,iBeacons 属于您。 大卫,如果你使用#2,有没有办法只获得一个回调(比如 didEnterRegion: 和 didExitRegion: 只在边界交叉处调用一次)? didRangeBeacons:每秒被调用一次。另外,有没有一种简单的方法可以使用这个范围来获得“didExit”功能?似乎当您退出一个信标的区域(但进入另一个信标的区域,所以您还没有离开“区域”)时,第一个信标会从远程信标阵列中退出。 使用选项#2,您将在进入区域后收到多个调用,并且在区域退出时不会收到任何回调。你必须编写额外的代码来处理这个问题:你可以维护一个包含所有看到的唯一信标(相同的 uuid/major/minor)的 NSMutableArray,并在测距回调中更新它。然后,您可以在区域退出回调中访问此数组,这样您就知道哪些信标消失了。当然,有可能在 5 秒的背景测距时间到期后看到 其他 信标,但您的应用永远不会知道它们。使用选项 #2,您必须接受此限制。【参考方案2】:您可以使用以下代码确定主要和次要:
- (void)locationManager:(CLLocationManager *)manager didEnterRegion:(CLRegion *)region
CLBeaconRegion *r = (CLBeaconRegion *) region;
NSLog(@"UUID %@, major %@, minor %@", r.proximityUUID, r.major, r.minor);
[self myNotification:@"You are in the region"];
[self.locationManager startRangingBeaconsInRegion:r];
【讨论】:
这个委托方法返回被监控的区域。基本上,它说“嘿,你告诉我监控的那个区域刚刚进入”它没有告诉你任何关于该区域的信标广告。因此,返回的主要和次要值将是您自己的,而不是触发通知的信标区域的值。以上是关于[LocationManager didEnterRegion] 可以获取 Beacon 的 Major & Minor 吗?的主要内容,如果未能解决你的问题,请参考以下文章
LocationManager.getLastKnownLocation(LocationManager.NETWORK_PROVIDER) 在 Galaxy S7 上总是返回 NULL(仅限)
locationManager.isProviderEnabled(LocationManager.NETWORK_PROVIDER) 使用 Wi-Fi 总是返回 false
我应该在 locationManager:didFailWithError: 中发送 [locationManager stopUpdatingLocation] 吗?