当检测到信标时,locationManager:didEnterRegion未被调用

17

在测试使用信标(iOS设备)时,我发现监听信标出现了一些意外的行为。即使信标进入区域,locationManager:didEnterRegion 方法也没有被调用。但是 locationManager:didRangeBeacons:inRegion: 被正确地调用,并且检测到的信标在那里显示。有人经历过类似的情况吗?


在苦苦挣扎了1.5天后,我发现问题出在飞行模式上。如果打开飞行模式,iBeacon的范围定位可以完美工作,但是监控却不能。很遗憾没有任何错误提示。 - bpolat
4个回答

33

请检查您的方法是否按照以下方式实现。 在viewDidLoad中,从结尾开始监视。

self.beaconRegion.notifyOnEntry=YES;
self.beaconRegion.notifyOnExit=YES;
self.beaconRegion.notifyEntryStateOnDisplay=YES;
[self.locationManager startMonitoringForRegion:self.beaconRegion];

开始监控后,请请求您定义的区域的状态。

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

确定状态后,开始对信标进行测距

-(void)locationManager:(CLLocationManager *)manager didDetermineState:(CLRegionState)state forRegion:(CLRegion *)region
{
    if (state == CLRegionStateInside)
    {
        //Start Ranging
        [manager startRangingBeaconsInRegion:self.beaconRegion];
    }
    else
    {
        //Stop Ranging here
    }
}

根据您的需求实现以下方法...

- (void)locationManager:(CLLocationManager *)manager didEnterRegion:(CLRegion *)region
{
    self.statusLbl.text=@"Entered region";
}

-(void)locationManager:(CLLocationManager *)manager didExitRegion:(CLRegion *)region
{
    self.statusLbl.text=@"Exited region";
}

-(void)locationManager:(CLLocationManager *)manager didRangeBeacons:(NSArray *)beacons inRegion:(CLBeaconRegion *)region
{
    if(beacons.count>0)
    {}
}

希望这能解决你的问题。


惊人的解释。非常感谢你。 - MeV
2
didEnterRegion: 方法中,我们不应该再次分配 CLLocationManager 吗?因为调用可能来自后台。 - Pedro Góes
需要记住的一件事是,即使您从前台调用此方法,应用程序的位置权限也必须设置为“始终”。 - Jakub
进入区域和离开区域没有被调用。 - Anita Nagori

12
before starting coding in project , you must follow given setup guidlines -->
1. in project info or info.plist -->
         Custom IOS Target Properties -->
                    . add "Required background modes"
                    . in this add two items -->
                                ."App shares data using CoreBluetooth"
                                ."App registers for location updates"
2. in project Capability -->
         There is Background Modes  
                   . check "Loaction update"  
                   . check "Acts as a Bluetooth LE accessory"
                   . check "uses bluetooth LE accessories"

请遵循Davidgyoung先生的指示。相信我,它一定会起作用。


如果您的应用程序是BLE中心,则需要在“所需后台模式”中设置“使用CoreBluetooth进行应用程序通信”。如果您的应用程序是BLE外设,则需要设置“使用CoreBluetooth共享数据的应用程序”。 - mezulu
我已经添加了每个,但仍然没有进入区域方法被调用。 - Anita Nagori

8
你还需要意识到,你是在监测一个区域而不是特定的信标。
因此,如果你有三个共享相同proximityUUID的信标,并且你的区域定义为仅包含proximityUUID(没有major和minor值),那么只有以下两种情况会通知你:
1. 区域内没有信标处于范围内,然后第一个信标被发现(didEnterRegion:)。 2. 一个或多个区域内的信标在范围内,然后全部不再可见约30秒(didExitRegion:)。

7
没有更多关于您测试的起始条件的具体信息,很难说是否看到了完全相同的情况。但是,在某些特定情况下,即使没有调用locationManager:didEnterRegion,也会调用locationManager:didRangeBeacons:inRegion。
如果您同时使用相同区域进行范围和监视,并且iOS认为您已经在监视的区域中,则可能不会调用locationManager:didEnterRegion。
要真正测试是否出现问题,您需要设置一个测试用例,其中:
1. 确保您不在该区域内。 2. 让iOS运行几分钟。 3. 开始监视该区域。 4. 让iOS继续运行几分钟。 5. 进入该区域。 6. 查看是否调用了locationManager:didEnterRegion。
如果您在执行上述步骤后仍然没有收到调用,那么肯定有问题。

我在进入该区域后开始传输。这种情况下应该调用...对吧?一旦我通过停止传输退出该区域,然后再次开始传输,它就像预期的那样工作(didEnterRegion被调用)。 - Dhanesh KM
不管你认为自己是否进入了该区域都无所谓。重要的是iOS LocationManager的想法,而它的当前状态对你来说是不可见的。在开始监视时,您需要确保它百分之百地认为自己尚未进入您定义的区域,因为如果它认为自己已经进入该区域,则可能不会收到回调。这就是为什么我建议上面的程序-它确保iOS在测试开始时将您识别为位于该区域之外。 - davidgyoung
让我换个方式问...如果你报告的问题是可重复的,那么你在评论中说的有效的情况和在原始帖子中说的无效的情况有什么区别?你是否重新启动了手机?你是否等待了更长的时间?重复失败需要什么条件? - davidgyoung
@davidgyoung 我的didEnterRegion代理没有被调用?你能告诉我如何检测我哪里出了问题吗? - iYoung
我遇到了同样的问题,并发现从iOS8开始,我们必须处理 requestAlwaysAuthorization 或 requestWhenInUseAuthorization 来获取位置信息。同时,我们还必须将 NSLocationAlwaysUsageDescription 或 NSLocationWhenInUseUsageDescription 添加到 info.plist 中。 - tokentoken

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接