我正在编写需要在设备周围找到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个物体。我已经下载了几个不属于我的应用程序,他们都看到了我的几个信标。
为什么我的代码不能看到我的任何信标?
答案 0 :(得分:2)
这是我在设置iBeacon应用程序时所做的事情。
并非所有这些都是必要的,但它会
首先要做的事情是:如果您使用的是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 8还是7,都应该将以下内容添加到plist文件中(您需要决定是否使用背景)。
注意: 以下是KEY的形式:KEY TYPE:VALUE表示字符串,KEY:KEY TYPE:[Value1,Value2 .. 。] for Arrays :
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
此部分已被删除,因为这可能导致您的应用被拒绝(正如@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] );
}
答案 1 :(得分:1)
首先检查其他应用,例如。Locate app添加您的UDID并检查此应用是否显示您的iBeacon。如果没有那么苹果IOS有时会出现问题。然后删除该应用程序。重启应用。它会对你有用。
答案 2 :(得分:0)
我们之前遇到过类似的问题,请确保您的iBeacon设备响应来自iOS的扫描请求,但不包含制造商特定字段。
答案 3 :(得分:0)
请查看苹果的这个说明
在尝试监控任何区域之前,您的应用应检查当前设备是否支持区域监控。以下是可能无法进行区域监控的一些原因:
用户拒绝了应用授权使用区域监控。
用户在“设置”应用中停用了位置服务。
用户在设置应用中为设备或应用禁用了后台应用刷新。
5.设备处于飞行模式,无法为必要的硬件供电。
在iOS 7.0及更高版本中,在尝试监控区域之前,始终调用isMonitoringAvailableForClass:
的{{1}}和authorizationStatus
类方法。 (在OS X v10.8及更高版本以及之前版本的iOS中,请改用CLLocationManager
类。)regionMonitoringAvailable
方法告诉您底层硬件是否支持指定类的区域监视。如果该方法返回NO,则您的应用无法在设备上使用区域监控。如果返回YES,则调用authorizationStatus方法以确定该应用程序当前是否有权使用位置服务。如果授权状态为isMonitoringAvailableForClass:
,您的应用可以接收其注册的任何地区的过境通知。如果授权状态设置为任何其他值,则应用程序不会收到这些通知。
Apple link goes here