我发出的警报只有在手机移动一定距离后才会关闭(强迫用户下床)。我需要能够找到警报响起后行驶的距离,然后采取这个距离,并在一个方法中使用它,如果已经行进了最小距离,则关闭警报声。有任何想法吗? 我使用以下内容更新位置。有关如何将其纳入禁用警报的任何想法吗?
-(void)locationManager:(CLLocationManager *)manager didUpdateToLocation:(CLLocation *)newLocation fromLocation:(CLLocation *)oldLocation
{
if(!newLocation) {
NSLog(@"No movement");
}
if ((oldLocation.coordinate.latitude != newLocation.coordinate.latitude) &&
(oldLocation.coordinate.longitude != newLocation.coordinate.longitude))
{
CLLocation *loc1 = [[CLLocation alloc] initWithLatitude:oldLocation.coordinate.latitude longitude:oldLocation.coordinate.longitude];
CLLocation *loc2 = [[CLLocation alloc] initWithLatitude:newLocation.coordinate.latitude longitude:newLocation.coordinate.longitude];
CLLocationDistance distance = [loc2 distanceFromLocation:loc1];
if (distance>=4) {
NSLog(@"Very good!");
}
}
NSLog(@"Location:%@", newLocation);
}
-(void)locationManager:(CLLocationManager *)manager didFailWithError:(NSError *)error
{
NSLog(@"Could not find location: %@", error);
}
答案 0 :(得分:7)
有几点想法:
你没有考虑horizontalAccuracy
。首先,如果这对任一坐标都是负的,那么你就是不能做任何比较。即使它们都是非负的,如果你真的想确定用户是否移动了一定的距离,你可能想要退出水平精度。
不仅要查看纬度和经度,还要查看horizontalAccuracy
。
您不打算在开启定位服务时,经常会出现一系列坐标,当水平精度越来越好时,坐标可能会反弹。你想确保你不要把这种缓慢的三角测量视为有资格起床的必要运动。
确保您在真实场景中的真实设备上进行实验。使用模拟器绝对不是一个好的测试。也没有使用插入计算机的设备(因为您希望在真实世界的场景中看到您的GPS,有人在睡觉前移动过)。
我建议从一个简单的应用程序开始,该应用程序将位置事件记录在数据库(或其他格式)中,并可能在tableview中显示日志,因此您不必总是返回计算机审查结果。启动该应用程序,四处走动,然后查看您获得的位置事件。这可以帮助您掌握人们使用实际设备时所看到的模式。
请注意,如果此应用程序的目的地是应用程序商店,那么您将需要在不同的环境和不同的设备以及不同的场景(不良的GPS位置,无线网络,无线网络等)中吸引大量不同的人。 )。即使您使用物理设备进行自己的真实GPS体验,也必须明白其他人可能会遇到不同的GPS结果。
我必须承认iPhone GPS对于这类应用程序是否足够准确作为一种通用解决方案,你可能会警告用户确保在他们去之前插入他们的iPhone睡觉所以GPS不会耗尽电池。您可能还想玩一些技巧,例如在用户证明他们已经启动后即可启用位置服务。您可能甚至不想在闹钟响起前几分钟打开位置服务,从而确保GPS在闹钟响起时尽可能准确,但如果他们不睡觉则不会耗尽电池恰好插上电源并充电。
<强>更新强>
可能比自己计算距离更容易,使用位置服务距离过滤器(即仅当位置按 x 米变化时才生成事件)。例如:
- (void)startLocationManager
{
self.locationManager = [[CLLocationManager alloc] init];
self.locationManager.desiredAccuracy = kCLLocationAccuracyBest;
self.locationManager.distanceFilter = 5.0; // detect when I move 5 meters
self.locationManager.delegate = self;
[self.locationManager startUpdatingLocation];
}
当我这样做时,完全静止不动,一旦我打开位置服务,我就会在开始移动之前得到一大堆事件。您可以看到GPS预热,并且变得越来越准确:
latitude longitude horizontalAccuracy ---------------- ------------------ ------------------ 39.9482837548282 (82.4963494095571) 65 39.9482817585030 (82.4964543834170) 10 39.9482392622539 (82.4964914314290) 5 39.9481753502422 (82.4964918505242) 5 39.9481269028419 (82.4964797805836) 5
我等不及了(在我的情况下花了15-20秒),然后我开始走直线,看着距离我上面的最后一个位置的距离。
latitude longitude horizontalAccuracy distance ---------------- ------------------ ------------------ -------- 39.9481722908476 (82.4964962091138) 5 5.3 39.9482206544289 (82.4965029146363) 5 10.4 39.9482627315828 (82.4965282279839) 5 15.4 39.9483157471204 (82.4965248752227) 5 21.2
我必须承认,虽然我没有测量它,但这些距离感觉不太正确,但可能在我使用distanceFilter
设置的5米容差范围内。
无论如何,正如所有这些证据一样,正确的过程可能是
启用位置服务,设置适合您应用的distanceFilter
;
等待该地点安定下来;
确保水平准确度甚至可以使这个过程完全起作用;以及
根据GPS确定已超出distanceFilter
等待新位置通知。
这永远不会是完美的(例如,在我的“5米”distanceFilter
被踢之前,我必须走6-10米,这可能是GPS滞后几秒和{{1}的组合}),但它可能“对政府工作来说足够好。”
(顺便说一下,我在上面的日志中改变了我的坐标,所以不要在这个俄亥俄州的玉米地里寻找我,但它会让你知道你可能会看到的那种模式。)