ios - 区域监控(地理围栏)会消耗电池电量 (iOS)

标签 ios objective-c iphone cocoa-touch cllocationmanager

我在我的应用程序中实现了 CLLocationManager 的区域监控功能,它可以工作,但会耗尽我的电池:

-

Image

-

应该是这样吗?

我的代码:

monitorLocationViewController.m(请滚动查看完整代码):

-(void)locationManager:(CLLocationManager *)manager didUpdateLocations:(NSArray<CLLocation *> *)locations
{
    //If "allStores"(NSMutableArray) isn't nil - calling "locationChangeHandler" to update monitoring
    if (self.allStores!=nil) {
        [self locationChangeHandler];
    }

    CLLocation *currentLocation=(CLLocation*)[locations lastObject];
    NSSet *monitoredRegionsSet=self.locationManager.monitoredRegions;
    [monitoredRegionsSet enumerateObjectsUsingBlock:^(CLCircularRegion *region, BOOL *stop) {
        if ([region containsCoordinate:currentLocation.coordinate]) {
            [self.locationManager stopMonitoringForRegion:region];
            [self locationManager:self.locationManager didEnterRegion:region];
        }
    }];
}

-(void)locationManager:(CLLocationManager *)manager didEnterRegion:(CLRegion *)region
{
     Store *store=[self storeForRegion:region];
    if (store.alreadySendNotification==NO) {
        UILocalNotification *notification=[[UILocalNotification alloc] init];
        notification.alertTitle=@"Arounder";
        notification.alertBody=[[self storeForRegion:region] address];
        [[UIApplication sharedApplication] scheduleLocalNotification:notification];

        store.alreadySendNotification=YES;
    }
}

    //For updating monitoring
-(void)locationChangeHandler
{
//If "allStores"(NSMutableArray) isn't nil
    if (self.allStores!=nil) {
        //Finding the 20 closest stores to he user's location and adding it to "twentyClosestStores"(NSMutableArray)
        [self sortClosestStores];
        //Stop monitoring "previousTwentyStores"(NSMutableArray) (20 closest stores before user's location  updated)
        [self stopMonitoringStores];
        //Start monitoring "twentyClosestStores"(NSMutableArray)
        [self startMonitoringClosestStores];
    }
}

//Start monitoring "twentyClosestStores"(NSMutableArray)
-(void)startMonitoringClosestStores
{
    //If monitoring isn't availible for "CLCircularRegion"
    if (![CLLocationManager isMonitoringAvailableForClass:[CLCircularRegion class]]) {
        NSLog(@"Monitoring is not available for CLCircularRegion class");
        return;
    }

    //Run on all "twentyClosestStores"(NSMutableArray)'s objects
    for (Store *currentStore in self.twentyClosestStores) {
        //Start monitoring "region"(CLCircularRegion)
        [self.locationManager startMonitoringForRegion:currentStore.circularRegion];
    }
}

//Stop monitoring "previousTwentyStores"(NSMutableArray) (20 closest stores before user's location  updated)
-(void)stopMonitoringStores
{
    //Run on all "monitoredRegions"(NSSet) of "locationManager"(CLLocationManager) objects
    for (CLCircularRegion *currentRegion in self.locationManager.monitoredRegions) {
        //Stop monitoring "region"(CLCircularRegion)
        [self.locationManager stopMonitoringForRegion:currentRegion];
    }
}

//Finding a store for region
-(Store*)storeForRegion:(CLCircularRegion*)region
{
    //Run on all "allStores"(NSMutableArray)'s objects
    for (Store *currentStore in self.allStores) {
        //If "currentStore"(Store)'s "circularRegion"'s identifier is equal to "region"(CLCircularRegion)'s identifier
        if ([currentStore.circularRegion.identifier isEqualToString:region.identifier]) {
            //Returning "currentStore"(Store)
            return currentStore;
        }
    }
    //Store not found - returning nil
    NSLog(@"No store found for this region: %f,%f",region.center.latitude,region.center.longitude);
    return nil;
}

AppDelegate.m:

-(BOOL)application:(UIApplication *)application willFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
    self.monitorLocationVC=[[monitorLocationViewController alloc] init];
    self.monitorLocationVC.locationManager=self.locationManager;

    [self configureLocationManager];
    [self.locationManager startUpdatingLocation];

    return YES;
}

-(void)configureLocationManager
{
    //Initializing locationManager
    self.locationManager=[[CLLocationManager alloc] init];
    //setting "locationManager"'s(CLLocationManager) delegate to "self"
    self.locationManager.delegate=self.monitorLocationVC;
    //Setting "locationManager"'s(CLLocationManager)'s distance filter to none
    self.locationManager.distanceFilter=kCLDistanceFilterNone;
    //Setting "locationManager"'s(CLLocationManager)'s activityType to navigation
    self.locationManager.activityType=CLActivityTypeAutomotiveNavigation;
    //setting "locationManager"'s(CLLocationManager) desiredAccuracy to "best"
    self.locationManager.desiredAccuracy=kCLLocationAccuracyBestForNavigation;

    self.locationManager.pausesLocationUpdatesAutomatically=NO;

    //If OS version is 9 or above - setting "allowsBackgroundLocationUpdates" to YES
    if ([[[UIDevice currentDevice] systemVersion] floatValue] >= 9) {
        self.locationManager.allowsBackgroundLocationUpdates = YES;
    }
}

谢谢!

最佳答案

您只想监视区域,而不是在后台不断更新其位置。

试试这个:

self.locationManager.desiredAccuracy=kCLLocationAccuracyBest;

您真的需要将 distanceFilter 设置为 kCLDistanceFilterNone 吗?这将导致使用更多的电池电量。您可能想尝试将其设置为 10、20、50 甚至 100 米左右。

另外,为了不不断更新位置,而不是:

[self.locationManager startUpdatingLocation];

尝试仅使用:

[self.locationManager startMonitoringSignificantLocationChanges];

所有这些都应该有助于减少电池的使用。当您将精度和距离过滤器设置为尽可能高的设置时,电池将会耗尽。

编辑: 由于应用程序的用途,无论您做什么,您都会消耗大量电池。我之前针对类似问题做过的解决方案是使用 NSTimer 创建算法或公式,该算法或公式每 x 分钟触发一次以更新用户的位置。 (但仅更新已移动 x 米的区域)。

  • 在 NSTimer 触发之间停止位置更新,这样您就不会不断更新位置。
  • 当计时器触发时,恢复位置更新,获取大约 10 个位置(以便获得准确的位置),然后关闭位置更新,直到计时器下次触发

关于ios - 区域监控(地理围栏)会消耗电池电量 (iOS),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/35208989/

相关文章:

ios - 为什么我的 View Controller (从 Storyboard segue 模态呈现)在被解雇后没有被释放?

objective-c - UIImage 与 NSImage : Drawing to an off screen image in iOS

iphone - 在不同 View Controller 中使用数据的最佳方法是什么?

iOS PWA 抑制工具栏

objective-c - 如何更改分组表格单元格的背景?

ios - 如何将已编程的 ViewController 与 Storyboard中创建的新 View 连接起来?

objective-c - 将 NSString 中的文本转换为 8 字节 ASCII Hex 等效值,然后存储回 NSString

iOS : How to implement handwriting recognition?

iphone - 应用程序必须准备好在 iTunes Connect 上上传,然后才能在 Xcode 中验证或提交

iphone - 'UIAttachmentBehavior' 没有可见的@interface 在 DynamicsCatalog.xcodeproj 中声明选择器 initWithItem