gpt4 book ai didi

iphone - CLLocationManager 有没有可能被其他应用影响?

转载 作者:可可西里 更新时间:2023-11-01 06:12:15 27 4
gpt4 key购买 nike

我遇到了一个非常奇怪的情况,我有一个应用程序使用 CLLocationManager 来获取用户的当前位置。我正在使用与 Apple 的 CLLocationManager 示例代码非常相似的包装类。它开始寻找位置,并一直等待,直到获得满足某些条件(时间戳年龄、准确性)的位置。当我在一个 GPS 非常方便的区域时,一切都很好。

现在是问题。当我在办公室使用 WiFi 连接时,GPS 信号似乎很差,我打开我的应用程序,但它永远找不到合适的位置。我退出我的应用程序,打开 Foursquare,它几乎立即找到了我附近的地方,让我假设它已经找到了我的位置。我退出 Foursquare,然后重新打开我的应用程序,发现它几乎立即找到了我的位置。

任何人都可以阐明这里可能发生的事情吗?如果人们认为这会有帮助,我可以发布一些代码,但这是一个更普遍的问题,关于其他应用程序如何对 CLLocationManager 的功能产生积极或消极的影响。理想情况下,我很想知道 Foursquare 究竟做了什么才能如此快速地获取位置,以及这可能如何导致我的应用程序突然也开始获取位置。

编辑:根据下面的答案,似乎人们已经体验过跨应用缓存,这很好。但是,它没有解释为什么 Foursquare 获取位置而我的应用程序仅在使用 Foursquare 后才获取位置。下面是我的 CLLocationManager 代码,希望有人能找到确凿的证据:

- (void) lazyInit {
if (!self.locationManager) {
self.locationManager = [[CLLocationManager alloc] init];
self.locationManager.delegate = self;
self.locationManager.desiredAccuracy = kCLLocationAccuracyHundredMeters;
self.reverseGeocoder = [[WPGeocodingService alloc] initWithDelegate:self];
self.locationAndPlacemark = NO;
}
}

- (void) getCurrentLocation {
[self lazyInit];
self.recentLocation = nil;
[self performSelector:@selector(timeoutLocationFetch) withObject:nil afterDelay:kLocationFetchTimeout];
[self.locationManager startUpdatingLocation];
}

- (void)locationManager:(CLLocationManager *)manager didUpdateToLocation:(CLLocation *)newLocation fromLocation:(CLLocation *)oldLocation {
NSLog(@"LocationService:update: <%f,%f> Accuracy: %f", newLocation.coordinate.latitude, newLocation.coordinate.longitude,
newLocation.horizontalAccuracy);

// test the age of the location measurement to determine if the measurement is cached
// in most cases you will not want to rely on cached measurements
NSTimeInterval locationAge = -[newLocation.timestamp timeIntervalSinceNow];
if (locationAge > 5.0) return;

// test that the horizontal accuracy does not indicate an invalid measurement
if (newLocation.horizontalAccuracy < 0) return;

// test the measurement to see if it is more accurate than the previous measurement
if (self.recentLocation == nil || self.recentLocation.horizontalAccuracy > newLocation.horizontalAccuracy) {
// store the location as the "best effort"
self.recentLocation = newLocation;
// test the measurement to see if it meets the desired accuracy
//
// IMPORTANT!!! kCLLocationAccuracyBest should not be used for comparison with location coordinate or altitidue
// accuracy because it is a negative value. Instead, compare against some predetermined "real" measure of
// acceptable accuracy, or depend on the timeout to stop updating. This sample depends on the timeout.
//
if (newLocation.horizontalAccuracy <= self.locationManager.desiredAccuracy) {
// we have a measurement that meets our requirements, so we can stop updating the location
//
// IMPORTANT!!! Minimize power usage by stopping the location manager as soon as possible.
//
[self.locationManager stopUpdatingLocation];
// we can also cancel our previous performSelector:withObject:afterDelay: - it's no longer necessary
[NSObject cancelPreviousPerformRequestsWithTarget:self selector:@selector(timeoutLocationFetch) object:nil];

if ([self.delegate respondsToSelector:@selector(locationService:didReceiveLocation:)]) {
[self.delegate locationService:self didReceiveLocation:self.recentLocation];
}
}
}
}

- (void)locationManager:(CLLocationManager *)manager didFailWithError:(NSError *)error {
NSLog(@"LocationService:error: %@", [error description]);
if ([error code] != kCLErrorLocationUnknown) {
[self.locationManager stopUpdatingLocation];
if ([self.delegate respondsToSelector:@selector(locationService:didFailWithError:)]) {
[self.delegate locationService:self didFailWithError:error];
}
}
}

- (void) timeoutLocationFetch {
NSLog(@"LocationService:timeout");
[self.locationManager stopUpdatingLocation];
if (self.recentLocation && [self.delegate respondsToSelector:@selector(locationService:didReceiveLocation:)]) {
if ([self.delegate respondsToSelector:@selector(locationService:didReceiveLocation:)]) {
[self.delegate locationService:self didReceiveLocation:self.recentLocation];
}
} else {
NSError* error = [NSError errorWithDomain:@"Location Error" code:0 userInfo:
[NSDictionary dictionaryWithObject:@"The application could not determine your location." forKey:NSLocalizedDescriptionKey]];
if ([self.delegate respondsToSelector:@selector(locationService:didFailWithError:)]) {
[self.delegate locationService:self didFailWithError:error];
}
}
}

最佳答案

你为什么要用

self.locationManager.desiredAccuracy = kCLLocationAccuracyHundredMeters

而不是kCLLocationAccuracyBest?当然,如果不将水平精度与此进行比较,正如您自己注意到的那样, 常量 - 但取而代之的是一些合理的其他值(比如 100.0m)。您是否尝试过它是否有所作为?

所需的精度控制在位置获取中投入的精力(对于更高的值,GPS 甚至不会打开,您可以使用 Xcode/Instruments/EnergyDiagnostics 进行检查)。更少的努力会导致准确性降低和/或获得职位的时间更长。这听起来不合理吗?

根据我自己的观察:当要求 iOS 提供具有特定所需精度的位置时,结果可以是任何结果:不太准确(即在 GPS 接收不良的建筑物中),如所需的那样准确,或者实际上比需要(另一个应用程序或同一应用程序的另一个 CLlocationManager 对象可能同时要求硬件提供更高的精度 - 然后所有其他应用程序无需额外努力即可继承更好的值)。

除上述之外,它可能会影响您的 iOS 设备是否正在访问互联网,因为它是一个辅助 GPS 接收器。如果设备由于某些其他互联网事件而恰好在线,则下载一些辅助数据可能会产生某种副作用。不过,最后一个想法纯属猜测。

还有一点:如果我没有在您的代码中忽略它,那么您还没有定义距离过滤器。尝试类似的东西

self.locationManager.distanceFilter = kCLDistanceFilterNone;

确保您获得尽可能多的更新。

关于iphone - CLLocationManager 有没有可能被其他应用影响?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/8943854/

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com