当应用程序未在后台运行时,使用 startmonitoringsignfiicantlocationchanges 跟踪设备位置

Posted

技术标签:

【中文标题】当应用程序未在后台运行时,使用 startmonitoringsignfiicantlocationchanges 跟踪设备位置【英文标题】:tracking device location using startmonitoringsignficantlocationchanges when app not running in background 【发布时间】:2013-10-22 11:24:55 【问题描述】:

即使应用程序没有在后台运行,我也想跟踪 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];


任何帮助将不胜感激。

谢谢

【问题讨论】:

我不知道为什么有人对我的问题投了反对票,但我会要求,如果问题中有任何问题,请也提及,以便下次用户可以提出更好的问题。跨度> 【参考方案1】:

您应该将位置背景模式添加到您的 info.plist。

【讨论】:

以上是关于当应用程序未在后台运行时,使用 startmonitoringsignfiicantlocationchanges 跟踪设备位置的主要内容,如果未能解决你的问题,请参考以下文章

已安排本地通知,但未在挂起和未运行模式下传递

Flutter:当应用程序处于后台但未在 iOS 中终止时,无法在通知单击时重定向到特定屏幕

当应用程序处于后台时,Android 2nd 推送通知有效负载数据未在附加中接收

Android FCM - onMessageReceived 未在后台调用

应用在后台运行时,本机深度链接

Flutter Firebase:抬头通知未在后台显示