当应用程序在后台时向服务器发送纬度和经度

Posted

技术标签:

【中文标题】当应用程序在后台时向服务器发送纬度和经度【英文标题】:Sending Latitude and Longitude to Server when app is in background 【发布时间】:2016-09-08 10:15:21 【问题描述】:

我浏览了这么多链接,即使在那之后我还没有找到获取纬度和经度的合适解决方案。

Periodic ios background location updates

iOS long-running background timer with "location" background mode

我尝试了一些链接和论坛,但它只工作了 3 分钟,然后应用程序根本没有更新用户位置。

- (void)applicationDidEnterBackground:(UIApplication *)application 
// Use this method to release shared resources, save user data, invalidate timers, and store enough application state information to restore your application to its current state in case it is terminated later.
// If your application supports background execution, this method is called instead of applicationWillTerminate: when the user quits.


//create new uiBackgroundTask
__block UIBackgroundTaskIdentifier bgTask = [app beginBackgroundTaskWithExpirationHandler:^
    [app endBackgroundTask:bgTask];
    bgTask = UIBackgroundTaskInvalid;
];

//and create new timer with async call:
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_HIGH, 0), ^

    [locationManager startUpdatingLocation];

    NSTimer* t = [NSTimer scheduledTimerWithTimeInterval:10 target:self selector:@selector(startTrackingBg) userInfo:nil repeats:YES];
    [[NSRunLoop currentRunLoop] addTimer:t forMode:NSDefaultRunLoopMode];
    [[NSRunLoop currentRunLoop] run];
);


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

//  store data
CLLocation *newLocation = [locations lastObject];


//tell the centralManager that you want to deferred this updatedLocation
if (_isBackgroundMode && !_deferringUpdates)

    _deferringUpdates = YES;
    [locationManager allowDeferredLocationUpdatesUntilTraveled:CLLocationDistanceMax timeout:10];


【问题讨论】:

【参考方案1】:

好的。

在挣扎了 3 天之后,即使在 3 分钟后,当应用程序处于后台时,它仍然可以发送纬度和经度。

我检查了我的应用程序,在后台连续发送 lat long 一个多小时。

它至少可以帮助一些人。

首先请在您的 pList 中添加以下两个键。

 1.NSLocationAlwaysUsageDescription
 2.NSLocationWhenInUseUsageDescription

两者都是字符串,你可以给任何值。

然后请在项目部分的功能下打开后台获取并检查位置更新。

然后导入 Corelocation 框架并添加以下代码。

locationManager 是一个全局变量。

- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions 
// Override point for customization after application launch.
 //create CLLocationManager variable
locationManager = [[CLLocationManager alloc] init];
//set delegate
locationManager.delegate = self;

app = [UIApplication sharedApplication];
// This is the most important property to set for the manager. It ultimately determines how the manager will
// attempt to acquire location and thus, the amount of power that will be consumed.

if ([locationManager respondsToSelector:@selector(setAllowsBackgroundLocationUpdates:)]) 
    [locationManager setAllowsBackgroundLocationUpdates:YES];

locationManager.desiredAccuracy = 45;
locationManager.distanceFilter = 100;
// Once configured, the location manager must be "started".
[locationManager startUpdatingLocation];


 - (void)applicationWillResignActive:(UIApplication *)application 
// Sent when the application is about to move from active to inactive state. This can occur for certain types of temporary interruptions (such as an incoming phone call or SMS message) or when the user quits the application and it begins the transition to the background state.
// Use this method to pause ongoing tasks, disable timers, and throttle down OpenGL ES frame rates. Games should use this method to pause the game.

[locationManager stopUpdatingLocation];
[locationManager setDesiredAccuracy:kCLLocationAccuracyBest];
[locationManager setDistanceFilter:kCLDistanceFilterNone];
locationManager.pausesLocationUpdatesAutomatically = NO;
locationManager.activityType = CLActivityTypeAutomotiveNavigation;
[locationManager startUpdatingLocation];
 

 - (void)applicationDidEnterBackground:(UIApplication *)application 
// Use this method to release shared resources, save user data, invalidate timers, and store enough application state information to restore your application to its current state in case it is terminated later.
// If your application supports background execution, this method is called instead of applicationWillTerminate: when the user quits.


[locationManager stopUpdatingLocation];

__block UIBackgroundTaskIdentifier bgTask = [app beginBackgroundTaskWithExpirationHandler:^
    bgTask = UIBackgroundTaskInvalid;
];

NSTimer *timer = [NSTimer scheduledTimerWithTimeInterval:10.0
                                              target:self
                                            selector:@selector(startTrackingBg)
                                            userInfo:nil
                                             repeats:YES];


 

-(void)startTrackingBg 

[locationManager startUpdatingLocation];
 NSLog(@"App is running in background");

 //starts automatically with locationManager
  -(void)locationManager:(CLLocationManager *)manager didUpdateToLocation:(CLLocation *)newLocation fromLocation:(CLLocation *)oldLocation
latitude=newLocation.coordinate.latitude;
longitude=newLocation.coordinate.longitude;
NSLog(@"Location: %f, %f",newLocation.coordinate.longitude, newLocation.coordinate.latitude);
 

【讨论】:

@Santo...请检查这个兄弟..并试图帮助我..***.com/questions/37338466/… @SurajSukale 首先告诉我,您在构建时是否获取当前位置? 不,兄弟...实际上我是这个应用程序开发的新手(第一次在这个特定的域位置上工作)....你能帮我解决这个问题吗 关注此链接***.com/questions/12736086/…appcoda.com/how-to-get-current-location-iphone-user 让我们continue this discussion in chat。【参考方案2】:

你需要参考这个苹果文档handling location events in the background

您需要在 Xcode 项目的功能中的后台模式中启用位置更新

标准定位服务 无法在后台模式下运行,因此您必须使用重大变化定位服务或访问服务。。 p>

使用此代码

locationManager.delegate = self
locationManager.startMonitoringSignificantLocationChanges()

启用重大变化定位服务。

【讨论】:

【参考方案3】:

在 Santos 答案的基础上,其中包含使背景定位工作的大部分重要步骤,我已经澄清并纠正了一些细节。

项目设置

您应该将这些键添加到您的 Xcode Target Info 属性列表中。确保为每个应用添加有效的描述,否则您的应用可能无法获得批准。

NSLocationAlwaysUsageDescription NSLocationWhenInUseUsageDescription NSLocationAlwaysAndWhenInUseUsageDescription

接下来,在 Target Capabilities 中,打开 Background Modes 并检查 Location updatesBackground fetch。位置更新将在后台启用位置,而后台获取将允许您在后台使用网络。

开始监控

首先创建CLLocationManager 的实例,对其进行配置并打开后台更新,然后启动它。尽管下面的代码使用最常用的函数startUpdatingLocation 来获取位置,但还有其他几个服务可供使用。选择最合适的服务是重要,因为这会极大地影响电池使用以及应用程序是否会被 iOS 重新启动。有关这方面的更多信息,请参见下文。

// Declare as properties in your class
@property (strong, nonatomic) CLLocationManager *locationManager;
@property (strong, nonatomic) CLLocation *lastLocation;

// Call to start
- (void)initializeAndStartLocationService 
    self.locationManager = [[CLLocationManager alloc] init];
    self.locationManager.delegate = self;

    // Must be set for background operation
    self.locationManager.allowsBackgroundLocationUpdates = YES;

    // Optional configuration
    self.locationManager.distanceFilter = kCLDistanceFilterNone;
    self.locationManager.desiredAccuracy = kCLLocationAccuracyBest;
    self.locationManager.pausesLocationUpdatesAutomatically = YES;
    self.locationManager.showsBackgroundLocationIndicator = YES;

    // Authorize - the lazy way
    [self.locationManager requestAlwaysAuthorization];

    // Start the standard location service, there are others
    [self.locationManager startUpdatingLocation];


// Delegate method that will receive location updates
- (void)locationManager:(CLLocationManager *)manager didUpdateLocations:(NSArray<CLLocation *> *)locations 
    // Keep the last received location
    self.lastLocation = [locations lastObject];

    NSLog(@"New position %f, %f", self.lastLocation.coordinate.latitude, self.lastLocation.coordinate.longitude);

    // Do something with the location or retrieve the location later
    //       :

停止监控

不要忘记停止监控以节省电池电量。您可以在 CLLocationManager 的单个实例上多次启动和停止。

- (void)dealloc 
    [self.locationManager stopUpdatingLocation];

应用自动重新启动注意事项

当您的应用在后台运行时,它可以(实际上经常会在一段时间后)被 iOS 终止。根据您使用的位置更新类型,iOS 会或不会自动为您重新启动您的应用程序。如果 iOS 没有重新启动,用户必须重新启动您的应用才能继续后台处理。

阅读更多this page。

阅读更多

CLLocationManager - Core Location | Apple DocumentationHandling Location Events in the Background | Apple Documentation

【讨论】:

以上是关于当应用程序在后台时向服务器发送纬度和经度的主要内容,如果未能解决你的问题,请参考以下文章

即使应用程序关闭,也每 5 分钟向服务器发送纬度和经度

如何定期向 Web 服务器发送位置数据(纬度、经度)

当应用程序在iOS swift 3中处于后台模式时如何每10秒获取一次纬度和经度

如何防止从客户端向服务器端发送数据(位置、纬度和经度)作弊?

我可以通过始终在后台运行的服务跟踪 gps 纬度和经度吗?

将地址转换为经度和纬度