当应用程序未运行(终止/终止)时,如何保持核心位置和核心蓝牙运行?
Posted
技术标签:
【中文标题】当应用程序未运行(终止/终止)时,如何保持核心位置和核心蓝牙运行?【英文标题】:How to keep Core Location and Core Bluetooth running when app is not running (killed/ terminated)? 【发布时间】:2017-07-26 04:43:19 【问题描述】:如果我终止应用程序,我在尝试保持我的功能运行时卡住了。
是否可以在应用未运行时保持核心位置(地理围栏/地理定位)和核心蓝牙运行?如果可能的话如何解决我的问题?我已经检查了后台模式,并实现了核心定位方法。 这是我的代码:
class AppDelegate: UIResponder, UIApplicationDelegate, CLLocationManagerDelegate
var viewController = ViewController()
var window: UIWindow?
var locationManager = CLLocationManager()
func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplicationLaunchOptionsKey: Any]?) -> Bool
locationManager = CLLocationManager()
locationManager.requestAlwaysAuthorization()
locationManager.delegate = self
locationManager.distanceFilter = kCLDistanceFilterNone
locationManager.desiredAccuracy = kCLLocationAccuracyBest
locationManager.pausesLocationUpdatesAutomatically = false
if #available(ios 9.0, *)
locationManager.allowsBackgroundLocationUpdates = true
beaconRegion.notifyEntryStateOnDisplay = true
beaconRegion.notifyOnEntry = true
beaconRegion.notifyOnExit = true
locationManager.startMonitoring(for: beaconRegion)
locationManager.stopRangingBeacons(in: beaconRegion)
locationManager.startRangingBeacons(in: beaconRegion)
locationManager.startUpdatingLocation()
return true
func locationManager(_ manager: CLLocationManager, didEnterRegion region: CLRegion)
if (region.identifier == beaconRegionIdentifier)
manager.requestState(for: region)
goBackground()
func locationManager(_ manager: CLLocationManager, didExitRegion region: CLRegion)
print("you exited region")
func locationManager(_ manager: CLLocationManager, didDetermineState state: CLRegionState, for region: CLRegion)
if (region.identifier == beaconRegionIdentifier)
manager.stopUpdatingLocation()
switch state
case .inside:
manager.startRangingBeacons(in: region as! CLBeaconRegion)
manager.startUpdatingLocation()
case .outside:
let delay = DispatchTime.now() + .seconds(3)
DispatchQueue.main.asyncAfter(deadline: delay)
manager.requestState(for: region)
case .unknown:
let delay = DispatchTime.now() + .seconds(3)
DispatchQueue.main.asyncAfter(deadline: delay)
manager.requestState(for: region)
func locationManager(_ manager: CLLocationManager, didRangeBeacons beacons: [CLBeacon], in region: CLBeaconRegion)
let state = UIApplication.shared.applicationState
switch(state)
case.active,
.inactive,
.background:
let mainView = UserDefaults.standard.bool(forKey: "toMainView")
var isWakeUpRunning = UserDefaults.standard.bool(forKey: "isWakeUpRunning")
if isWakeUpRunning
if mainView
for aBeacon in beacons
if aBeacon.rssi > WAKE_UP_THRESHOLD && aBeacon.rssi != 0
UserDefaults.standard.set(false, forKey: "isWakeUpRunning")
self.viewController.startFunction()
manager.stopRangingBeacons(in: region)
else if aBeacon.rssi != 0 && aBeacon.rssi < WAKE_UP_THRESHOLD
manager.stopRangingBeacons(in: region)
manager.requestState(for: region)
else
manager.stopRangingBeacons(in: region)
manager.requestState(for: region)
func goBackground()
let app = UIApplication.shared
var bgTask: UIBackgroundTaskIdentifier = 0
bgTask = app.beginBackgroundTask(expirationHandler:
NSLog("Expired: %lu", bgTask)
app.endBackgroundTask(bgTask)
)
NSLog("Background: %lu", bgTask)
根据我的代码,它可以在前台和后台运行。但是当我从任务切换器向上滑动应用程序时,它无法工作。而且我也无法从 xcode 中看到日志。有什么想法可以帮助我吗?
【问题讨论】:
你需要使用 startMonitoringRegion 已经实现 【参考方案1】:一旦您从任务切换器向上滑动应用程序,您的应用程序将被终止,但 CoreLocation 仍将在操作系统级别为您工作,寻找与您所在地区匹配的信标:
locationManager.startMonitoring(for: beaconRegion)
一旦该区域发生变化(didEnter 或 didExit),您的应用将重新启动到后台。此时将依次调用以下方法:
application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplicationLaunchOptionsKey: Any]?)
locationManager(_ manager: CLLocationManager, didEnterRegion region: CLRegion)
届时您的应用将继续在后台运行。因为您的应用会启动一个后台任务,所以这会持续 180 秒,然后才会暂停。
但是,您的应用不会在从屏幕滑出到下一次区域转换发生之间运行。这是您能做的最好的事情。
【讨论】:
如果我的应用程序是通过退出一个区域启动的(在它被终止之后),我会在里面做locationManager.startUpdatingLocation
,而我在后台模式下启用了位置......会我的位置工作 180 或无限期? 2. 如果应用程序在后台或暂停中保持活动状态,但由于某种原因我的位置跟踪被操作系统暂停(即没有被我暂停),我是否能够无限期恢复位置跟踪或再次 180 秒?
(1) 你的位置会在区域进入/退出时再次开始更新,如果你成功获得了后台运行的权限,它将无限期地继续运行,就像应用程序从未被杀死一样. (2) 我不确定您如何建议暂停跟踪。例如,如果用户关闭了位置信息,那么不,您的应用将无法恢复跟踪,直到用户重新打开位置信息。
被locationManagerDidPauseLocationUpdates
回调暂停
根据文档here,该方法在位置不变时被调用。之后,您的应用可能会再次调用 locationManager.startUpdatingLocation
。我认为这与您是否在后台无关。以上是关于当应用程序未运行(终止/终止)时,如何保持核心位置和核心蓝牙运行?的主要内容,如果未能解决你的问题,请参考以下文章