7

我使用 CoreLocation 在我的应用程序上发现了一个奇怪的行为。我正在使用区域监控功能,但是在授权定位服务(通过弹出窗口或设置->定位服务)后,区域监控失败(操作无法完成。kCLErrorDomain 错误 5.)。如果我关闭应用程序并重新启动(因此已经授权),一切都会按预期工作。我的代码如下所示:

-(void)initializeLocationServices
{
    NSLog(@"Started location services");

    locationManager = [[CLLocationManager alloc] init];
    locationManager.delegate = self;
    locationManager.distanceFilter = kCLDistanceFilterNone;
    locationManager.desiredAccuracy = kCLLocationAccuracyBestForNavigation;
    locationManager.pausesLocationUpdatesAutomatically = NO;

    [locationManager startUpdatingLocation]; // to show authorisation popup
}

-(CLCircularRegion*)createRegion
{   
    // Test coordinates
    CLLocationDegrees latitude = 50;
    CLLocationDegrees longitude = -1;
    CLLocationDistance radius = 50; // meters;

    // If radius is too large, registration fails automatically, so limit the radius to the maximum value
    if (radius > locationManager.maximumRegionMonitoringDistance) {
        radius = locationManager.maximumRegionMonitoringDistance;
    }

    CLCircularRegion* region = [[CLCircularRegion alloc] initWithCenter:CLLocationCoordinate2DMake(latitude, longitude) radius:radius identifier:@"TEST"];

    region.notifyOnEntry = YES;
    region.notifyOnExit = YES;

    NSLog(@"Created region");

    return region;
}

-(void)monitorProximity
{
    CLRegion *region = [self createRegion];

    // Check if support is unavailable
    if ( ![CLLocationManager isMonitoringAvailableForClass:[CLRegion class]]) {
        NSLog( @"Failed to initialise region monitoring: support unavailable");
        return;
    }

    // Check if authorised
    if ([CLLocationManager authorizationStatus] != kCLAuthorizationStatusAuthorized) {
        NSLog( @"Failed to initialise region monitoring: app not authorized to use location services");
        return;
    } else {
        NSLog(@"Started monitoring proximity");
    }


    // Clear out any old regions to prevent buildup.
    if ([locationManager.monitoredRegions count] > 0) {
        for (id obj in locationManager.monitoredRegions)
            [locationManager stopMonitoringForRegion:obj];
    }

    [locationManager startMonitoringForRegion:region];
}

-(void)locationManager:(CLLocationManager *)manager didStartMonitoringForRegion:(CLRegion *)region
{
    NSLog(@"Started monitoring for region: %@", [region description]);
    [locationManager requestStateForRegion:region]; // check if already inside region
}

-(void)locationManager:(CLLocationManager *)manager monitoringDidFailForRegion:(CLRegion *)region withError:(NSError *)error
{
    NSLog(@"Failed to start monitoring for region: %@", [error localizedDescription]);
}


-(void)locationManager:(CLLocationManager *)manager didDetermineState:(CLRegionState)state forRegion:(CLRegion *)region
{
    NSLog(@"didDetermineState");

    if (state == CLRegionStateInside) {

        NSLog(@"inside");
        return;


    } else if (state == CLRegionStateOutside) {
        NSLog(@"outside");

    } else {
        NSLog(@"unknown");
    }

}

-(void)locationManager:(CLLocationManager *)manager didEnterRegion:(CLRegion *)region
{
    NSLog(@"didEnterRegion");
}

-(void)locationManager:(CLLocationManager *)manager didExitRegion:(CLRegion *)region
{
    NSLog(@"didExitRegion");
}

-(void)locationManager:(CLLocationManager *)manager didChangeAuthorizationStatus:(CLAuthorizationStatus)status
{
    NSLog(@"Monitoring authorisation status is now: %@", status == kCLAuthorizationStatusAuthorized ? @"authorized" : @"not authorized");

    if (status == kCLAuthorizationStatusAuthorized) {
        [self monitorProximity];
    }
}

我在这里做错了吗?调用 didChangeAuthorizationStatus 后,我的流程是否有问题?

4

3 回答 3

8

其他用户报告来看,区域监控失败似乎kCLErrorDomain 5是“包罗万象”;它没有提供太多有用的信息。我相信您的问题是由线路引起的

[locationManager requestStateForRegion:region]; // check if already inside region

您从委托方法内部调用的didStartMonitoringForRegion:

我在我自己的项目中看到了一些非常相似的东西,并且把这条线去掉(或延迟它的执行一段时间)解决了这个问题。我最好的猜测是,当这个委托方法触发时,iOS 仍在运行一些内部区域监控代码,所以现在不是调用的合适时间requestStateForRegion:

试着把它拿出来,看看它是否是答案。

于 2014-09-01T20:24:27.213 回答
1

kCLErrorDomain 代码/错误 5 表示您已尝试监控超过 20 个 CLRegions。描述在这里

startMonitoringForRegion描述它说:
一个应用程序一次最多可以注册 20 个区域。为了及时报告区域变化,区域监控服务需要网络连接。

于 2014-03-14T14:29:44.493 回答
1

kCLErrorDomain 5是一个抓住所有可能意味着许多不同事物的东西。

其中一个来源是当[locationManager requestStateForRegion:region]您第一次监视某个区域以了解您是否已经在该区域时,这是必要的。这是因为 didEnter 区域只有在您实际进入该区域时才会被调用。通常这意味着您第一次监视该区域时,您必须等待 5 秒钟,直到未检测到该区域,然后才会在您下次进入该区域时触发 didEnter region。

关于问题的原因有许多不同的报告:

然而,这些都不适合我。我认为我的根本原因类似于 iOS 7.1 错误,它只是随机停止在某些设备上工作。我尝试了重新启动和重新启动蓝牙,没有任何帮助。

不知道发生了什么变化,但我第二天又试了一次,它开始工作了。

基本上,您可能想尝试不同的设备,直到该设备再次开始工作。

于 2018-08-21T05:06:02.530 回答