屏幕关闭时如何在 iOS 应用程序中检测 iBeacon?

Posted

技术标签:

【中文标题】屏幕关闭时如何在 iOS 应用程序中检测 iBeacon?【英文标题】:How to detect iBeacon in iOS app when screen is off? 【发布时间】:2015-12-28 05:24:37 【问题描述】:

在我的 ios 应用程序中,我仍在为屏幕关闭模式而使用 iBeacon 监控。

在我的实验中,当屏幕关闭时,委托方法“locationManager:didRangeBeacons:inRegion:”仍然会持续触发,但是,一旦屏幕关闭,信号就会相应消失(RSSI=0, beacon .accuracy=-1.0),然后,10 秒后,根本找不到信标。

我在this 帖子中发现了一些重要信息,称“iOS 以两种不同的方式使用信标:区域监控和信标测距。后者在后台不工作......,或者当应用程序终止时。

CLLocationManager 在进入区域时只会触发一次委托调用。如果您在该区域内开始监视该区域,则不会调用入口委托。您的应用必须手动调用 CLLocationManager 的 requestStateForRegion 方法。退出监控区域后,CLLocationManager 将在大约 30-45 秒后调用 didExitRegion。”

现在我尝试在屏幕关闭时连续调用“requestStateForRegion:”方法。结果是:

    如果我的 iPhone 已经在 iBeacon 区域,委托方法 “didDetermineState”连续给出“CLRegionStateInside”; 当我拿着 iPhone 走出 iBeacon 区域时,或者只是 关闭 iBeacon 的广告,30-45 秒后, 委托方法“didDetermineState”变为“CLRegionStateOutside” 并保持在“外部”状态; 当我拿着我的 iPhone 走进 iBeacon 区域,或者打开 iBeacon 的广告再次,委托方法 “didDetermineState”仍然连续给出“外部”并且从不 回到“内部”。

我需要的是,当屏幕关闭时,我可以在我的 iOS 设备进入 iBeacon 区域时立即检测到。寻求帮助...提前致谢。

【问题讨论】:

【参考方案1】:

您是否在您的info.plist 中添加了NSLocationAlwaysUsageDescription?我真的可以推荐你按照 this 教程来完成这一切。

【讨论】:

是的,我确实在 info.plist 中添加了密钥。 我也尝试并阅读了教程。它还没有解决我的问题。 我尝试了教程,发现它有同样的问题:只能捕获退出事件,但进入事件永远保持沉默。【参考方案2】:

当您开始监控时,总会有一个对didDetermineState 委托的初始调用。这就是您可以确定您是否已经在信标区域的方法。从那时起,您可以继续依赖didEnter/didExitdidDetermineState 也被称为这些)。唯一的问题是,如果用户关闭蓝牙然后重新打开——您将失去在此期间通常会发生的任何状态转换——所以在检测到蓝牙重新打开后致电requestState 是个好主意, 以了解当前状态。

总而言之,没有必要连续调用requestState,而且通常在屏幕锁定时你也不能这样做——iOS 会让你的应用进入睡眠状态,@987654321 @。除非您使用后台模式来保持应用程序在后台运行,但是当您提交应用程序以供审核时,您必须能够保护它,因为后台模式是为非常特定的用例保留的。 如果蓝牙处于关闭和打开状态,您应该依靠自动呼叫didEnter/didExit/didDetermineState,并辅以requestState

当我拿着我的 iPhone 走进 iBeacon 区域内,或者再次打开 iBeacon 的广告时,委托方法“didDetermineState”仍然持续给出“outside”,从不返回“inside”。

请记住,根据您的 iOS 设备的硬件功能(您没有提到您正在测试哪个设备),“enter”事件可能需要一段时间才能触发。 Radius 的人did some testing long time ago,iOS 7.1 上的 iPhone 4S 最多 15 分钟。那是 b/c iPhone 4S 不支持将 BLE 扫描卸载到蓝牙芯片,这与较新的 iPhone 型号不同。但即使在这些较新的型号上,也有可以将多少扫描卸载到芯片上的限制,Radius also measured to be 30(在 iOS 8.3 和 3 种不同的 iOS 设备上)。

【讨论】:

非常感谢。我的设备是 iPhone 5s。现在我删除了连续的“requestState”并转而捕捉“didEnter”/“didExit”委托方法。结果都是一样的,在屏幕关闭模式下,“didExit”可以被捕获但“didEnter”永远不会被触发,而后者是我真正需要的。 (假设大部分用例是 iPhone 在用户口袋中且屏幕关闭,当接近 iBeacon 时,应该触发推送通知,这依赖于及时捕获“didEnter”。)

以上是关于屏幕关闭时如何在 iOS 应用程序中检测 iBeacon?的主要内容,如果未能解决你的问题,请参考以下文章

是否可以在 JavaScript 中检测 Android 和 iOS 浏览器何时关闭屏幕

如何根据检测到颤振应用程序中的锁定或关闭屏幕采取行动

Android在后台运行任务时关闭屏幕

在 iOS 中,当用户滚动浏览 WKWebView 时,如何检测屏幕上可见的 html 元素?

如何以编程方式关闭/禁用 iOS 11 中引入的屏幕截图弹出框?

iOS屏幕关闭时如何继续监控iBeacon?