所以我正在处理iPhone GPS的一些准确性问题.我有一个使用位置的应用程序.
在委托方法中,locationManager: didUpdateToLocation: fromLocation:我正在返回一个位置.从一些研究来看,似乎GPS在返回的第一个结果上并不总是准确的,即使设置desiredAccuracy属性也是如此kCLLocationAccuracyBest.
为了解决这个问题,我不会stopUpdatingLocation在它返回newLocation:至少3次之前打电话(这很快).我还玩过两个关于是否stopUpdatingLocation返回的"要求" newLocation.我尝试的一种方法是检查lat和long newLocation并进行比较oldLocation,如果这些不相同,则保持位置更新运行.我也试图与检查之间的距离oldLocation和newLocation,如果它小于20米,它的罚款.这两个都是通过返回至少3次运行来测试的.后一种方式不那么"严格",因为如果用户在移动的车辆中,newLocation并且oldLocation很难与100%完全相同.
现在,我的问题是,即使在进行上述操作时(基本上不接受某个位置,直到发生一些更新并CLLocationManager检查CLLocations它们之间的距离(或者它们是否相同),我仍然看到有时奇怪的位置结果,在测试时.
如果我离开应用程序,进入Maps.app,使用GPS,然后打开多任务处理,强制退出我的应用程序,然后重新打开它以获得干净的启动,有时会修复.
人们习惯于解决同类问题的经验和可能的解决方案?评论和解决方案赞赏:)
这是我的代码......
-(void)locationManager:(CLLocationManager *)manager didUpdateLocations:(NSArray *)locations
{
location_updated = [locations lastObject];
NSLog(@"updated coordinate are %@",location_updated);
latitude1 = location_updated.coordinate.latitude;
longitude1 = location_updated.coordinate.longitude;
self.lblLat.text = [NSString stringWithFormat:@"%f",latitude1];
self.lblLon.text = [NSString stringWithFormat:@"%f",longitude1];
NSString *str = [NSString stringWithFormat:@"https://maps.googleapis.com/maps/api/geocode/json?latlng=%f,%f&sensor=false",latitude1,longitude1];
url = [NSURL URLWithString:str];
NSURLRequest *request = [NSURLRequest requestWithURL:url];
connection = [NSURLConnection connectionWithRequest:request delegate:self];
if (connection)
{
webData1 = [[NSMutableData alloc]init];
}
GMSMarker *marker = [[GMSMarker alloc] init];
marker.position = CLLocationCoordinate2DMake(latitude1,longitude1);
marker.title = formattedAddress;
marker.icon = [UIImage imageNamed:@"m2.png"];
marker.map = mapView_;
marker.draggable = YES;
}
Run Code Online (Sandbox Code Playgroud)
这个方法多次调用,我不想......
我一直试图找出如何在应用程序终止时获取用户的位置,就像应用程序Moves一样.我知道这样做的唯一方法是使用重要的位置更改.但是,如果位置发生重大变化,应用程序每隔500米就会被唤醒,并且只有在最后一次更新后大约5分钟才会被唤醒.
根据Apple的说法:
只要设备从之前的通知移动500米或更长时间,应用就会收到通知.它不应该比每五分钟更频繁地预期通知.如果设备能够从网络检索数据,则位置管理器更有可能及时发送通知.
在Moves应用程序中,即使应用程序终止,它也能够非常准确地检索用户的位置,而不会有太多的电池排水.它似乎也没有打开背景位置,因为它在电池使用列表中的原因仅显示"背景活动".所以我想知道像Moves这样的应用程序是如何做到这一点的.任何帮助都会很棒!谢谢.
我有一个实现的视图控制器CLLocationManagerDelegate.我创建了一个CLLocationManager变量:
let locationManager = CLLocationManager()
Run Code Online (Sandbox Code Playgroud)
然后在viewDidLoad,我设置属性:
// Set location manager properties
locationManager.delegate = self
locationManager.desiredAccuracy = kCLLocationAccuracyHundredMeters
locationManager.distanceFilter = 50
Run Code Online (Sandbox Code Playgroud)
问题是,即使在我检查授权状态之前,函数也会被调用.
func locationManager(manager: CLLocationManager!, didChangeAuthorizationStatus status: CLAuthorizationStatus) {
if (status == .AuthorizedWhenInUse) {
// User has granted autorization to location, get location
locationManager.startUpdatingLocation()
}
}
Run Code Online (Sandbox Code Playgroud)
谁能告诉我可能导致这种情况发生的原因?
我在viewDidLoad中有以下循环:
for(int i=1; i<[eventsArray count]; i++) {
NSArray *componentsArray = [[eventsArray objectAtIndex:i] componentsSeparatedByString:@","];
if([componentsArray count] >=6) {
Koordinate *coord = [[Koordinate alloc] init];
coord.latitude = [[componentsArray objectAtIndex:0] floatValue];
coord.longtitude = [[componentsArray objectAtIndex:1] floatValue];
coord.magnitude = [[componentsArray objectAtIndex:2] floatValue];
coord.depth = [[componentsArray objectAtIndex:3] floatValue];
coord.title = [componentsArray objectAtIndex:4];
coord.strasse = [componentsArray objectAtIndex:5];
coord.herkunft = [componentsArray objectAtIndex:6];
coord.telefon = [componentsArray objectAtIndex:7];
coord.internet = [componentsArray objectAtIndex:8];
[eventPoints addObject:coord];
}
Run Code Online (Sandbox Code Playgroud)
coord是CLLocationCoordinate2D
但是我如何在下面的方法中使用coord,因为我需要这个以获得两个坐标之间的距离:
- (void)locationManager:(CLLocationManager *)manager
didUpdateToLocation:(CLLocation *)newLocation
fromLocation:(CLLocation *)oldLocation{
}
Run Code Online (Sandbox Code Playgroud)
请帮帮我,我被困了!
谢谢大家事先帮忙
我正在尝试设置一个应用程序,该应用程序可以在后台检查人员的位置,查看他们是否位于给定位置,如果是,则将ping发送到服务器.我们不想耗尽用户的精力,因此我们试图找出最佳解决方案.
我已经做了大量阅读,但我没有找到关于这些方法的大量信息.我会理解他们现在理解的优点和缺点
startMonitoringForSignificantChanges
描述:基于Wi-Fi和蜂窝塔的变化,系统唤醒了应用程序.
文件:
只要设备从之前的通知移动500米或更长时间,应用就会收到通知.它不应该比每五分钟更频繁地预期通知.如果设备能够从网络检索数据,则位置管理器更有可能及时发送通知.
优点:
缺点:
10分钟的开始更新或"n分钟更新":
描述:这基本上要求应用程序有更多时间,当额外时间即将到期时,它调用[self.locationManager startUpdating],抓取位置并将后台线程扩展10分钟.
优点:
缺点:
问题:这对电池有什么影响?唤醒GPS并将其关闭会对电池造成更大伤害吗?我无法想象在后台运行一个简短的位置检查会耗尽电池那么多......但话又说回来,我不知道是什么导致GPS启动并获得可用的信号.
startMonitoringForRegion(geo-fencing):
简而言之,当您进入预定义区域时,您的应用会被唤醒.这是他们的古怪,它是最新的,并且有较少的文档.我无法找到关于"系统如何监控"过境点的良好描述.据我所知,这是一些非常聪明的算法,或者他们不断地对GPS进行ping操作,这会使其效率低于其他方法.
优点:
缺点:
我想我的问题归结为startMonitoringForRegion:与电池寿命,一致性和精确度相比,在后台测试用户位置的其他方法.有没有人彻底测试过这个?或者在他们的应用程序中使用它并获得至少一些反馈?可能,就我的目的而言,权衡是在地理围栏和10分钟更新方法之间.(同样考虑到Apple公开谈论的iOS7会有一些后台任务......这会改变这两种方法之间权衡的微积分吗?)有没有人知道这两者的比较方式?
非常感谢!期待看到我们是否可以深入了解如何比较这些方法.
我的输入是纬度和经度.我需要使用reverseGeocodeLocationswift 的功能,给我一个本地的输出.我尝试使用的代码是
println(geopoint.longitude)
println(geopoint.latitude)
var manager : CLLocationManager!
var longitude :CLLocationDegrees = geopoint.longitude
var latitude :CLLocationDegrees = geopoint.latitude
var location: CLLocationCoordinate2D = CLLocationCoordinate2DMake(latitude, longitude)
println(location)
CLGeocoder().reverseGeocodeLocation(manager.location, completionHandler: {(placemarks, error) -> Void in
println(manager.location)
if error != nil {
println("Reverse geocoder failed with error" + error.localizedDescription)
return
}
if placemarks.count > 0 {
let pm = placemarks[0] as CLPlacemark
println(pm.locality)
}
else {
println("Problem with the data received from geocoder")
}
Run Code Online (Sandbox Code Playgroud)
在我得到的日志中
//-122.0312186
//37.33233141
//C.CLLocationCoordinate2D
//fatal error: unexpectedly found …Run Code Online (Sandbox Code Playgroud) 问题:我似乎无法停止Core Location向我的应用/跟踪发送更新.
我在做什么:在我的viewWillAppear调用中self.locationManager,将其传递给一个方法,以显示用户在地图上的位置(实例MKMapView).重写getter以检查服务器的可用性,以查看是否已授权.如果是这样,它allocs/inits和startMonitoringSignificantLocationChanges和returns.
在viewDidDisappear,我打电话[self.locationManager stopUpdatingLocation].但我仍然可以在状态栏中看到位置图标.即使我通过双击主页按钮并关闭它来终止应用程序,图标仍然存在...即使在延长的时间(10分钟以上)之后.当我转到设置应用程序时,它告诉我我的应用程序仍在使用位置服务(紫色图标).
问题:我在这里错过了什么?为什么位置更新不会停止?
提前致谢.
我创建了一个简单的应用程序,它可以跟踪用户位置,并在每次更新位置时创建本地通知.
我启用了下面的背景模式,
let locationManager = CLLocationManager()
open override func viewDidLoad() {
locationManager.delegate = self;
locationManager.desiredAccuracy = kCLLocationAccuracyBest;
locationManager.distanceFilter = 10
locationManager.allowsBackgroundLocationUpdates = true
locationManager.startUpdatingLocation()
}
open func locationManager(_ manager: CLLocationManager, didUpdateLocations locations: [CLLocation]) {
let notification = UILocalNotification()
notification.alertBody = "location updated"
notification.fireDate = Date()
UIApplication.shared.scheduleLocalNotification(notification)
}
Run Code Online (Sandbox Code Playgroud)
我设置字符串NSLocationAlwaysUsageDescription并请求许可.用户授予第一次加载应用时始终使用的权限.
当应用程序处于前台时它运行良好,当背景仍然工作至少在5-40分钟的时间范围内,可以通过电池或其他打开的应用程序进行更改.
问题是为什么它停止工作,它不会继续工作?
我从未在Apple文档中看到时间限制.
从iOS 12开始,CLLocationManager不再在后台运行.应用程序在随机时间没有崩溃日志的情况下终止.这在iOS 12之前运行良好.
为了演示这个问题,我在这里创建了一个示例应用程序
演示应用程序只是启动CLLocationManager并在后台运行它.在后台运行时,我们通过记录它来跟踪它.问题是应用程序被iOS终止.创建演示应用程序以演示此问题.
重现步骤
结果:
随机时间后应用程序无任何理由终止.
预期结果:
它应该如何工作
这是Apple工程师证实的:
一旦CLLocationManager更新在前台启动并且您完成了让它在后台运行的所有工作,位置更新应该在后台运行,直到: