【问题标题】:Why doesn't it find my beacons?为什么它找不到我的信标?
【发布时间】:2023-04-10 21:30:01
【问题描述】:

我正在编写需要在设备周围找到 BLE 信标的 Android 和 iOS 应用程序。

当我从 Android 运行我的代码时,它在我所在的房间里发现了几个信标。

我有 8 个信标。

当我从 iPhone 运行信标代码时,它会返回一个正好包含 0 个信标的列表。

这是我的代码:

    - (void)viewDidLoad
{
    [super viewDidLoad];
    // Do any additional setup after loading the view.
    self.locationManager = [[CLLocationManager alloc] init];
    self.locationManager.delegate = self;
    [self initRegion];
    [self locationManager:self.locationManager didStartMonitoringForRegion:self.beaconRegion];
}

- (void)locationManager:(CLLocationManager *)manager didStartMonitoringForRegion:(CLRegion *)region {
    [self.locationManager startRangingBeaconsInRegion:self.beaconRegion];
}

- (void)initRegion {
    NSUUID *uuid = [[NSUUID alloc] initWithUUIDString:BEACONUUID];
    self.beaconRegion = [[CLBeaconRegion alloc] initWithProximityUUID:uuid identifier:BEACONIDENTIFIER];
    [self.locationManager startMonitoringForRegion:self.beaconRegion];

}

- (void)locationManager:(CLLocationManager *)manager didEnterRegion:(CLRegion *)region {
    NSLog(@"Beacon Found");
    [self.locationManager startRangingBeaconsInRegion:self.beaconRegion];
}

-(void)locationManager:(CLLocationManager *)manager didExitRegion:(CLRegion *)region {
    NSLog(@"Left Region");
    [self.locationManager stopRangingBeaconsInRegion:self.beaconRegion];
    self.beaconFoundLabel.text = @"No";
}

-(void)locationManager:(CLLocationManager *)manager didRangeBeacons:(NSArray *)beacons inRegion:(CLBeaconRegion *)region {
    CLBeacon *beacon = [beacons lastObject];//<== is always 0

    self.beaconFoundLabel.text = @"Yes";
    self.proximityUUIDLabel.text = beacon.proximityUUID.UUIDString;
    self.majorLabel.text = [NSString stringWithFormat:@"%@", beacon.major];
    self.minorLabel.text = [NSString stringWithFormat:@"%@", beacon.minor];
    self.accuracyLabel.text = [NSString stringWithFormat:@"%f", beacon.accuracy];
    if (beacon.proximity == CLProximityUnknown) {
        self.distanceLabel.text = @"Unknown Proximity";
    } else if (beacon.proximity == CLProximityImmediate) {
        self.distanceLabel.text = @"Immediate";
    } else if (beacon.proximity == CLProximityNear) {
        self.distanceLabel.text = @"Near";
    } else if (beacon.proximity == CLProximityFar) {
        self.distanceLabel.text = @"Far";
    }
    self.rssiLabel.text = [NSString stringWithFormat:@"%ld", (long)beacon.rssi];
}

在我的didRangeBeaconsInRegion 中,信标NSArray 总是出现0 个对象。 虽然我有 8 个对象。而且我下载了几个不是我的应用程序,它们都看到了我的几个信标。

为什么我的代码看不到我的任何信标?

【问题讨论】:

  • 是否调用了任何信标委托方法?
  • 您是否指定了正确的区域 UUID?令人惊讶的是,其他应用会看到您的信标,除非您手动将区域 UUID 输入到它们中,或者它们实际上并没有读取 iBeacon 广告数据包,而只是检测信标的存在而没有获得一致的标识符。
  • @AntonijoDev 你能举一个“任何信标委托方法”的例子吗?
  • @ChrisStratton 是的,我指定了正确的 UUID。我从我拥有的校准应用程序中复制了它。
  • didEnterRegion、didExitRegion、didRangeBeacons...

标签: ios bluetooth-lowenergy ibeacon


【解决方案1】:

这是我在设置 iBeacon 应用程序时所做的事情。

并非所有这些都是必要的,但它会

  1. 工作
  2. 让您的用户满意
  3. (也许是最重要的)让 Apple 开心

仅限 iOS 8+

首先要做的事:如果您使用的是 iOS 8,则需要在使用 CLLocationManager 之前确保您确实拥有访问权限。

CLLocationManager *locationManager = [[CLLocationManager alloc] init];
locationManager.delegate = self;

// You can either use requestAlwaysAuthorization, or requestWhenInUseAuthorization
[self.locationManager requestAlwaysAuthorization];

您还需要在您的 plist 中输入 NSLocationAlwaysUsageDescription(同样,仅限 iOS 8)


iOS 7+

您应用的 pList

无论您使用的是 iOS 8 还是 7,您都应该将以下内容添加到您的 plist 文件中(您需要决定是否使用背景)。

注意:下面的形式是 KEY : KEY TYPE : VALUE 代表字符串,KEY : KEY TYPE : [ Value1, Value2... ] 代表数组

NSLocationUsageDescription : String : "Gimmie access to your location or else..."
NSBluetoothPeripheralUsageDescription : String : "Gimmie access to your blue tooth or else"

// Optionally supply if you need background modes.  I don't believe you need this either if you plan to turn these options on using the Capabilities section of your App's Settings (see below section)
UIBackgroundModes : Array : [ location, bluetooth-central ]
UIApplicationExitsOnSuspend : Boolean : NO



您应用的项目设置(功能)

此部分已被删除,因为这可能会导致您的应用被拒绝(如 cmets 中的 @heypiotr 所述)


最后的想法

最后的建议是尝试将[self locationManager:self.locationManager didStartMonitoringForRegion:self.beaconRegion] 移动到您的viewDidAppear

这是我通常做的一个例子(对我来说效果很好)。

-(void)viewDidAppear:(BOOL)animated {
    [super viewDidAppear:animated];

    [self initLocationManager];
    [self initBeaconRegion];
    [self startMonitoring];
}

-(void)initLocationManager {

    self.locationManager = [[CLLocationManager alloc] init];
    self.locationManager.delegate = self;

    // Not necessary, but I like to do it.
    if( ![CLLocationManager locationServicesEnabled] ) {
        [self.locationManager startUpdatingLocation];
    }

    // Only necessary if you're in iOS 8.  Checking for existence though to support iOS 7
    if( ![CLLocationManager authorizationStatus] != kCLAuthorizationStatusAuthorized ) {
        if ([CLLocationManager respondsToSelector:@selector(requestAlwaysAuthorization)]) {
            [self.locationManager performSelector:@selector( requestAlwaysAuthorization )];
        }
    }
}

-(void)initBeaconRegion {

    NSUUID *uuid = [[NSUUID alloc] initWithUUIDString:kYOUR_UUID_HERE];

    self.beaconRegion = [[CLBeaconRegion alloc] initWithProximityUUID:uuid identifier:kYOUR_IDENTIFIER_HERE];

    // Change this to whatever you want....
    self.beaconRegion.notifyEntryStateOnDisplay = YES;
    self.beaconRegion.notifyOnEntry = NO;
    self.beaconRegion.notifyOnExit = YES;
}


# pragma mark -
# pragma mark Monitoring Beacons
# pragma mark -

-(void)startMonitoring {
    // Monitor Beacon signals around me and report them back to me
    [self.locationManager startMonitoringForRegion:self.beaconRegion];
}

最后一部分(viewDidAppear 中的位置)可能有帮助,也可能没有帮助 - 这完全取决于我想在 stackoverflow 响应中要考虑的因素太多。

希望对您有所帮助,祝您好运!

最终编辑

忘记了另外一件可能有帮助的事情。您可以实施一些有用的方法来帮助您进一步调试问题。以下是其中一些示例:

#pragma mark Authorization Status Changed
-(void)locationManager:(CLLocationManager *)manager didChangeAuthorizationStatus:(CLAuthorizationStatus)status {

    if( ![CLLocationManager locationServicesEnabled] ) {
        NSLog(@"Couldn't turn on ranging: Location services are not enabled.");
    } else {
        NSLog(@"Location services ARE enabled.");
    }

    if( [CLLocationManager authorizationStatus] != kCLAuthorizationStatusAuthorized ) {
        NSLog(@"Couldn't turn on monitoring: Location services not authorized.");
    } else {
        NSLog(@"Location services ARE authorized.");
    }
}


#pragma mark -
#pragma mark CLLocationManager Errors
#pragma mark -

-(void)locationManager:(CLLocationManager *)manager didFailWithError:(NSError *)error {
    NSLog( @"FAIL ERROR: %@", [error description] );
}

-(void)locationManager:(CLLocationManager *)manager rangingBeaconsDidFailForRegion (CLBeaconRegion *)region withError:(NSError *)error {
    NSLog( @"RANGE BEACONS ERROR: %@", [error description] );
}

【讨论】:

  • 只是想说这个答案非常详细,并且在几个月前我需要它时很有帮助。我当时投了赞成票(不知道为什么在撰写本文时只有两个人投了赞成票)。如果我可以多次投票,我会的!
  • 谢谢 Eric,我很感激,很高兴能帮上忙!
  • 非常有帮助!不过有一条评论——实际上不需要后台模式才能在后台进行信标监控,“始终”授权访问定位服务就足够了。并且在不需要时启用后台模式通常会导致应用在 App Store 提交审核期间被拒绝。
  • 这是一个很好的观点 heypiotr(我不知道)。我认为在发帖时,这是我可以让它始终如一地工作的唯一方法。不过我会从回复中删除它 - 谢谢!
【解决方案2】:

首先检查其他应用,例如。Locate app 添加您的 UDID 并检查此应用是否显示您的 iBeacon。如果不是,那么苹果 IOS 有时会出现问题。然后删除该应用程序。重新启动应用程序。它会为你工作。

【讨论】:

    【解决方案3】:

    我们之前遇到过类似的问题,请确保您的 iBeacon 设备响应来自 iOS 的扫描请求,响应中不包含制造商特定字段。

    【讨论】:

      【解决方案4】:

      请查看苹果的这条说明

      在尝试监控任何区域之前,您的应用应检查当前设备是否支持区域监控。以下是区域监控可能不可用的一些原因:

      1. 设备没有必要的硬件来支持区域 监控。
      2. 用户拒绝了应用程序使用区域监控的授权。

      3. 用户在“设置”应用中禁用了定位服务。

      4. 用户在“设置”应用中为设备或您的应用禁用了后台应用刷新。

      5.设备处于飞行模式,无法启动必要的硬件。

      在 iOS 7.0 及更高版本中,始终在尝试监视区域之前调用 CLLocationManagerisMonitoringAvailableForClass:authorizationStatus 类方法。 (在 OS X v10.8 及更高版本以及之前的 iOS 版本中,请改用 regionMonitoringAvailable 类。)isMonitoringAvailableForClass: 方法告诉您底层硬件是否支持指定类的区域监视。如果该方法返回 NO,则您的应用无法在设备上使用区域监控。如果返回YES,调用authorizationStatus方法判断应用当前是否被授权使用定位服务。如果授权状态为kCLAuthorizationStatusAuthorized,则您的应用可以接收其注册的任何区域的越界通知。如果授权状态设置为任何其他值,则应用程序不会收到这些通知。 Apple link goes here

      【讨论】:

      • 在指定信标管理器为ESTBeaconManager *beaconManager 的区域[self.beaconManager startRangingBeaconsInRegion:staticRegion]; [self.beaconManager startMonitoringForRegion:motionRegion]; 后,您能否尝试使用此功能;
      猜你喜欢
      • 1970-01-01
      • 2010-10-19
      • 1970-01-01
      • 1970-01-01
      • 2010-09-26
      • 1970-01-01
      • 2010-12-16
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多