iOS后台持续定位并定时上传
2016-07-05 15:34
691 查看
最近做一个考勤APP,功能很简单,就是一直在后台运行,每隔固定时间向服务器上传一次位置信息。持续运行24小时测试,功能实现。
#import <CoreLocation/CoreLocation.h>并实现CLLocationManagerDelegate 代理,.h文件完整代码如下:
[objc] view
plain copy
#import <UIKit/UIKit.h>
#import <CoreLocation/CoreLocation.h>
@interface ViewController : UIViewController<CLLocationManagerDelegate>
@end
右键,Add Row,添加的Key为NSLocationAlwaysUsageDescription,其它值默认,示例如下:
(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
.m文件完整代码如下:
[objc] view
plain copy
#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
(5)以上方法虽然可以让APP在后台运行,但是定位是一直在运行着,难免产生耗电量大的问题,从iOS6开始,Apple提供了方法
官方说明文档:
官方示例代码:
[objc] view
plain copy
// 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 定位成功
[objc] view
plain copy
-(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;
}
}
但是经过测试,还是没有达到延时的效果,经过查看官方文档和Google后,可能的原因有1.需要使用iphone5及以上的硬件设备(模拟器不得行)2.有其它APP也在请求定位信息,先把他们结束掉。。。。等等等,可以看看这篇论坛讨论:https://devforums.apple.com/message/766429#766429
1.ViewController.h文件:
#import <CoreLocation/CoreLocation.h>并实现CLLocationManagerDelegate 代理,.h文件完整代码如下:[objc] view
plain copy
#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
.m文件完整代码如下:
[objc] view
plain copy
#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
(5)以上方法虽然可以让APP在后台运行,但是定位是一直在运行着,难免产生耗电量大的问题,从iOS6开始,Apple提供了方法
allowDeferredLocationUpdatesUntilTraveled:timeout:,可以设置在用户移动多远距离或者经过多少时间间隔后才进行一次定位,从而达到省电的目的。
官方说明文档:
官方示例代码:
[objc] view
plain copy
// 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 定位成功
[objc] view
plain copy
-(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;
}
}
但是经过测试,还是没有达到延时的效果,经过查看官方文档和Google后,可能的原因有1.需要使用iphone5及以上的硬件设备(模拟器不得行)2.有其它APP也在请求定位信息,先把他们结束掉。。。。等等等,可以看看这篇论坛讨论:https://devforums.apple.com/message/766429#766429
相关文章推荐
- iOS Code Signing
- IOS 系统打电话事件的监听与状态获取
- Xcode7隐藏、更改状态栏
- AFNetworking 使用说明
- 【IOS】在某个页面第一次启动的时候,显示引导页
- iOS 常用的#define合集
- CoreData轻量级版本迁移
- iOS开发-关闭/收起键盘方法总结
- iOS 启动页后广告Demo
- iOS 时间戳转化为时间(附13位转10位方法)
- iOS-Error Domain=NSCocoaErrorDomain Code=3840 "The operation couldn’t be complet
- iOS 中const的使用
- ios 类似于网易的启动页广告
- iOS中处理计算精度要求很高的数据
- iOS之Alcatraz常见插件
- iOS使用第三方管理工具
- TableViewController中的搜索框和mj刷新配合使用
- IOS 如何选择delegate、notification、KVO?
- iOS绘制图形的基本方法
- iOS开发多线程篇—线程间的通信