2016-02-04 35 views
1

我在我的应用程序中实现的CLLocationManager区域监控功能,它的工作原理,但它杀死我的电池:地区监测(区域范围设定)水渠电池(IOS)

-

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]; 
     [email protected]"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; 
    } 
} 

谢谢!

+0

添加在您初始化CLLocationManager代码位置更新。 –

+0

@MSU_Bulldog更新了帖子,请看看 –

+0

我会发表一个答案,我看到你的问题。 –

回答

2

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

试试这个:

self.locationManager.desiredAccuracy=kCLLocationAccuracyBest; 

你真的需要的distanceFilter设置为kCLDistanceFilterNone?这会导致使用更多的电池电量。你可能想要设置为10,20,50甚至100米。

而且,为了不不断更新的位置,而不是:

[self.locationManager startUpdatingLocation]; 

尽量只使用:

[self.locationManager startMonitoringSignificantLocationChanges]; 

所有这些事情应有助于较少的电池使用情况。当您将精度和距离过滤器设置为可能的最高设置时,电池即将耗尽。

编辑: 由于您的应用程序的目的,你会吃掉很多电池。我之前完成的一个类似于这个问题的解决方案是用NSTimer创建算法或公式,每隔x分钟触发一次,以更新用户的位置。 (但只有在移动x米时更新区域)。

  • 停止NSTimer发射之间的位置更新,以便您不会不断更新位置。
  • 当计时器火灾,恢复位置更新,抢约10个位置(这样你就得到一个准确的一个),然后关闭,直到下一次定时器触发
+0

我确实需要更新背景中的区域,因为我有超过20个区域,我需要根据用户的位置启动/停止监视器 –

+0

这些区域有多近?根据我的经验,重要位置更改通常更新用户的行驶距离100-200米左右的位置。如果您想每隔10英尺更新一次他们的位置并重置正在监测的区域,您可以预计电池将在几小时内耗尽。 –

+0

它可以非常接近彼此(我有一个商店的列表,我希望用户更新,甚至可能在同一条街上有10家商店),我该如何处理? –