我想获得用户位置,即使用户不使用app.now我可以在按下主页按钮后获得位置并且应用程序进入后台状态,但在几秒钟位置更新停止后。当我针对stoped杀死应用程序位置更新时。这是我在app delegate中的代码。
let locationManager = CLLocationManager()
var LatitudeGPS = String()
var LongitudeGPS = String()
var speedGPS = String()
var Course = String()
var Altitude = String()
var bgtimer = Timer()
func applicationDidEnterBackground(_ application: UIApplication) {
self.doBackgroundTask()
}
func beginBackgroundUpdateTask() {
backgroundUpdateTask = UIApplication.shared.beginBackgroundTask(expirationHandler: {
self.endBackgroundUpdateTask()
})
}
func endBackgroundUpdateTask() {
UIApplication.shared.endBackgroundTask(self.backgroundUpdateTask)
self.backgroundUpdateTask = UIBackgroundTaskInvalid
}
func doBackgroundTask() {
DispatchQueue.global(qos: .background).async {
self.beginBackgroundUpdateTask()
self.StartupdateLocation()
self.bgtimer = Timer.scheduledTimer(timeInterval: 30, target: self, selector: #selector(self.bgtimer(timer:)), userInfo: nil, repeats: true)
RunLoop.current.add(self.bgtimer, forMode: RunLoopMode.defaultRunLoopMode)
RunLoop.current.run()
self.endBackgroundUpdateTask()
}
}
func bgtimer(timer:Timer!){
print("Fired from Background ************************************")
updateLocation()
}
func StartupdateLocation() {
locationManager.delegate = self
locationManager.startUpdatingLocation()
locationManager.desiredAccuracy = kCLLocationAccuracyBest
locationManager.distanceFilter = kCLDistanceFilterNone
locationManager.requestAlwaysAuthorization()
locationManager.allowsBackgroundLocationUpdates = true
locationManager.pausesLocationUpdatesAutomatically = false
}
func updateLocation() {
locationManager.startUpdatingLocation()
locationManager.stopUpdatingLocation()
print("Latitude: \(LatitudeGPS)")
print("Longitude: \(LongitudeGPS)")
print("Speed: \(speedGPS)")
print("Heading: \(Course)")
print("Altitude BG: \(Altitude)")
DispatchQueue.main.async {
print(UIApplication.shared.backgroundTimeRemaining)
}
}
func locationManager(_ manager: CLLocationManager, didUpdateLocations locations: [CLLocation]) {
LatitudeGPS = String(format: "%.10f", manager.location!.coordinate.latitude)
LongitudeGPS = String(format: "%.10f", manager.location!.coordinate.longitude)
speedGPS = String(format: "%.3f", manager.location!.speed)
Altitude = String(format: "%.3f", manager.location!.altitude)
Course = String(format: "%.3f", manager.location!.course)
}
}
我认为几秒钟后我的应用程序终止并且位置更新停止了。 我希望在20分钟后应用程序终止(操作系统或用户)停止更新位置以保持电池充电。 我的位置更新问题在哪里。
答案 0 :(得分:8)
要改变一些事情。
第1步:
确保您已在项目的功能部分启用了位置更新后台模式,如下所示
第2步:
当我针对stoped。
杀死应用位置更新时
引用苹果文档
在上述陈述中要注意的重要事项是如果您启动此服务并且您的应用随后被终止,则 如果是新的,系统会自动将应用重新启动到后台 事件到了。在这种情况下,选项字典传递给了 application(:willFinishLaunchingWithOptions :)和 应用程序的应用程序(:didFinishLaunchingWithOptions :)方法 delegate包含指示您的应用程序所在的关键位置 由于位置事件而启动。重新启动后,您仍然必须 配置位置管理器对象并调用此方法继续 接收位置事件。当您重新启动位置服务时, 当前事件立即传递给您的代表。此外, 填充您的位置管理器对象的位置属性 在您开始定位之前,使用最新的位置对象 服务。
重新启动后,您仍然必须配置位置管理器对象 调用此方法继续接收位置事件。
意思是,您当前的位置管理器用处不大,您应该创建一个新的实例并配置新实例并再次调用startMonitorSignificantLocationChanges
。
因此,只有在您使用startMonitoringSignificantLocationChanges
时,iOS才会向已终止的应用发送位置更新。
所有这些仅适用于您的应用已终止并且iOS在接收位置更新时重新启动它。但是,如果您的应用只是在后台,则无需使用startMonitorSignificantLocationChanges
startUpdatingLocation
仅在app处于后台/前台模式时才有效。如果您的应用被暂停或被杀,iOS将停止更新位置。
如果您启动此服务并且您的应用已暂停,则系统会停止 交付事件,直到您的应用程序再次开始运行(在...中) 前景或背景)。如果您的应用程序被终止,则交付 新的位置事件完全停止。因此,如果您的应用需要 要在后台接收位置事件,它必须包括 其Info.plist中的UIBackgroundModes键(具有位置值) 文件。
所以修改你的代码
locationManager.startMonitoringSignificantLocationChange()
好的是关于startMonitoringSignificantLocationChanges
和startupdatinglocation
的正确使用。现在计时代码中的错误。
错误1:
self.bgtimer = Timer.scheduledTimer(timeInterval: 30, target: self, selector: #selector(self.bgtimer(timer:)), userInfo: nil, repeats: true)
使用计时器及时获取位置更新。那不是它的工作方式!你不能永远运行Timer。一旦您的应用程序暂停或终止,计时器就会停止。位置管理器会在位置更改时通知应用,您应该只依赖它。您无法运行计时器以及时检查位置更新。它不会在暂停或终止状态下运行。
错误2:
func updateLocation() {
locationManager.startUpdatingLocation()
locationManager.stopUpdatingLocation()
为什么在后续语句中启动和停止更新位置?这没有多大意义。
错误3:
func StartupdateLocation() {
locationManager.delegate = self
locationManager.startUpdatingLocation()
您的StartupdateLocation
被多次调用,每次调用此方法时,您都会在同一个位置管理器实例上重复调用startUpdatingLocation
。你不需要那样做!您只能拨打startUpdatingLocation
或startMonitoringSignificantLocationChange
一次。