簡體   English   中英

iOS:當應用在后台運行一段時間后,停止位置更新

[英]IOS: Stop location updates when app is in the background for a while

我寫了一個監控用戶位置的應用程序。 當我的視圖加載時,位置服務會打開:

// Create the location manager if this object does not
// already have one.
if (nil == self.locationManager) {
    self.locationManager = [[CLLocationManager alloc] init];
}

self.locationManager.delegate = self;

// Check for iOS 8. Without this guard the code will crash with "unknown selector" on iOS 7.
if ([self.locationManager respondsToSelector:@selector(requestAlwaysAuthorization)]) {
    [self.locationManager requestAlwaysAuthorization];
}

[self.locationManager startMonitoringSignificantLocationChanges];
NSLog(@"Started monitoring significant location changes");

如果我在激活應用程序時將其終止,則定位服務會停止。 這是我為停止AppDelegate.m中的位置服務而編寫的代碼:

- (void)applicationWillTerminate:(UIApplication *)application {
    // Called when the application is about to terminate. Save data if appropriate. See also            
       applicationDidEnterBackground:.
    // Saves changes in the application's managed object context before the application terminates.
    NSLog(@"entered terminate in delegate");
    [myController.locationManager stopUpdatingLocation];
    [myController.locationManager stopMonitoringSignificantLocationChanges];
    myController.locationManager = nil;
    [self saveContext];
}

我遇到一個問題,如果我的應用程序已經在后台,則不會調用上述方法,因此無法關閉定位服務。 為了解決此問題,我找到了嘗試過的解決方案:

- (void)applicationDidEnterBackground:(UIApplication *)application {
    // Use this method to release shared resources, save user data, invalidate timers, and store enough application state information to restore your application to its current state in case it is terminated later.
    // If your application supports background execution, this method is called instead of applicationWillTerminate: when the user quits.

    UIApplication *app = [UIApplication sharedApplication];
    if ([app respondsToSelector:@selector(beginBackgroundTaskWithExpirationHandler:)]) {
        self.bgTask = [app beginBackgroundTaskWithExpirationHandler:^{
            // Synchronize the cleanup call on the main thread in case
            // the task actually finishes at around the same time.
            dispatch_async(dispatch_get_main_queue(), ^{
                if (self.bgTask != UIBackgroundTaskInvalid)
                {
                    NSLog(@"Marking bgTask as Invalid when we entered background");
                    [app endBackgroundTask:self.bgTask];
                    self.bgTask = UIBackgroundTaskInvalid;
                }
            });
        }];
    }
}

因此,如果我的應用程序在后台運行,則上述解決方案有效。 但是,我注意到,如果讓我的應用程序在后台長時間運行(超過五分鍾),則會啟動到期處理程序。因此,如果我終止應用程序而不將其置於前台。 定位服務圖標仍顯示在電話上。 我必須先重新啟動應用程序或先將其置於前台,然后再終止禁用定位服務的代碼。

如果我刪除這兩行:

         [app endBackgroundTask:self.bgTask];
         self.bgTask = UIBackgroundTaskInvalid;

在連接調試器五分鍾后,找到定位服務即可停止。 如果我讓它在后台運行的時間更長,那么終止代碼將永遠不會啟動。是因為我沒有更改位置,還是應用最終消失了?

所以我的問題是,如果應用程序在后台運行了一段時間,是否還有另一種方法可以確保該應用程序正確停止位置服務監視?

謝謝...阿姆羅


編輯,我做了更多的實驗,這是我的發現:

當連接調試器時,如果我等待進入后台模式的時間為11分鍾,則會調用方法willTerminate:

2015-01-13 08:52:45.935 [441:37074] @@@AMRO--->applicationWillResignActive entered

2015-01-13 08:52:46.642 [441:37074] @@@AMRO--->Entered background mode

2015-01-13 08:55:42.697 [441:37074] @@@AMRO--->beginBackgroundTaskWithExpirationHandler called

2015-01-13 09:03:26.265 [441:37074] entered terminate in delegate

如果我在沒有調試器的情況下嘗試此操作,並且僅等待四分鍾,則不會調用終止函數,而不必等待整個11分鍾。

從Apple的文檔中:

應用終止

應用必須隨時准備終止,並且不應該等待保存用戶數據或執行其他關鍵任務。 系統啟動的終止是應用程序生命周期的正常組成部分。 系統通常會終止應用程序,以便可以回收內存並為用戶正在啟動的其他應用程序騰出空間,但是系統也可能會終止行為不當或未及時響應事件的應用程序。

掛起的應用終止時不會收到任何通知; 系統終止進程並回收相應的內存。 如果某個應用程序當前正在后台運行且未掛起,則系統將在終止之前調用其應用程序委托的applicationWillTerminate:。 設備重啟時,系統不會調用該方法。

除了系統終止您的應用程序外,用戶還可以使用多任務UI顯式終止您的應用程序。 用戶啟動的終止與終止已暫停的應用程序具有相同的效果。 該應用程序的進程被終止,並且沒有通知發送到該應用程序。

https://developer.apple.com/library/ios/documentation/iPhone/Conceptual/iPhoneOSProgrammingGuide/TheAppLifeCycle/TheAppLifeCycle.html#//apple_ref/doc/uid/TP40007072-CH2-SW1

關於重大更改位置:

如果您使重大更改位置服務保持運行狀態,並且隨后您的iOS應用被暫停或終止,則當新位置數據到達時,該服務會自動喚醒您的應用。

https://developer.apple.com/library/ios/documentation/UserExperience/Conceptual/LocationAwarenessPG/CoreLocation/CoreLocation.html

如果您不希望應用程序被ificantChangeLocation喚醒,則可以在backgroundTimeRemaining即將到期時調用stopMonitoringSignificantLocationChanges。

參加

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM