最近做一个考勤APP,功能很简单,就是一直在后台运行,每隔固定时间向服务器上传一次位置信息。持续运行24小时测试,功能实现。
1.ViewController.h文件:
#import <CoreLocation/CoreLocation.h>并实现CLLocationManagerDelegate 代理,.h文件完整代码如下:
- #import <UIKit/UIKit.h>
- #import <CoreLocation/CoreLocation.h>
- @interface ViewController : UIViewController<CLLocationManagerDelegate>
- @end
2.info.list文件:
右键,Add Row,添加的Key为NSLocationAlwaysUsageDescription,其它值默认,示例如下:
3.添加后台定位权限
4.ViewController.m 文件:
(1)定义一个私有CLLocationManager对象
(2)初始化并设置参数(initLocation方法),其中
locationManager.desiredAccuracy设置定位精度,有六个值可选,精度依次递减
kCLLocationAccuracyBestForNavigation
kCLLocationAccuracyBest
kCLLocationAccuracyNearestTenMeters
kCLLocationAccuracyHundredMeters
kCLLocationAccuracyKilometer
kCLLocationAccuracyThreeKilometers
locationManager.pausesLocationUpdatesAutomatically 设置是否允许系统自动暂停定位,这里要设置为NO,刚开始我没有设置,后台定位持续20分钟左右就停止了!
(3)实现CLLocationManagerDelegate的代理方法,此方法在每次定位成功后调用:
-(void)locationManager:(CLLocationManager *)manager didUpdateLocations:(NSArray*)locations;
*也可以通过实现以下方法:
- (void)locationManager:(CLLocationManager *)manager
didUpdateToLocation:(CLLocation *)newLocation
fromLocation:(CLLocation *)oldLocation
(4)实现CLLocationManagerDelegate的代理方法,此方法在定位出错后调用:
-(void)locationManager:(CLLocationManager *)manager didFailWithError:(NSError *)error
- #import "ViewController.h"
- @interface ViewController (){
- CLLocationManager *locationManager;
- CLLocation *newLocation;
- CLLocationCoordinate2D coordinate;
- }
- @end
- @implementation ViewController
- - (void)viewDidLoad {
- [super viewDidLoad];
- [self initLocation];
- }
- #pragma mark 初始化定位
- -(void)initLocation {
- locationManager=[[CLLocationManager alloc] init];
- locationManager.delegate = self;
- locationManager.desiredAccuracy = kCLLocationAccuracyBest;//设置定位精度
- if([[[UIDevice currentDevice] systemVersion] floatValue] >= 8.0){
- [locationManager requestWhenInUseAuthorization];
- }
- if(![CLLocationManager locationServicesEnabled]){
- NSLog(@"请开启定位:设置 > 隐私 > 位置 > 定位服务");
- }
- if([locationManager respondsToSelector:@selector(requestAlwaysAuthorization)]) {
- [locationManager requestAlwaysAuthorization]; // 永久授权
- [locationManager requestWhenInUseAuthorization]; //使用中授权
- }
- locationManager.pausesLocationUpdatesAutomatically = NO;
- [locationManager startUpdatingLocation];
- //[locationManager startMonitoringSignificantLocationChanges];
- }
- #pragma mark 定位成功
- -(void)locationManager:(CLLocationManager *)manager didUpdateLocations:(NSArray *)locations{
- newLocation = [locations lastObject];
- double lat = newLocation.coordinate.latitude;
- double lon = newLocation.coordinate.longitude;
- NSLog(@"lat:%f,lon:%f",lat,lon);
- }
- #pragma mark 定位失败
- -(void)locationManager:(CLLocationManager *)manager didFailWithError:(NSError *)error{
- NSLog(@"error:%@",error);
- }
- - (void)didReceiveMemoryWarning {
- [super didReceiveMemoryWarning];
- // Dispose of any resources that can be recreated.
- }
- @end
**经过充电状态下以及非充电状态下测试各24小时,APP运行正常,下图为考勤记录截图,另外测试时,每次定位成功都将日志保存到本地plist文件中中,方法链接:http://blog.csdn.net/dolacmeng/article/details/44805953
allowDeferredLocationUpdatesUntilTraveled:timeout:
,可以设置在用户移动多远距离或者经过多少时间间隔后才进行一次定位,从而达到省电的目的。
- // Delegate method from the CLLocationManagerDelegate protocol.
- - (void)locationManager:(CLLocationManager *)manager
- didUpdateLocations:(NSArray *)locations {
- // Add the new locations to the hike
- [self.hike addLocations:locations];
- // Defer updates until the user hikes a certain distance
- // or when a certain amount of time has passed.
- if (!self.deferringUpdates) {
- CLLocationDistance distance = self.hike.goal - self.hike.distance;
- NSTimeInterval time = [self.nextAudible timeIntervalSinceNow];
- [locationManager allowDeferredLocationUpdatesUntilTraveled:distance
- timeout:time];
- self.deferringUpdates = YES;
- }
- }
因此我们把didUpdateLocations方法改成这样(deferringUpdates是BOOl类型全局变量,标记是否是Defer):
#pragma mark 定位成功
- -(void)locationManager:(CLLocationManager *)manager didUpdateLocations:(NSArray *)locations{
- newLocation = [locations lastObject];
- double lat = newLocation.coordinate.latitude;
- double lon = newLocation.coordinate.longitude;
- NSLog(@"lat:%f,lon:%f",lat,lon);
- if (!self.deferringUpdates) {
- CLLocationDistance distance = 500;
- NSTimeInterval time = 20;
- [locationManager allowDeferredLocationUpdatesUntilTraveled:distance
- timeout:time];
- self.deferringUpdates = YES;
- }
- }