iOS:后台定位应用耗电过多
iOS: Background location app using too much battery
我有一个应用程序,每行驶 25 米,每 2 分钟在后台获取一次位置更新。我的问题是,虽然位置跟踪工作正常,但它严重耗尽了我的电池。 24 小时内的电池使用率为 30%,而我下一个最接近的应用程序为 14%。是否有一些技巧可以减少我的应用程序的电池使用量,同时保持我的位置更新的准确性和时间段?
会不会因为调用 didUpdateLocations: 的频率而耗尽电池电量?还是每次位置更新时我都在后台与 Web 服务通信?我真的不知道如何提高电池使用率,非常感谢任何帮助!
下面是我在 AppDelegate 中获取位置和向服务器发送更新的代码:
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
self.locationManager = [CLLocationManager new];
[self.locationManager setDelegate:self];
if ([self.locationManager respondsToSelector:@selector(requestAlwaysAuthorization)]) {
[self.locationManager requestAlwaysAuthorization];
}
[self.locationManager startUpdatingLocation];
[self.locationManager startMonitoringSignificantLocationChanges];
[self initializeRegionMonitoring];
}
-(void) initializeRegionMonitoring {
self.locationManager = [[CLLocationManager alloc] init];
self.locationManager.delegate = self;
// notify changes when the device has moved x meters
self.locationManager.distanceFilter = 25; // or set to 20 meters
self.locationManager.desiredAccuracy = kCLLocationAccuracyNearestTenMeters;
[self.locationManager startUpdatingLocation];
[self.locationManager startMonitoringSignificantLocationChanges];
}
- (void)locationManager:(CLLocationManager *)manager didUpdateLocations:(NSArray *)locations {
NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults];
NSDate *lastDate = [defaults objectForKey:@"lastSavedDate"];
if ([[NSDate date] timeIntervalSinceDate:lastDate] < 120) {
NSLog(@"LAST SAVE TIME LESS THAN 2 MINUTES");
return;
}
[self saveLocation];
//tell the centralManager that you want to deferred this updatedLocation
if (isBackgroundMode && !_deferringUpdates)
{
NSLog(@"THIS IS GETTING CALLED EVERY TIME");
_deferringUpdates = YES;
[self.locationManager allowDeferredLocationUpdatesUntilTraveled:CLLocationDistanceMax timeout:120];
}
}
- (void) locationManager:(CLLocationManager *)manager didFinishDeferredUpdatesWithError:(NSError *)error {
_deferringUpdates = NO;
}
-(void) saveLocation {
// This code saves location data to a web service
}
- (void)applicationWillResignActive:(UIApplication *)application {
isBackgroundMode = YES;
[self.locationManager stopUpdatingLocation];
[self.locationManager setDesiredAccuracy:kCLLocationAccuracyNearestTenMeters];
[self.locationManager setDistanceFilter:25];
self.locationManager.pausesLocationUpdatesAutomatically = NO;
self.locationManager.activityType = CLActivityTypeAutomotiveNavigation;
[self.locationManager startUpdatingLocation];
}
-(BOOL)application:(UIApplication *)application willFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
[[UIApplication sharedApplication] setMinimumBackgroundFetchInterval:UIApplicationBackgroundFetchIntervalMinimum];
return true;
}
-(void)application:(UIApplication *)application performFetchWithCompletionHandler:(void (^)(UIBackgroundFetchResult))completionHandler {
[self saveLocation];
completionHandler(UIBackgroundFetchResultNewData);
NSLog(@"Fetch completed");
}
[self.locationManager setDesiredAccuracy:kCLLocationAccuracyNearestTenMeters];
[self.locationManager setDistanceFilter:25];
将这些属性更改为不太准确。您可以节省大量电池。
这些配置取决于它是什么类型的应用程序。如果它是某种卡路里燃烧应用程序,它可能会更准确。您每 2 分钟更新一次,因此应将其设置为具有某个阈值的时间覆盖的近似距离的平均值。
self.locationManager.pausesLocationUpdatesAutomatically=YES;
//monitor locations for significant location change
[self.locationManager startMonitoringSignificantLocationChanges];
如果您的应用不需要用户的准确位置,您可以尝试使用显着的位置更改,这是更优化内存的方式,但最终取决于具体情况,更重要的是高位置精度或电池用法。我已经对这种方法进行了重要测试,通常它每 4-5 分钟或 500 米更新一次位置,以最早者为准。
我有一个应用程序,每行驶 25 米,每 2 分钟在后台获取一次位置更新。我的问题是,虽然位置跟踪工作正常,但它严重耗尽了我的电池。 24 小时内的电池使用率为 30%,而我下一个最接近的应用程序为 14%。是否有一些技巧可以减少我的应用程序的电池使用量,同时保持我的位置更新的准确性和时间段?
会不会因为调用 didUpdateLocations: 的频率而耗尽电池电量?还是每次位置更新时我都在后台与 Web 服务通信?我真的不知道如何提高电池使用率,非常感谢任何帮助!
下面是我在 AppDelegate 中获取位置和向服务器发送更新的代码:
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
self.locationManager = [CLLocationManager new];
[self.locationManager setDelegate:self];
if ([self.locationManager respondsToSelector:@selector(requestAlwaysAuthorization)]) {
[self.locationManager requestAlwaysAuthorization];
}
[self.locationManager startUpdatingLocation];
[self.locationManager startMonitoringSignificantLocationChanges];
[self initializeRegionMonitoring];
}
-(void) initializeRegionMonitoring {
self.locationManager = [[CLLocationManager alloc] init];
self.locationManager.delegate = self;
// notify changes when the device has moved x meters
self.locationManager.distanceFilter = 25; // or set to 20 meters
self.locationManager.desiredAccuracy = kCLLocationAccuracyNearestTenMeters;
[self.locationManager startUpdatingLocation];
[self.locationManager startMonitoringSignificantLocationChanges];
}
- (void)locationManager:(CLLocationManager *)manager didUpdateLocations:(NSArray *)locations {
NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults];
NSDate *lastDate = [defaults objectForKey:@"lastSavedDate"];
if ([[NSDate date] timeIntervalSinceDate:lastDate] < 120) {
NSLog(@"LAST SAVE TIME LESS THAN 2 MINUTES");
return;
}
[self saveLocation];
//tell the centralManager that you want to deferred this updatedLocation
if (isBackgroundMode && !_deferringUpdates)
{
NSLog(@"THIS IS GETTING CALLED EVERY TIME");
_deferringUpdates = YES;
[self.locationManager allowDeferredLocationUpdatesUntilTraveled:CLLocationDistanceMax timeout:120];
}
}
- (void) locationManager:(CLLocationManager *)manager didFinishDeferredUpdatesWithError:(NSError *)error {
_deferringUpdates = NO;
}
-(void) saveLocation {
// This code saves location data to a web service
}
- (void)applicationWillResignActive:(UIApplication *)application {
isBackgroundMode = YES;
[self.locationManager stopUpdatingLocation];
[self.locationManager setDesiredAccuracy:kCLLocationAccuracyNearestTenMeters];
[self.locationManager setDistanceFilter:25];
self.locationManager.pausesLocationUpdatesAutomatically = NO;
self.locationManager.activityType = CLActivityTypeAutomotiveNavigation;
[self.locationManager startUpdatingLocation];
}
-(BOOL)application:(UIApplication *)application willFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
[[UIApplication sharedApplication] setMinimumBackgroundFetchInterval:UIApplicationBackgroundFetchIntervalMinimum];
return true;
}
-(void)application:(UIApplication *)application performFetchWithCompletionHandler:(void (^)(UIBackgroundFetchResult))completionHandler {
[self saveLocation];
completionHandler(UIBackgroundFetchResultNewData);
NSLog(@"Fetch completed");
}
[self.locationManager setDesiredAccuracy:kCLLocationAccuracyNearestTenMeters];
[self.locationManager setDistanceFilter:25];
将这些属性更改为不太准确。您可以节省大量电池。 这些配置取决于它是什么类型的应用程序。如果它是某种卡路里燃烧应用程序,它可能会更准确。您每 2 分钟更新一次,因此应将其设置为具有某个阈值的时间覆盖的近似距离的平均值。
self.locationManager.pausesLocationUpdatesAutomatically=YES;
//monitor locations for significant location change
[self.locationManager startMonitoringSignificantLocationChanges];
如果您的应用不需要用户的准确位置,您可以尝试使用显着的位置更改,这是更优化内存的方式,但最终取决于具体情况,更重要的是高位置精度或电池用法。我已经对这种方法进行了重要测试,通常它每 4-5 分钟或 500 米更新一次位置,以最早者为准。