首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >是否可以使用objective C在禁用位置服务的情况下扫描信标?

是否可以使用objective C在禁用位置服务的情况下扫描信标?
EN

Stack Overflow用户
提问于 2016-05-24 19:06:09
回答 3查看 1.7K关注 0票数 2

如果蓝牙和定位服务已打开,我可以成功扫描信标。但我想知道有没有办法扫描信标时,蓝牙是打开模式和位置服务是在关闭模式。

我使用过此代码,但在位置服务关闭时不会调用此委托方法

代码语言:javascript
复制
-(void)locationManager:(CLLocationManager *)manager didRangeBeacons:(NSArray *)beacons inRegion:(CLBeaconRegion *)region 

有没有人能详细解释一下,如果没有定位服务,我们如何扫描信标?

提前谢谢。

EN

回答 3

Stack Overflow用户

发布于 2016-05-24 19:58:51

在蓝牙打开但位置关闭的情况下,您只能使用CoreBluetooth CoreLocation 检测蓝牙LE信标设备,而不能使用API检测API。

这可以有效地阻止您检测iBeacon传输,因为iOS会通过CoreBluetooth阻止它们的检测。请看我的博客帖子:http://developer.radiusnetworks.com/2013/10/21/corebluetooth-doesnt-let-you-see-ibeacons.html

但是,您可以使用CoreBluetooth来检测其他信标格式,如AltBeacon和Eddystone。我有一些开源代码,展示了如何使用iOS beacon tools来做到这一点。

使用上面的工具,下面是一个扫描AltBeacon、Eddystone-UID、Eddystone-URL和Eddystone-EID并记录检测到的标识符的示例:

代码语言:javascript
复制
self.beaconParsers = [[NSMutableArray alloc] init];
RNLBeaconParser *altBeaconParser = [[RNLBeaconParser alloc] init];
[altBeaconParser setBeaconLayout:@"m:2-3=beac,i:4-19,i:20-21,i:22-23,p:24-24,d:25-25" error: Nil ];
RNLBeaconParser *uidBeaconParser = [[RNLBeaconParser alloc] init];
[uidBeaconParser setBeaconLayout:@"s:0-1=feaa,m:2-2=00,p:3-3:-41,i:4-13,i:14-19" error: Nil];
RNLBeaconParser *urlBeaconParser = [[RNLBeaconParser alloc] init];
[urlBeaconParser setBeaconLayout:@"s:0-1=feaa,m:2-2=10,p:3-3:-41,i:4-20v" error: Nil];
RNLBeaconParser *eidBeaconParser = [[RNLBeaconParser alloc] init];
[eidBeaconParser setBeaconLayout:@"s:0-1=feaa,m:2-2=30,p:3-3:-41,i:4-11" error: Nil];
self.beaconParsers = @[ altBeaconParser, uidBeaconParser, urlBeaconParser, eidBeaconParser ];
self.cbManager = [[CBCentralManager alloc] initWithDelegate:self queue:dispatch_get_main_queue()
                                                  options:@{ CBCentralManagerOptionRestoreIdentifierKey:
                                                               @"myCentralManagerIdentifier" }];

...

- (void)centralManagerDidUpdateState:(CBCentralManager *)central {
  if (central.state == CBCentralManagerStatePoweredOn && self.scanning) {
    CBUUID *eddystone16BitUUID = [CBUUID UUIDWithString:@"FEAA"];
    NSLog(@"eddy uuid is %@", [eddystone16BitUUID UUIDString]);
    [self.cbManager scanForPeripheralsWithServices:@[eddystone16BitUUID] options:@{CBCentralManagerScanOptionAllowDuplicatesKey : @(YES)}];
    // this scans for BLE peripherals including beacons
    [self.cbManager scanForPeripheralsWithServices:nil options:@{CBCentralManagerScanOptionAllowDuplicatesKey : @(YES)}];

  }
  else {
    if (central.state == CBCentralManagerStateUnknown) {
      NSLog(@"CoreBluetooth state UNKNOWN");
    }
    else if (central.state == CBCentralManagerStateResetting)  {
      NSLog(@"CoreBluetooth state RESETTING");
    }
    else if (central.state == CBCentralManagerStateUnsupported)  {
      NSLog(@"CoreBluetooth state UNSUPPORTED");
    }
    else if (central.state == CBCentralManagerStateUnauthorized)  {
      NSLog(@"CoreBluetooth state UNAUTHORIZED");
    }
    else if (central.state == CBCentralManagerStatePoweredOff)  {
      NSLog(@"CoreBluetooth state POWERED OFF");
    }
  }
}


- (void)centralManager:(CBCentralManager *)central didDiscoverPeripheral:(CBPeripheral *)peripheral advertisementData:(NSDictionary *)advertisementData RSSI:(NSNumber *)RSSI {
  NSDictionary *serviceData = advertisementData[@"kCBAdvDataServiceData"];

  RNLBeacon *beacon = Nil;
  NSData *adData = advertisementData[@"kCBAdvDataManufacturerData"];

  for (RNLBeaconParser *beaconParser in self.beaconParsers) {
    if (adData) {
      beacon = [beaconParser fromScanData: adData withRssi: RSSI forDevice: peripheral serviceUuid: Nil];
      beacon.bluetoothIdentifier = [peripheral.identifier UUIDString];
    }
    else if (serviceData != Nil) {
      for (NSObject *key in serviceData.allKeys) {
        NSString *uuidString = [(CBUUID *) key UUIDString];
        NSScanner* scanner = [NSScanner scannerWithString: uuidString];
        unsigned long long uuidLongLong;

        [scanner scanHexLongLong: &uuidLongLong];
        NSNumber *uuidNumber = [NSNumber numberWithLongLong:uuidLongLong];

        NSData *adServiceData = [serviceData objectForKey:key];
        if (adServiceData) {
          beacon = [beaconParser fromScanData: adServiceData withRssi: RSSI forDevice: peripheral serviceUuid: uuidNumber];
        }
      }
    }
    if (beacon != Nil) {
      break;
    }
  }

  if (beacon != Nil) {
    NSString *key = [NSString stringWithFormat:@"%@ %@ %@", beacon.id1, beacon.id2, beacon.id3];
    NSLog(@"Detected beacon: %@", key);
}
票数 2
EN

Stack Overflow用户

发布于 2016-05-24 19:14:48

不,我不认为你可以在关闭定位服务的情况下使用系统iBeacon支持。iBeacon支持由核心位置框架提供。

你也许能够编写低级的BLE代码来查找来自iBeacons的消息,但是我已经看到一些人的帖子,他们不知道如何做到这一点。此外,你还会失去Core Location提供的好处,比如在检测到信标时,即使你的应用程序没有运行,也会得到有关信标的通知。

票数 1
EN

Stack Overflow用户

发布于 2016-05-24 19:30:06

不,如果没有定位服务,您就不能使用iBeacon。看看苹果的文档是怎么说的:

iBeacon在iOS中使用定位服务。有了iBeacon,你的iOS设备可以在你接近或离开某个位置时提醒应用程序。除了监视你的位置,应用程序还可以知道你何时靠近iBeacon,就像零售店的收银台一样。iBeacon不使用纬度和经度来确定您的位置,而是使用由iOS设备检测到的蓝牙低能耗信号。

有关更多详细信息,请阅读Apple support for iBracon

希望这能有所帮助:)

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/37411765

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档