アプリがバックグラウンドで実行されていなくても、iOS デバイスの位置を追跡したい。私の主な目的は、デバイスの場所を取得し、Web サービス呼び出しを使用してサーバーに送信することです。この目的のために、私はこのチュートリアルhttp://www.mindsizzlers.com/2011/07/ios-background-location/に従いましたが、同じことを達成することはできません。
今のところ、サーバーに座標を送信する代わりに、場所をテキスト ファイルに記録しようとしていますが、「アプリがバックグラウンドで実行されていない場合は、それを達成できません」と同じために次のコードを使用しています。
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions{
if (!locationManager) {
locationManager = [[CLLocationManager alloc]init];
}
[locationManager setDelegate:self];
//
// [locationManager startMonitoringSignificantLocationChanges];
//
if ([launchOptions objectForKey:UIApplicationLaunchOptionsLocationKey] ) {
[locationManager startMonitoringSignificantLocationChanges];
}
else{
[locationManager startUpdatingLocation];
}
}
-
- (void)applicationWillTerminate:(UIApplication *)application {
[locationManager startMonitoringSignificantLocationChanges];
}
-
- (void)applicationDidEnterBackground:(UIApplication *)application
{
[locationManager startMonitoringSignificantLocationChanges];
}
-
- (void)locationManager:(CLLocationManager *)manager didUpdateLocations:(NSArray *)locations{
BOOL isInBackground = NO;
if ([UIApplication sharedApplication].applicationState == UIApplicationStateBackground)
{
isInBackground = YES;
NSLog(@"is in background");
}
// Handle location updates as normal, code omitted for brevity.
// The omitted code should determine whether to reject the location update for being too
// old, too close to the previous one, too inaccurate and so forth according to your own
// application design.
if (isInBackground)
{
[self sendBackgroundLocationToServer:[locations lastObject]];
}
else
{
// ...
}
}
-
- (void) log:(NSString*)msg
{
NSDateFormatter * formatter = [[NSDateFormatter alloc] init];
[formatter setTimeStyle:NSDateFormatterMediumStyle];
NSString * logMessage = [NSString stringWithFormat:@"%@ %@", [formatter stringFromDate:[NSDate date]], msg];
NSString * fileName = [self locationPath];
FILE * f = fopen([fileName cString], "at");
fprintf(f, "%s\n", [logMessage cString]);
fclose (f);
}
-
- (NSString*)locationPath
{
NSString* path = [NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES) lastObject];
return [path stringByAppendingPathComponent:@"locationPath.txt"];
}
-
-(void) sendBackgroundLocationToServer:(CLLocation *)location
{
// REMEMBER. We are running in the background if this is being executed.
// We can't assume normal network access.
// bgTask is defined as an instance variable of type UIBackgroundTaskIdentifier
// Note that the expiration handler block simply ends the task. It is important that we always
// end tasks that we have started.
bgTask = [[UIApplication sharedApplication] beginBackgroundTaskWithExpirationHandler:^{
[[UIApplication sharedApplication] endBackgroundTask:bgTask];
}];
[self log:[NSString stringWithFormat:@"Background location %.06f %.06f %@" , location.coordinate.latitude, location.coordinate.longitude, location.timestamp]];
// ANY CODE WE PUT HERE IS OUR BACKGROUND TASK
// For example, I can do a series of SYNCHRONOUS network methods (we're in the background, there is
// no UI to block so synchronous is the correct approach here).
// ...
// AFTER ALL THE UPDATES, close the task
if (bgTask != UIBackgroundTaskInvalid)
{
[[UIApplication sharedApplication] endBackgroundTask:bgTask];
bgTask = UIBackgroundTaskInvalid;
}
}
-
- (void)applicationWillEnterForeground:(UIApplication *)application
{
// Called as part of the transition from the background to the inactive state; here you can undo many of the changes made on entering the background.
}
-
- (void)applicationDidBecomeActive:(UIApplication *)application
{
// Restart any tasks that were paused (or not yet started) while the application was inactive. If the application was previously in the background, optionally refresh the user interface.
// [locationManager stopMonitoringSignificantLocationChanges];
[locationManager startUpdatingLocation];
}
どんな助けでも大歓迎です。
ありがとう