2016-02-04 57 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家商店),我該如何處理? –