24

アプリが「重要な変更位置情報サービス」を使用している場合、アプリが終了した場合でも、位置情報の更新が配信されると、iOSはそれをウェイクアップすることを知っています。

アプリが標準の位置情報サービスを使用していて、UIBackgroundModesのキーとして位置情報を指定している場合、ケースについて明確な答えを見つけることができませんでした。iOSは、アプリが終了した場合でも、更新を配信するために起動しますか?または、位置更新コールバックを取得するためにアプリをバックグラウンドで実行する必要がありますか?

更新:私がこれを求めていたとき、私はそれをテストする時間がありませんでした。しかし、ここで回答を得た後、アプリケーションのデリゲートにこのコードを記述して、位置が更新されたときに終了したアプリが再起動されるかどうかを確認しました。更新の通知を受けたときにUILocalNotificationを表示しています。ただし、アプリを終了してから市内の場所を変更したところ、アプリが再起動されず、更新がありませんでした。私が間違っているのは何なのか教えていただけますか?

更新#2:このQ&Aの最終結果によると、このコードに問題はなく、終了後に再起動されない、標準の位置情報サービスを使用するアプリの予想される動作です。

Info.plistファイルにUIBackgroundModesの1つとして場所を追加しました。

そして、これは私のアプリデリゲートの場所に関連する部分です:

- (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];
}
4

3 に答える 3

5

実行可能な解決策を見つけたようです。重要な変更フレームワークを使用すると、目的に十分な精度がある限り、バッテリーの寿命をいくらか節約できるようです。このソリューションは、最も近いリージョンのみを監視することで、同時に監視できる20のリージョンのアプリごとの制限を超える可能性があるため、有益です。

同様の機能が必要ですが、大幅な変更が私のアプリにとって十分に正確であるとは思わないので、もう少し掘り下げて次のことを見つけました。

Location Awareness Programming Guideの「MonitoringShape-BasedRegions」の下にある:

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ロケーションキーを設定しなくてもこれが機能することが示されています。このユースケースでは、OSが境界の監視を処理してから、イベントを処理するのに十分な時間だけイベントをアプリに送信します。これはアプリを起動しません。アプリをバックグラウンドで数秒間実行して境界イベントを処理します。その間、関連するアクティビティのみを実行できます。これが他の誰かにも役立つことを願っています!

于 2013-05-03T15:30:58.633 に答える
4

はい、アップデートをより頻繁に受信する(したがって、より多くのバッテリーを消費する)ことを除いて、同じように動作します。

出典:「ユーザーの場所の追跡」セクションの「アプリの状態とマルチタスク」 。

編集再読み込み後、プログラムは一時停止状態から復帰しますが、終了状態からは起動しないようです。ただし、このバックグラウンドモードは本当に必要ではないと思います。細かい位置情報(ターンバイターン方式のナビゲーションなど)が必要なアプリ向けに設計されています。「地域ベース」のプログラミングについては、ロケーションプログラミングガイドのセクションをご覧ください。あなたのコメントの例は、このアプリの使用法の1つとしてリストされています。

もう一度編集コメントの説明によると、最終的な解決策は、ユーザーが十分に近づくまで大幅な場所の変更を設定し、その後、細かい場所の変更に切り替えることです(その間にアプリが終了しないことを期待しています^^ )。

于 2012-09-03T01:26:11.103 に答える
4

アプリを強制終了すると、位置情報の更新がアプリケーションに送信されます

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

以下のように起動キーを探して、このデリゲートメソッド内の場所の更新を収集する必要があります。

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

これがあなたが探しているものであることを願っています。はい、plistで「必要なバックラウンドモード」のキーに「位置情報の更新のためのアプリレジスタ」の値を設定する必要があります。

于 2013-08-30T15:59:34.850 に答える