簡體   English   中英

如果已經為UIBackgroundModes的位置注冊,iOS會喚醒已終止的應用嗎?

[英]Will iOS wake up the terminated app if it's registered with location for UIBackgroundModes?

我知道,如果應用程序使用“重要更改位置服務”,即使應用程序已終止,iOS也會在有位置更新時將其喚醒。

如果應用程序使用標准位置服務並指定位置作為UIBackgroundModes的密鑰,我無法找到關於此案例的明確答案:iOS是否也會將其喚醒以提供更新,即使它已終止? 或者應用程序是否需要在后台運行以獲取位置更新回調?

更新:當我問這個時,我沒有時間去測試它。 但是在我得到答案后,我在我的應用程序的委托中編寫了這段代碼,看看我的終止應用程序是否會在獲得位置更新時重新啟動。 當我收到更新通知時,我正在顯示UILocalNotification。 但是,當我終止我的應用程序,然后更改我在城市的位置,該應用程序沒有重新啟動,我沒有得到任何更新。 你能告訴我我做錯了什么嗎?

更新#2:根據此問答中的最終結果,此代碼沒有任何問題,這是使用標准位置服務的應用程序的預期行為,而不是在終止后重新啟動。

我已將位置添加為Info.plist文件中的UIBackgroundModes之一。

這是我的應用代表的位置相關部分:

- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {    

    [UIApplication sharedApplication].applicationIconBadgeNumber = 0;

    m_locManager = [[CLLocationManager alloc] init];
    m_locManager.delegate = self;
    [m_locManager startUpdatingLocation];
    return YES;
}

- (void)applicationDidEnterBackground:(UIApplication *)application {
    [m_locManager startUpdatingLocation];
}

- (void)locationManager:(CLLocationManager *)manager didFailWithError:(NSError *)error
{
    NSLog("%@", [NSString stringWithFormat:@"Background Fail %@", [error localizedDescription]]);
}

- (void)locationManager:(CLLocationManager *)manager
    didUpdateToLocation:(CLLocation *)newLocation
           fromLocation:(CLLocation *)oldLocation
{
    UILocalNotification * theNotification = [[UILocalNotification alloc] init];
    theNotification.alertBody = [NSString stringWithFormat:@"Background location %.06f %.06f %@" , newLocation.coordinate.latitude, newLocation.coordinate.longitude, newLocation.timestamp];
    theNotification.alertAction = @"Ok";

    theNotification.fireDate = [NSDate dateWithTimeIntervalSinceNow:1];

    [[UIApplication sharedApplication] scheduleLocalNotification:theNotification];
}

是的,除了更頻繁地接收更新(因此消耗更多電池)之外,它的行為方式相同。

來源: 跟蹤用戶位置部分下的應用程序狀態和多任務處理

編輯重新閱讀后,似乎程序將從暫停狀態喚醒,但不會被終止狀態喚醒。 不過,我認為你真的不需要這種背景模式。 它專為需要精確位置信息的應用程序而設計(如逐向導航)。 查看位置編程指南中有關“基於區域”編程的部分。 您評論中的示例被列為此應用的一種用途。

再次編輯根據評論中的討論,最終解決方案似乎是設置顯着的位置更改,直到用戶足夠接近,然后切換到精細位置更改(並希望應用程序在此期間不會終止^^ )

看起來你找到了一個可行的解決方案,似乎使用重要的更改框架可以節省一些電池壽命,只要它足夠准確,適合您的目的。 您的解決方案也是有益的,因為它只允許監控您最接近的區域,從而允許您處理超過允許同時監控的20個區域的每個應用程序限制的可能性。

我需要類似的功能,但不要認為重大變化對我的應用程序來說足夠准確,所以我挖了一些更多的東西並找到了以下內容。

根據位置感知編程指南 ,在“監控基於形狀的區域”下:

在iOS中,系統會始終跟蹤與您的應用相關聯的區域,包括您的應用未運行時。 如果在應用未運行時越過區域邊界,則會將該應用重新啟動到后台以處理該事件。 同樣,如果應用程序在事件發生時被暫停,則會被喚醒,並且只需要很短的時間來處理事件。

以及“處理區域的邊界交叉事件”:

每當用戶的當前位置越過邊界區域時,系統都會為您的應用生成適當的區域事件。 如果您的應用程序已在運行,則這些事件將直接發送給任何當前位置管理器對象的代理。 如果您的應用未運行,系統會在后台啟動它,以便它可以響應。 應用可以實現以下方法來處理邊界交叉:

的LocationManager:didEnterRegion:

的LocationManager:didExitRegion:

在我的情況下,我只需要在跨越邊界時觸發通知,因此我將AppDelegate設置為符合CLLocationManagerDelegate,創建了一個locationManager屬性,並將其放在我的實現文件中:

- (BOOL)application:(UIApplication *)application willFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
    self.locationManager.delegate = self;
    return YES;
}

- (CLLocationManager *)locationManager
{
    if (!_locationManager) {
        _locationManager = [[CLLocationManager alloc] init];
        _locationManager.desiredAccuracy = kCLLocationAccuracyHundredMeters;
    }
    return _locationManager;
}

- (void)locationManager:(CLLocationManager *)manager didEnterRegion:(CLRegion *)region
{
    UILocalNotification *notification = [[UILocalNotification alloc] init];
    notification.alertBody = NSLocalizedString(@"You crossed a boundary!", @"user crossed a boundary");
    [[UIApplication sharedApplication] presentLocalNotificationNow:notification];
}

測試顯示無需設置UIBackgroundModes位置鍵即可。 在此用例中,操作系統為您處理邊界監視,然后將事件發送到您的應用程序足夠長的時間來處理事件。 這不會啟動應用程序,它只是在后台運行它幾秒鍾來處理邊界事件,在此期間您只能執行相關活動。 希望這也有助於其他人!

一旦您終止應用程序,位置更新將發送到應用程序

- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions

您需要通過查找啟動密鑰來收集此委托方法中的位置更新,如下所示,

if ([launchOptions objectForKey:UIApplicationLaunchOptionsLocationKey])
{
//Code to handle the location update
}

希望這是你想要的。 是的,您需要在plist中設置值“必需的背景模式”,其值為“應用寄存器以進行位置更新”。

暫無
暫無

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

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