0

バックグラウンドでユーザーの位置を追跡するサンプル アプリを開発していますが、位置情報サービスを常に有効にしたままにしたくありませんが、タイマーの何かが正しく動作しません。

私の考えでは、x 分ごとにサービスが開始され、新しい場所が正しく取得されると再びリリースされ、テスト用に 10 秒に設定されました。(重要な LocationChange はトリックではなく、十分に正確ではありません)

私はたくさん (iOS Dev center + StackOverflow) を検索していて、beginBackgroundTaskWithExpirationHandler、いくつかのブロック、およびタイマーを使用して、バックグラウンドに移行してから 10 分以上コードを実行できる「新しい」バックグラウンド ロケーション機能を見つけました。

バックグラウンド モードを [場所] に設定しましたが、今ではバックグラウンド時間の終了を処理する必要はないと思います (最初に、15 ~ 20 秒ごとに場所を取得したいと考えています)。

コードは「正常に」動作していますが、

  • タイマーが作動する場合と作動しない場合があります。
  • タイマーが作動すると、それを行うのに最低 10 分かかります。
  • OS でのいくつかのランダムなアクション (検索デスクトップへの入力など) は、タイマーが起動するように推定しているように見えます (これについてはよくわかりません。どのように可能かわかりませんが、そこにあります...)

そして、コードを超えると、別の質問になります。

appdelegates のメソッド:

// applicationDidEnterBackground

- (void)applicationDidEnterBackground:(UIApplication *)application{

NSLog(@"to background");

UIApplication*    app = [UIApplication sharedApplication];

bgTask = [app beginBackgroundTaskWithExpirationHandler:^{
    [app endBackgroundTask:bgTask];
    bgTask = UIBackgroundTaskInvalid;
}];

// Start the long-running task and return immediately.
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{

    // Do the work associated with the task.
    _triggertimer = nil;
    [self initTimer];

});
NSLog(@"backgroundTimeRemaining: %.0f", [[UIApplication sharedApplication] backgroundTimeRemaining]);}

// initTimer

- (void) initTimer{
NSLog(@"InitTimer ");


UIApplication *app = [UIApplication sharedApplication];

bgTask = [app beginBackgroundTaskWithExpirationHandler:^{



_triggertimer = [NSTimer scheduledTimerWithTimeInterval:10.0
                                                     target:self
                                                   selector:@selector(checkUpdates:)
                                                   userInfo:nil
                                                    repeats:YES];

[[NSRunLoop currentRunLoop] addTimer:_triggertimer forMode:NSDefaultRunLoopMode] ;
[[NSRunLoop currentRunLoop] run];

}];}

// checkUpdates

- (void)checkUpdates:(NSTimer *)timer{

NSLog(@"CheckUpdates ");

UIApplication*    app = [UIApplication sharedApplication];

if (nil == _locationManager) _locationManager = [[CLLocationManager alloc] init];

_locationManager.delegate = self;


_locationManager.distanceFilter = 10;
_locationManager.desiredAccuracy = kCLLocationAccuracyHundredMeters;

[_locationManager startUpdatingLocation];
[_locationManager startMonitoringSignificantLocationChanges];



double remaining = app.backgroundTimeRemaining;
NSLog(@"Reminaing %f", remaining);}

私はこれを修正するために多くのことを試みましたが、おそらく何かを台無しにしたり見逃したりしました...何が見えますか? いくつかの概念エラーがあるかもしれません。ブロックについて自己紹介しようとしていますが、まだドメイン化していません ¬¬

ちなみに、 beginBackgroundTaskWithExpirationHandlerで何かを行う前に、私が見つけたすべてのコードにこれが含まれているのはなぜですか?

 bgTask = [app beginBackgroundTaskWithExpirationHandler:^{
    [app endBackgroundTask:bgTask];
    bgTask = UIBackgroundTaskInvalid;
}];

これはその 600 秒の背景を撮影するためだと思っていましたが、よくわかりません。

4

2 に答える 2

0

OK、問題は、beginBackgroundTaskWithExpirationHandler を 2 回呼び出していたことです。1 つはApplicationDidEnterBackgroundで、もう 1 つはinitTimer内で...

于 2012-11-19T15:06:59.537 に答える
0

アプリがバックグラウンド化されると、アプリの info.plist で UIBackgroundModes キーの「場所」の値が設定されていない限り、タイマーは起動しなくなります。

beginBackgroundTaskWithExpirationHandler を使用してバックグラウンドで実行できる時間を延長できますが (「場所」を設定していない場合)、対応する終了呼び出しと常にペアにする必要があります。

于 2012-11-14T13:23:51.873 に答える