ios 如何在后台跟踪用户位置?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/17465929/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-31 00:12:17  来源:igfitidea点击:

How to track user location in background?

iosios6geolocationcore-locationcllocationdistance

提问by Alexey Sidorov

I'm looking for an open source app or library to track user location in the background. Now I'm trying to do it with CLLocationand background tasks, but accuracy is not enough for my case. Could you explain, how apps, like "moves", "runkeeper", "endmondo", creates my route? Should I use Accelerometer or/and compass to create a route between CLLocation background points?

我正在寻找一个开源应用程序或库来在后台跟踪用户位置。现在我正在尝试使用CLLocation后台任务来完成它,但对于我的案例来说,准确性还不够。你能解释一下,像“移动”、“跑卫”、“endmondo”这样的应用程序是如何创建我的路线的吗?我应该使用加速度计或/和指南针在 CLLocation 背景点之间创建路线吗?

Some code:

一些代码:

//location manager init
self.locationManager = [[CLLocationManager alloc] init];
self.locationManager.distanceFilter = kCLDistanceFilterNone;
self.locationManager.desiredAccuracy = kCLLocationAccuracyBest;
self.locationManager.delegate = self;


#pragma mark - CLLocationManager Delegate

- (void)locationManager:(CLLocationManager *)manager didUpdateToLocation:(CLLocation *)newLocation fromLocation:(CLLocation *)oldLocation {

    if ([self isInBackground]) {
        if (self.locationUpdatedInBackground) {
            bgTask = [[UIApplication sharedApplication] beginBackgroundTaskWithExpirationHandler: ^{
                [[UIApplication sharedApplication] endBackgroundTask:bgTask];
            }];

            self.locationUpdatedInBackground(newLocation);
            [self endBackgroundTask];
        }
    } else {
        if (self.locationUpdatedInForeground) {
            self.locationUpdatedInForeground(newLocation);
        }
    }
}

UPD: Justed tested my app with next properties

UPD:Justed 使用下一个属性测试了我的应用程序

self.locationManager.distanceFilter = kCLDistanceFilterNone;
self.locationManager.desiredAccuracy = kCLLocationAccuracyBest;
self.locationManager.activityType = CLActivityTypeFitness;
self.locationManager.pausesLocationUpdatesAutomatically=NO;

In this case I have about 10 fired events during 1,5 hour trip

在这种情况下,我在 1.5 小时的行程中大约有 10 个触发事件

回答by Phillip Kamikaze

Use

kCLLocationAccuracyBestForNavigation

kCLLocationAccuracyBestForNavigation

check this.

检查这个

回答by Maxime Berail

You need to add in your "Info.plist" file the key UIBackgroundModes(array) with the value "location" (app registers for location updates). You can check all background modes here.

您需要在“Info.plist”文件中添加UIBackgroundModes值为“location”的键(数组)(应用程序注册位置更新)。您可以在此处查看所有背景模式。

回答by Ravi_Parmar

So your app uses location services. Then please read the Location Awareness Programming Guide.

所以您的应用程序使用位置服务。然后请阅读位置感知编程指南

You need to make some changes to your Info.plist:

您需要对 Info.plist 进行一些更改:

  • If your app relies on location services to function properly, add location-services to UIRequiredDeviceCapabilities
  • if your app requires GPS hardware, add gps to UIRequiredDeviceCapabilities
  • if you need to run your app longer then 10 minutes in the background, add location to UIBackgroundModes. Then your location manager will deliver locations beyond the 10-minute-limit.
  • you should also set NSLocationUsageDescription (can also be localized)
  • 如果您的应用依赖位置服务才能正常运行,请将位置服务添加到 UIRequiredDeviceCapabilities
  • 如果您的应用需要 GPS 硬件,请将 gps 添加到 UIRequiredDeviceCapabilities
  • 如果您需要在后台运行应用程序超过 10 分钟,请将位置添加到 UIBackgroundModes。然后,您的位置经理将提供超过 10 分钟限制的位置。
  • 您还应该设置 NSLocationUsageDescription(也可以本地化)

Getting Location Events in the Background

在后台获取位置事件

If your app needs location updates delivered whether the app is in the foreground or background, there are multiple options for doing so. The preferred option is to use the significant location change service to wake your app at appropriate times to handle new events. However, if your app needs to use the standard location service, you can declare your app as needing background location services.

如果您的应用需要提供位置更新,无论应用是在前台还是后台,都有多种选择。首选选项是使用显着位置更改服务在适当的时间唤醒您的应用程序以处理新事件。但是,如果您的应用需要使用标准位置服务,您可以声明您的应用需要后台位置服务。

An app should request background location services only if the absence of those services would impair its ability to operate. In addition, any app that requests background location services should use those services to provide a tangible benefit to the user. For example, a turn-by-turn navigation app would be a likely candidate for background location services because of its need to track the user's position and report when it is time to make the next turn.

仅当缺少这些服务会损害其运行能力时,应用才应请求后台位置服务。此外,任何请求后台位置服务的应用程序都应该使用这些服务来为用户提供切实的好处。例如,逐向导航应用程序可能是后台定位服务的候选者,因为它需要跟踪用户的位置并报告何时需要进行下一次转弯。

回答by AlexWien

Your problem is the background handler. Remove it and enable gps background mode in plist file. then you should get full power gps all the time.

您的问题是后台处理程序。删除它并在 plist 文件中启用 gps 背景模式。那么您应该始终获得全功率 GPS。

Set property pausesLocationUpdatesAutomatically=NO

设置属性 pausesLocationUpdatesAutomatically=NO

This is new in ios6.

这是 ios6 的新功能。

From CLLocationManager:

CLLocationManager

Allowing the location manager to pause updates can improve battery life on the target device without sacrificing location data. When this property is set to YES, the location manager pauses updates (and powers down the appropriate hardware) at times when the location data is unlikely to change. For example, if the user stops for food while using a navigation app, the location manager might pause updates for a period of time. You can help the determination of when to pause location updates by assigning a value to the activityType property.

The default value of this property is YES.

允许位置管理器暂停更新可以在不牺牲位置数据的情况下延长目标设备的电池寿命。当此属性设置为 YES 时,位置管理器会在位置数据不太可能更改时暂停更新(并关闭适当的硬件)。例如,如果用户在使用导航应用程序时停下来吃饭,位置管理器可能会暂停更新一段时间。您可以通过为 activityType 属性分配一个值来帮助确定何时暂停位置更新。

此属性的默认值为 YES。

For analysis add these methods to your LocationManager delegate:

为了分析,将这些方法添加到您的 LocationManager 委托中:

- (void)locationManagerDidPauseLocationUpdates:(CLLocationManager *)manager {
     NSLog(@"locMan: locationManagerDidPauseLocationUpdates");
}

- (void)locationManagerDidResumeLocationUpdates:(CLLocationManager *)manager {
    NSLog(@"locMan: locationManagerDidResumeLocationUpdates");
}

回答by Suryakant Sharma

You can set up monitoring location stuff in you VC as below

你可以在你的 VC 中设置监控位置的东西,如下所示

in viewDidLoad method do as below

在 viewDidLoad 方法中做如下

CLLocationManager locationManager = [[CLLocationManager alloc] init];
locationManager.delegate = self;
locationManager.distanceFilter = kCLDistanceFilterNone;
locationManager.desiredAccuracy = kCLLocationAccuracyBest;(Accuracy according to your need)
[locationManager startUpdatingLocation];

than you have to overrite below two optional delegate methods of CLLocationManagerDelegate protocol

比您必须覆盖 CLLocationManagerDelegate 协议的两个可选委托方法

for iOS6+

适用于 iOS6+

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

and for iOS 2 to 6

和 iOS 2 到 6

- (void)locationManager:(CLLocationManager *)manager didUpdateToLocation:(CLLocation *)newLocation fromLocation:(CLLocation *)oldLocation

in these methods you will get updated location. use it as you want. every time location updated these method get calls.

在这些方法中,您将获得更新的位置。随心所欲地使用它。每次位置更新时,这些方法都会调用。

回答by Marc Millet

you don't ask for code. You ask for: "I'm looking for an open source app or library"

你不要求代码。您要求:“我正在寻找开源应用程序或库”

It may help you to visit thiswebsite.

它可以帮助您访问网站。

hope it helps you,

希望对你有帮助

Also a tutorial.

还有教程

回答by jsetting32

Here was my solution to this,

这是我对此的解决方案,

Declare the instance variable:

声明实例变量:

CLLocationManager *locationManager;

Be sure to include the delegate

确保包括代表

<CLLocationManagerDelegate>

In viewDidLoad:

在 viewDidLoad 中:

locationManager = [[CLLocationManager alloc] init];
locationManager.delegate = self;
locationManager.distanceFilter = kCLDistanceFilterNone; // whenever we move, location is updated
locationManager.desiredAccuracy = kCLLocationAccuracyBest; // get best current locaton coords
locationManager.headingFilter = 1;
[locationManager startUpdatingLocation];
[locationManager startUpdatingHeading];

Implement the delegate method:

实现委托方法:

- (void)locationManager:(CLLocationManager *)manager didUpdateToLocation:(CLLocation *)newLocation fromLocation:(CLLocation *)oldLocation
{
    int degrees = newLocation.coordinate.latitude;
    double decimal = fabs(newLocation.coordinate.latitude - degrees);
    int minutes = decimal * 60;
    double seconds = decimal * 3600 - minutes * 60;
    NSString *lat = [NSString stringWithFormat:@"%d° %d' %1.4f\"",
                     degrees, minutes, seconds];
    NSLog(@" Current Latitude : %@",lat);
    latitudeLocation.text = lat;
    degrees = newLocation.coordinate.longitude;
    decimal = fabs(newLocation.coordinate.longitude - degrees);
    minutes = decimal * 60;
    seconds = decimal * 3600 - minutes * 60;
    NSString *longt = [NSString stringWithFormat:@"%d° %d' %1.4f\"",
                       degrees, minutes, seconds];
    NSLog(@" Current Longitude : %@",longt);
    longitudeLocation.text = longt;
}

回答by Joel Green

Disclaimer: I work for Cintric

免责声明:我为 Cintric 工作

We also wanted to be able to accurately track a users location in background (even after the app had been killed). We spent a long time solving the problem, especially focusing on battery drain.

我们还希望能够在后台准确跟踪用户位置(即使在应用程序被杀死之后)。我们花了很长时间来解决这个问题,尤其是在电池消耗方面。

We posted a great blog poston how we solved it. And also are providing a drag and drop SDK solution. It's not open source but you can integrate it for free:

我们发布了一篇很棒的博客文章,介绍了我们如何解决它。并且还提供拖放SDK解决方案。它不是开源的,但您可以免费集成它:

You can download the .framework file, drag it into your project and initialize with one line of code: [CintricFind initWithApiKey:@"YOUR_API_KEY_HERE" andSecret:@"YOUR_SECRET_HERE"];

您可以下载 .framework 文件,将其拖到您的项目中并使用一行代码进行初始化: [CintricFind initWithApiKey:@"YOUR_API_KEY_HERE" andSecret:@"YOUR_SECRET_HERE"];

You can get an API key for free. There are docs explaining everything here.

您可以免费获得 API 密钥。有文档解释了这里的一切。