首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >背景中的iBeacons测距有时会有延迟

背景中的iBeacons测距有时会有延迟
EN

Stack Overflow用户
提问于 2014-05-04 16:45:24
回答 3查看 2.7K关注 0票数 4

我有一个iBeacons应用程序,可以在后台或不运行时对信标进行测距。我实现了UILocalNotifications,它们工作得很好,这意味着当我到达信标的范围时会收到通知。

没有真正的信标,我创建了一个应用程序(对于另一个设备,假设下一个场景是一个iPad ),它的作用类似于两个不同的信标,这意味着它可以播放两个不同的信号,相同的UUID值,但不同的Major/Minor值(称为信标A和B),很明显,一次广播一个信号。我的问题是在这种情况下:

  1. 将我的iPhone (关闭iBeacons应用程序)放在锁定屏幕上
  2. 激活我的iPad应用程序,广播信标A
  3. 我的iPhone反应显示了一个通知
  4. 我从广播信标A停止iPad应用程序,等一下,开始广播信标B
  5. 我的iPhone 没有的反应
  6. 我阻止iPad广播
  7. 几分钟后(大约2),我的iPhone向我展示了信标B的通知。

现在我不明白的是,这个延迟,当我的iPhone第一次立即反应,第二次需要大约2分钟通知我的信标。

如果在通知信标B之后,我重新开始广播一个信标(A或B),我的iPhone会立即响应,那么下一次它总是等待2分钟。

为什么会发生这种情况?我读过一些文章说,这是因为蓝牙每2-4分钟醒来一次,而应用程序在后台,所以我可以得到的信息不超过这一次。但是我看不出有什么意义,因为每当我收到第二次通知--信标的广播(在我的场景中是B)--已经停止了,这意味着如果蓝牙在那一刻醒来,空中就没有信标!但是我收到了通知,所以这意味着我的iPhone在我停止广播之前找到了它。

这是可以解决的问题吗?

使用一些代码进行编辑

这是我的viewDidLoad

代码语言:javascript
复制
- (void)viewDidLoad
{
    [super viewDidLoad];

    // Initialize location manager and set ourselves as the delegate and beacons dictionary
    _beacons = [[NSMutableDictionary alloc] init];
    self.locationManager = [[CLLocationManager alloc] init];
    self.locationManager.delegate = self;

    // Create a NSUUID with the same UUID as the broadcasting beacon
    NSUUID *uuid = [[NSUUID alloc] initWithUUIDString:@"6C1AA496-1653-403D-BD1E-7F630AA6F254"];

    // Setup a new region with that UUID and same identifier as the broadcasting beacon
    self.myBeaconRegion = [[CLBeaconRegion alloc] initWithProximityUUID:uuid
                                                             identifier:@"testregion"];

    NSLog(@"startMonitoring");
    // Tell location manager to start monitoring for the beacon region
    [self.locationManager startMonitoringForRegion:self.myBeaconRegion];
    [self.locationManager startRangingBeaconsInRegion:self.myBeaconRegion];

    _myBeaconRegion.notifyEntryStateOnDisplay = YES;

    // Check if beacon monitoring is available for this device
    if (![CLLocationManager isMonitoringAvailableForClass:[CLBeaconRegion class]]){
        UIAlertView *alert = [[UIAlertView alloc] initWithTitle:@"Monitoring not available" message:nil delegate:nil cancelButtonTitle:@"Ok" otherButtonTitles: nil]; [alert show]; return;
    }

}

现在,每当我收到一个信标,我就发送一个通知,我只想尝试一下它是如何工作的,所以我还没有实现发送一个通知的方法,这意味着我得到了大约9个通知,每秒1个通知,这就是代码在后台运行的活动时间(1秒进入区域,9个信标范围)。

代码语言:javascript
复制
-(void)locationManager:(CLLocationManager*)manager
       didRangeBeacons:(NSArray*)beacons
              inRegion:(CLBeaconRegion*)region
{
    if([[UIApplication sharedApplication] applicationState] == UIApplicationStateBackground){
        UILocalNotification *notification = [[UILocalNotification alloc] init];
        notification.alertBody = @"Found Beacon";
        notification.soundName = @"Default";
        [[UIApplication sharedApplication] presentLocalNotificationNow:notification];
    }
}

实际上,更具体的是,如果我完全关闭我的应用程序的多任务视图,或只是让它的背景,当我开始广播一个信标,我得到通知**S**(1秒的延迟)。然后停止广播和重播,延迟就成了分钟的顺序。

现在,对于一个真实的场景,我应该在同一个地方有许多信标,只要我收到通知,而我已经远离信标本身,这个延迟可能是个问题。

我的代码有问题吗?我读了那些文章,但从来没有发现有15分钟的延误。

达维杨建议后的EDIT2

我修改了我的代码,正如您所说,对于信标A和B,使用两个不同的区域,延迟总是为空。我还记录了您给出的代码,我发现了这一点。

  1. 广播Region_1信标
  2. 设备显示了Region_1的通知
  3. 停止广播Region_1的信标
  4. 日志上说我还在这个地区,只有几分钟后我才得到“Region_1外”的日志,现在我可以重播广播,从Region_1那里得到另一个通知。

所以我对此很好奇,我读了http://beekn.net/2014/03/apple-ios-7-1-launches-major-ibeacon-improvement/的文章

作者说,在iOS 7.1中,退出某个区域的响应是即时的,实际上我运行了7.1,但我也有几分钟的延迟。为什么要这样?你在考试中发现同样的问题了吗?

现在,我读到一个设备只能监听20个区域,对吗?这意味着,如果我有100个信标,我只可以设置20个区域,并将这100个区域分成20个组,收到的通知不超过20个(假设这100个区域位于同一位置,都在我的设备范围内)?这可能是一个问题,因为这将迫使用户在前台运行应用程序来获取所有信息(假设100个信标中的每一个都有一个特定的单元角色),对吗?

EN

回答 3

Stack Overflow用户

回答已采纳

发布于 2014-05-04 21:21:20

编辑:这是我在看到代码之前的第一个答案.

我无法根据您的描述解释此行为,但我怀疑设置可能存在问题,即延迟本地通知或在发送通知时不准确地报告信标区域B的状态。

有两件事将有助于核实/消除这一可能的原因:

  1. 将NSLog语句添加到didDetermineState: forRegion:回调中,如下所示,然后重复报告日志结果的测试。 //将其放入您的AppDelegate -(CLLocationManager*)管理器didDetermineState:(CLRegionState)CLRegionState forRegion:(CLRegion *)区域{ if(state == CLRegionStateInside) {NSLog(“locationManager didDetermineState in in for %@",region.identifier);} if(state == CLRegionStateOutside) { NSLog(@"locationManager == put for %@”);} OTHER {(@in 20 OTHER for %@),;}}
  2. 发布设置监视的代码,并在检测时发出通知。

如果您还没有读过这篇文章,您可能需要快速查看一下我为测量背景检测时间所做的类似测试:

http://developer.radiusnetworks.com/2013/11/13/ibeacon-monitoring-in-the-background-and-foreground.html

http://developer.radiusnetworks.com/2014/03/12/ios7-1-background-detection-times.html

票数 3
EN

Stack Overflow用户

发布于 2014-05-05 04:18:22

在看了代码之后,我认为这里出现了一些问题:

  1. 代码只定义了包含信标A和信标B的单个区域,防止独立区域进入/退出监视回调,并在从发射信标A切换到信标B时阻止手机被唤醒。这一点至关重要,因为这意味着如果您从发射信标A切换到信标B,iOS将考虑自己仍然位于一个区域。这可以防止手机获得监控事件,这将唤醒手机的背景。
  2. 在远程回调中没有代码来检查哪个信标是可见的,因此似乎不可能确定是哪个信标导致了通知。即使传递给测距回调方法的信标数组为空(即没有检测到信标),通知也会触发。
  3. 在背景中,测距一般不起作用。唯一的例外是在进入/退出某个区域之后的几秒钟内。我怀疑您报告的两分钟延迟是iPhone对iBeacons执行下一次背景扫描所需的时间(根据电话状态的不同,此延迟可能为2、4或15分钟)。在执行下一次扫描之后,将检测到一个区域转换(可能是一个退出区域通知,因为没有任何传输),并且测距启动5秒触发一个通知。

如果不直接记录我在第一个答复中提到的监视区域回调以及测距回调,以及记录检测到的信标的标识符,这一切都非常困难。确保您了解这些回调中的哪一个是按哪个信标发出的,并且不要试图一次排除太多故障!

除了首先对单个回调进行故障排除之外,我还建议:

  • 将代码更改为每个信标有一个区域,以获得最大的背景响应能力。
  • 将检测到的信标标识符放入通知中,以便您知道信标会引发通知。
票数 2
EN

Stack Overflow用户

发布于 2014-05-05 14:07:35

DavidGYoung是正确的。当探测到信标区域遍历时,iOS7.1将调用您的应用程序。但是,这一点很关键,只有当您进入或退出信标区域时,iOS才会调用终止的应用程序,而且只有在您的应用程序之前已经注册了该特定信标区域的位置事件时,才会调用该应用程序。

在上面的解释中,看起来您只是在监视一个信标区域(您没有指定主要/次要数字,因此任何具有相同UUID的信标都有资格)。不幸的是,您使用相同的UUID创建了两个信标发射器。因此,当您启动信标时,您将得到一个通知(输入),但必须等待几分钟以等待另一个通知(退出)。通常情况下,在信标停止传输后30秒左右,我就会看到退出通知。

如果您想再次执行实验,请尝试注册两个不同的信标区域(使用diff主/小数声明两个区域,或制作两个diff UUID),然后在信标发射机中使用这两个diff值。应该会起作用的。汤姆

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

https://stackoverflow.com/questions/23458821

复制
相关文章

相似问题

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