2014-04-04 35 views
1

我正在使用CLLocationManager的「startMonitoringSignificantLocationChanges」方法。此方法在後臺狀態和活動狀態下運行良好,但在應用程序終止時不會運行。上述方法的文檔說:startMonitoringSignificantLocationChanges問題

「如果你啓動這個服務和應用程序隨後被終止,系統將自動是否有新的事件到來將重新啓動應用程序進入後臺。」

但我不能夠在我的代碼中實現它。我在Stack Overflow中經歷了很多QnA,並嘗試了一些解決方案,但尚未成功。 我的iOS版本是7.1。

我的代碼:

ViewController.m

//Created sharedInstance of my class 

+(ViewController *)sharedInstance { <br/><br/> 
    static ViewController *sharedViewController = nil; <br/> 
    @synchronized(self) { <br/> 
     if (sharedViewController == nil) { <br/> 
      sharedViewController = [[self alloc] init]; <br/> 
     } <br/> 
    } <br/> 
    return sharedViewController; <br/> 
} 

//點擊按鈕會觸發startMonitoringSignificantLocationChanges方法

- (IBAction)clickedGetCurrentLocation:(id)sender { <br/> 
    locationManager.delegate = self; <br/> 
    locationManager.desiredAccuracy = kCLLocationAccuracyBest; 

    [self startMonitoringSignificantLocationChanges]; <br/> 
} 

- (void) startMonitoringSignificantLocationChanges 
{ <br/> 
    [locationManager startMonitoringSignificantLocationChanges]; <br/> 
} 

#pragma mark - CLLocationManagerDelegate 

- (void)locationManager:(CLLocationManager *)manager didFailWithError:(NSError *)error 
{ <br/> 
    NSLog(@"didFailWithError: %@", error); <br/> 
    UIAlertView *errorAlert = [[UIAlertView alloc] 
           initWithTitle:@"Error" message:@"Failed to Get Your Location" delegate:nil cancelButtonTitle:@"OK" otherButtonTitles:nil]; <br/> 
    [errorAlert show]; 

    [locationManager stopUpdatingLocation]; <br/> 
} 

- (void)locationManager:(CLLocationManager *)manager didUpdateLocations:(NSArray *)locations { 

    CLLocation *currentLocation = locations[0]; 

    if (currentLocation != nil) { <br/> 
     longitudeLabel.text = [NSString stringWithFormat:@"%.8f", currentLocation.coordinate.longitude]; <br/> 
     latitudeLabel.text = [NSString stringWithFormat:@"%.8f", currentLocation.coordinate.latitude]; <br/> 
    } 

    // Reverse Geocoding <br/> 
    [geocoder reverseGeocodeLocation:currentLocation completionHandler:^(NSArray *placemarks, NSError *error) { <br/> 
     if (error == nil && [placemarks count] > 0) { <br/> 
      placemark = [placemarks lastObject]; <br/> 
      addressLabel.text = [NSString stringWithFormat:@"%@ %@\n%@ %@\n%@\n%@", 
           placemark.subThoroughfare, placemark.thoroughfare, 
           placemark.postalCode, placemark.locality, 
           placemark.administrativeArea, 
           placemark.country]; <br/>    
     } else { <br/> 
      NSLog(@"%@", error.debugDescription); <br/> 
     } <br/> 
    } ]; 

    UILocalNotification* localNotification = [[UILocalNotification alloc] init]; <br/> 

    NSString *message = [NSString stringWithFormat:@"Location Changed To (%@, %@)", [latitudeLabel text], [longitudeLabel text]]; <br/> 
    localNotification.alertBody = message; <br/> 
    localNotification.fireDate = [NSDate date]; <br/> 
    localNotification.alertAction = @"Location Change Detected"; <br/> 
    localNotification.timeZone = [NSTimeZone timeZoneWithName:@"Asia/India"]; <br/> 
    localNotification.applicationIconBadgeNumber = [[UIApplication sharedApplication] applicationIconBadgeNumber] + 1; 

    [[UIApplication sharedApplication] scheduleLocalNotification:localNotification];  

    [[NSNotificationCenter defaultCenter] postNotificationName:@"reloadData" object:self]; 
} 

AppDelegate.m

- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions 
{ <br/> 
    if ([launchOptions objectForKey:UIApplicationLaunchOptionsLocationKey]) { <br/> 
     [[ViewController sharedInstance] startMonitoringSignificantLocationChanges]; <br/> 
    } <br/> 

    UILocalNotification *locationNotification = [launchOptions objectForKey:UIApplicationLaunchOptionsLocalNotificationKey]; 

    if (locationNotification) { <br/> 
     application.applicationIconBadgeNumber = 0; <br/> 
    } 

    return YES; <br/> 
} 

- (void)application:(UIApplication *)application didReceiveLocalNotification:(UILocalNotification *)notification 
{ <br/> 
    UIApplicationState state = [application applicationState]; <br/> 
    if (state == UIApplicationStateActive) { <br/> 
     UIAlertView *alert = [[UIAlertView alloc] initWithTitle:@"Location" 
                 message:notification.alertBody 
                 delegate:self cancelButtonTitle:@"OK" 
               otherButtonTitles:nil]; <br/> 
     [alert show]; <br/> 
    } 

    // Set icon badge number to zero <br/><br/> 
    application.applicationIconBadgeNumber = 0; 
} 
+0

我建議你展示一些你的代碼,並解釋哪些方法有效,哪些方法不起作用。你的問題很難回答。 – Volker

+0

@Volker,我已經添加了代碼給我的問題。請看看它 – user3498010

+0

我認爲當應用程序由於位置更改而啓動時,您必須重新啓動位置服務:在重新啓動時,您仍然必須配置位置管理器對象並調用此方法以繼續接收位置事件。 - 我沒有在你的應用程序代理代碼中看到那些你剛剛開始監視信號位置變化而沒有設置位置管理器的地方。 – Volker

回答

0

當IOS收到位置更新,並在終止應用程序後重新啓動您的應用程序,讓它知道它由於位置服務而重新生成。那麼你需要重新啓動後臺定位服務,在diddidFinishLaunchingWithOptions方法如下:

- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {  
    if ([launchOptions objectForKey:UIApplicationLaunchOptionsLocationKey]) { 
     [[LocationController sharedInstance] startMonitoringSignificantLocationChanges]; 
    } 
    return YES; 
} 
+0

下,我的didFinishLaunchingWithOptions包含視圖激活的其他代碼。應該執行還是我只需要執行startMonitoringSignificantLocationChanges? –

+0

以上,我的didFinishLaunchingWithOptions不會被調用,當我的應用程序在後臺和重大的位置更改觸發應用程序恢復。 –

+1

didFinishLaunchingWithOptions只會在終止後再次啓動應用程序或第一次啓動應用程序時執行,而視圖的代碼將正常執行,但您需要做的僅僅是在應用程序再次啓動時添加此startMonitoringSignificantLocationChanges –

0

從我的經驗應用不會從終端發起由於顯著位置的變化但是地理範圍會做的伎倆。 如果您設置了用戶進入/退出的圍欄,您將從終止啓動到響應該事件約30秒的背景時間(取決於設備類型)。

相關問題