简体   繁体   English

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

[英]How to track user location in background?

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 CLLocation and background tasks, but accuracy is not enough for my case. 现在我正在尝试使用CLLocation和后台任务,但对于我的情况,准确性还不够。 Could you explain, how apps, like "moves", "runkeeper", "endmondo", creates my route? 你能解释一下,像“移动”,“管理员”,“endmondo”等应用程序如何创建我的路线? Should I use Accelerometer or/and compass to create a route between CLLocation background points? 我应该使用Accelerometer或/和指南针在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个被解雇的事件

Use 使用

kCLLocationAccuracyBestForNavigation kCLLocationAccuracyBestForNavigation

check this . 检查一下

You need to add in your "Info.plist" file the key UIBackgroundModes (array) with the value "location" (app registers for location updates). 您需要在“Info.plist”文件中添加键值为“location”的关键UIBackgroundModes (数组)(app注册位置更新)。 You can check all background modes here . 您可以在此处查看所有背景模式。

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 如果您的应用依赖于位置服务来正常运行,请将位置服务添加到UIRequiredDeviceCapabilities
  • if your app requires GPS hardware, add gps to UIRequiredDeviceCapabilities 如果您的应用需要GPS硬件,请将gps添加到UIRequiredDeviceCapabilities
  • if you need to run your app longer then 10 minutes in the background, add location to UIBackgroundModes. 如果您需要在后台运行超过10分钟的应用程序,请将位置添加到UIBackgroundModes。 Then your location manager will deliver locations beyond the 10-minute-limit. 然后,您的位置经理将提供超过10分钟限制的位置。
  • you should also set NSLocationUsageDescription (can also be localized) 你还应该设置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. 例如,逐向导航应用程序可能是后台定位服务的候选者,因为它需要跟踪用户的位置并报告何时进行下一轮转弯。

Your problem is the background handler. 你的问题是后台处理程序。 Remove it and enable gps background mode in plist file. 将其删除并在plist文件中启用gps后台模式。 then you should get full power gps all the time. 然后你应该一直获得全功率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. 当此属性设置为YES时,位置管理器会在位置数据不太可能更改时暂停更新(并关闭相应的硬件)。 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. 您可以通过为activityType属性指定值来帮助确定何时暂停位置更新。

The default value of this property is YES. 此属性的默认值为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");
}

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. 每次位置更新这些方法获取调用。

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 this website. 它可能会帮助您访问网站。

hope it helps you, 希望它能帮到你,

Also a tutorial . 也是一个教程

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;
}

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 post on how we solved it. 我们发布了一篇关于我们如何解决它的博文 And also are providing a drag and drop SDK solution. 并且还提供拖放SDK解决方案。 It's not open source but you can integrate it for free: 它不是开源的,但您可以免费集成它:

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. 您可以免费获得API密钥。 There are docs explaining everything here . 有文档解释一切在这里

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM