当前位置: 首页 > 知识库问答 >
问题:

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

周鸿云
2023-03-14

我有一个iBeacons应用程序能够在后台或不运行时范围内的信标。我实现了UILocal通知,它们工作正常,这意味着当我到达信标的范围时,我会收到通知。

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

  1. 有我的iPhone(与iBeacons应用程序关闭)在锁屏
  2. 激活我的iPad应用,广播信标A
  3. 我的iPhone反应显示我的通知
  4. 我停止iPad应用程序广播信标A,等待1秒,开始广播信标B
  5. 我的iPhone没有反应
  6. 我停止iPad广播
  7. 几分钟后(约2)我的iPhone向我显示beacon B的通知

现在我不明白的是这种延迟,我的iPhone第一次立即做出反应,第二次通知我灯塔需要大约2分钟。

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

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

这是一个可以解决的问题吗?

用一些代码编辑

这是我的viewDidLoad

- (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个信标)

-(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分钟的延迟。

大卫杨建议之后的编辑2

我修改了我的代码,正如你所说,信标A和B使用两个不同的区域,延迟总是空的。我也用你给的一段代码登录,我发现了这个。

  1. 广播区域\u 1的信标
  2. 设备向我显示区域\u 1的通知
  3. 停止广播区域\u 1的信标
  4. 日志显示我仍在该地区,几分钟后我才收到日志“OUTSIDEregion_1”,现在我可以重新播放广播,从region_1获得另一个通知

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

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

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

共有3个答案

禄俊逸
2023-03-14

大卫杨是正确的。第7条。1将在检测到信标区域遍历时终止时调用您的应用程序。但是,这一点非常关键,只有当您进入或退出信标区域,并且您的应用程序之前已为该特定信标区域注册了位置事件时,iOS才会调用终止的应用程序。

在上面的解释中,您似乎只监视一个信标区域(您没有指定主/辅编号,因此任何具有相同UUID的信标都符合条件)。不幸的是,您创建了两个具有相同UUID的信标发射机。因此,当您启动信标时,您收到一个通知(输入),但必须等待几分钟才能收到另一个通知(退出)。通常我会在信标停止传输30秒后看到退出通知。

如果要再次执行该实验,请尝试注册两个不同的信标区域(声明两个区域具有不同的主/次编号,或创建两个不同的UUID),然后在信标发射器中使用这两个不同的值。那就行了。汤姆

徐正雅
2023-03-14

看到代码后,我认为这里有几个问题:

>

测距回调中没有代码来检查哪个信标是可见的,因此似乎不可能确定是哪个信标引起了通知。即使传递给测距回调方法的信标数组为空(即没有检测到信标),通知也会触发。

测距一般在后台不起作用。唯一的例外是进入/退出区域后的几秒钟。我怀疑你报告的两分钟延迟是你的苹果手机为iBeacons执行下一次背景扫描所需的时间(根据手机状态,延迟可以是2分钟、4分钟或15分钟)。执行下一次扫描后,检测到区域转换(可能是退出区域通知,因为没有任何传输),测距开始5秒触发通知。

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

除了故障排除个别回调第一,我还建议:

  • 将代码更改为每个信标有一个区域,以获得最大的背景响应能力。
  • 将检测到的信标标识符放在通知中,这样你就知道信标导致了通知的触发。
尹俊雅
2023-03-14

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

根据您的描述,我无法解释此行为,但我怀疑安装程序可能存在问题,延迟了您的本地通知,或者在发送通知时错误地报告了信标区域B的状态。

有两件事有助于验证/消除这一可能的原因:

>

  • didDeterministEstate:forRegion:回调中添加NSLog语句,如下图所示,然后重复测试报告日志结果。

    // put this in your AppDelegate
    - (void)locationManager:(CLLocationManager *)manager didDetermineState:(CLRegionState)state forRegion:(CLRegion *)region
    {
        if(state == CLRegionStateInside) {
            NSLog(@"locationManager didDetermineState INSIDE for %@", region.identifier);
        }
        else if(state == CLRegionStateOutside) {
            NSLog(@"locationManager didDetermineState OUTSIDE for %@", region.identifier);
        }
        else {
            NSLog(@"locationManager didDetermineState OTHER for %@", region.identifier);
        }
    }
    

    发布设置监视并在检测时发出通知的代码。

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

    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

  •  类似资料:
    • 我目前正在编写一个应用程序,使用在2个或更多的手机之间传递小字符串的数据。 当前在前台,我正在传递:和。当应用程序位于前台时,我能够恢复(通过NSLog)通过CBAdvertisementDataLocalNameKey传递的字符串。 但是,当应用程序位于后台时,不会被传递。仍然与整数、和一起传递。 在梳理了一个似乎永无止境的叫做苹果文档的圈子后,我发现没有办法在应用程序处于后台时传递一个小字符串

    • 使用指定背景颜色和指定背景颜色有什么区别? 片段#1 片段#2

    • 问题内容: 如何在JPANEL上放置图像背景? 问题答案: 这是一个解释。

    • 背景色:rgb按照我的预期工作,但是背景:rgb填满了整个div。我看过的每个教程都告诉我,这两个基本相同,只是简写版可以有更多属性。 观看此视频以供参考。https://www.youtube.com/watch?v=10Q5D8kUMQo

    • 我想为游戏乒乓球创建一个简单的游戏菜单。在背景中有一个球在边缘反弹,只是为了看起来漂亮。现在我想在这个菜单屏幕上添加按钮。但是背景不再画了。所以我想画一个实时背景,但是按钮应该仍然留在前面。这个实时背景是用循环实现的。下面是GUI类和DrawStartMenueClass。 我听说过图层,但是每个人都在NetBeans中用某种工具来使用它们,我有日蚀,所以我没有那个机会。我想你可以把按钮和背景放在

    • 我正在我的网站上实现懒惰加载,但出于某种原因,当图像完全加载并显示时,图像位置会发生变化。 我曾尝试重新安排调用js和css文件的位置,但没有成功。 https://jsfiddle.net/f3q01ha5/3/ 这是没有懒惰加载和我想要的背景位置: 我已经附加了JSFIDLE,但请注意,我无法在这个网站上运行惰性加载,但在本地运行良好。 无论我是否使用延迟加载程序,我都希望背景图像加载到相同的