35

最近、iOS デバイスを iOS 7 を使用するようにアップグレードしました。私たちが開発しているアプリの 1 つは、デバイスの位置を追跡するためにバックグラウンドの位置情報サービスを使用しています。すべてのテスターは、アプリが iOS のバックグラウンドで追跡されなくなったと報告しています。 7。

デバイスの設定でアプリのバックグラウンド処理が有効になっていることを確認しており、以前のビルドは iOS 6 で問題なく動作していました。

iOS 7 でこれを機能させるには、他に何かする必要がありますか?

4

7 に答える 7

47

これは、フォアグラウンドまたはバックグラウンドに関係なく、iOS 7 デバイスから継続的な位置情報を取得するために使用したソリューションです。

ブログと github から完全な解決策と説明を見つけることができます:-

  1. iOS 7 および 8 のバックグラウンド位置更新プログラミング

  2. Github プロジェクト: iOS 7 および 8 のバックグラウンド位置更新プログラミング

方法と説明:-

  1. 関数didUpdateLocationsで 1 分ごとにロケーション マネージャーを再起動します。

  2. シャットダウンする前に、ロケーション マネージャーがデバイスからロケーションを 10 秒間取得できるようにします (バッテリーを節約するため)。

以下の部分的なコード:-

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

for(int i=0;i<locations.count;i++){
    CLLocation * newLocation = [locations objectAtIndex:i];
    CLLocationCoordinate2D theLocation = newLocation.coordinate;
    CLLocationAccuracy theAccuracy = newLocation.horizontalAccuracy;
    NSTimeInterval locationAge = -[newLocation.timestamp timeIntervalSinceNow];

    if (locationAge > 30.0)
        continue;

    //Select only valid location and also location with good accuracy
    if(newLocation!=nil&&theAccuracy>0
       &&theAccuracy<2000
       &&(!(theLocation.latitude==0.0&&theLocation.longitude==0.0))){
        self.myLastLocation = theLocation;
        self.myLastLocationAccuracy= theAccuracy;
        NSMutableDictionary * dict = [[NSMutableDictionary alloc]init];
        [dict setObject:[NSNumber numberWithFloat:theLocation.latitude] forKey:@"latitude"];
        [dict setObject:[NSNumber numberWithFloat:theLocation.longitude] forKey:@"longitude"];
        [dict setObject:[NSNumber numberWithFloat:theAccuracy] forKey:@"theAccuracy"];
        //Add the vallid location with good accuracy into an array
        //Every 1 minute, I will select the best location based on accuracy and send to server
        [self.shareModel.myLocationArray addObject:dict];
    }
}

//If the timer still valid, return it (Will not run the code below)
if (self.shareModel.timer)
    return;

self.shareModel.bgTask = [BackgroundTaskManager sharedBackgroundTaskManager];
[self.shareModel.bgTask beginNewBackgroundTask];

//Restart the locationMaanger after 1 minute
self.shareModel.timer = [NSTimer scheduledTimerWithTimeInterval:60 target:self
                                                       selector:@selector(restartLocationUpdates)
                                                       userInfo:nil
                                                        repeats:NO];

//Will only stop the locationManager after 10 seconds, so that we can get some accurate locations
//The location manager will only operate for 10 seconds to save battery
NSTimer * delay10Seconds;
delay10Seconds = [NSTimer scheduledTimerWithTimeInterval:10 target:self
                                                selector:@selector(stopLocationDelayBy10Seconds)
                                                userInfo:nil
                                                 repeats:NO];
 }

2014 年 5 月の更新: 特定の時間間隔で場所をサーバーに送信する際にサンプル コードを追加するようにといういくつかのリクエストを受け取りました。サンプル コードを追加し、BackgroundTaskManager の修正を組み合わせて、長時間にわたるバックグラウンド実行の不具合を解決しました。ご不明な点がございましたら、こちらのディスカッションに参加してください:サーバー ディスカッションへのロケーション更新による iOS 7 のバックグラウンド ロケーション更新プログラミング

2015 年 1 月の更新: アプリが中断されている場合でも位置情報の更新を取得したい場合は、以下を参照してください: iOSアプリが中断されている場合でも位置情報の更新を取得する

于 2014-02-23T09:49:26.793 に答える
15

彼らは最適化を行い(おそらくモーションセンサーを使用して)、電話の「比較的」静止した位置を検出し、位置情報の更新を停止したと思います。これは憶測にすぎませんが、私のテストでは現在次のことが示されています。

  1. 場所の更新を開始します。(10 メートルと 100 メートルの精度で、それぞれ 3 回テスト済み)
  2. デバイスの画面をオフにして、アプリをバックグラウンドにします。
  3. デバイスを 30 分間固定したまま (机の上など) にします。

私がログに記録したデータは、ジオアップデートが 15 分 30 秒後に停止することを示しています。これにより、実行する他のすべてのバックグラウンド処理も終了します。

私のデバイスは iOS 7 を搭載した iPhone 5 です。

これは iOS 6/6.1 には当てはまらないことを 95% 確信しています。100 メートルの精度で地理情報を更新すると、バックグラウンドでほぼ継続的に実行できます。

アップデート

Location Manager を 8 分ごとに再起動すると、継続的に実行されます。

アップデート #2

これは最新ではテストしていませんが、投稿を書いたときに再起動した方法です。これがお役に立てば幸いです。

- (void)tryRestartLocationManager
{
    NSTimeInterval now = [[NSDate date] timeIntervalSince1970];

    int seconds = round(floor(now - locationManagerStartTimestamp));

    if ( seconds > (60 * 8) ) {
        [locationManager stopUpdatingLocation];
        [locationManager startUpdatingLocation];
        locationManagerStartTimestamp = now;
    }
}
于 2013-09-24T09:13:58.433 に答える
5

別のスレッドStart Location Manager in iOS 7 をバックグラウンド タスクSash から見つけました。

問題/解決策を見つけました。位置情報サービスを開始してバックグラウンド タスクを停止する時間になると、バックグラウンド タスクは遅延して停止する必要があります (私は 1 秒に設定しました)。そうしないと、位置情報サービスが開始されません。

誰でもそれを試して確認できますか?

ニコライ、ここにコードを貼り付けてもらえますか? Location Manager を 8 分ごとに再起動しようとしましたが、連続して実行されません。

アップデート:

High と Low を検索した後、Apple フォーラムから解決策を見つけました。

iOS 7 では、位置情報サービスをバックグラウンドで開始できません。位置情報サービスをバックグラウンドで実行し続けたい場合は、フォアグラウンドで開始する必要があり、バックグラウンドで引き続き実行されます。

あなたが私のようだった場合、位置情報サービスを停止し、タイマーを使用してバックグラウンドで再起動しても機能しません。

詳細については、WWDC 2013 のビデオ 307 の最初の 8 分間をご覧ください: https://developer.apple.com/wwdc/videos/

2014 年 2 月の更新: 数か月試した後、iOS 7 を使用してデバイスから継続的に場所を取得できます。あなたはここで完全な答えを見るかもしれません:iOS 7でバックグラウンド位置情報サービスが機能しない

于 2013-09-27T03:46:03.240 に答える