iOS开发 程序后台上传位置CLLocationManager
来源:互联网 发布:韵乐x5效果器软件 编辑:程序博客网 时间:2024/06/11 18:20
之前开发一款配送员用的APP时,用到了在程序在后台时,可以不断上传位置的功能,今天略微整理了一下,
主要用到系统的CoreLocation
代码:
#import <Foundation/Foundation.h>#import <UIKit/UIKit.h>@interface XSDLocationTools : NSObject+ (XSDLocationTools *)shareInstance;// 开启定位- (void)startLocationService;@end
.m
//// XGLocationTool.m// XGPayDemo//// Created by 小广 on 16/4/25.// Copyright © 2016年 小广. All rights reserved.//#import "XSDLocationTools.h"#import <CoreLocation/CoreLocation.h>//#import "WGS84ToGCJ02.h"#import "BaiduMapDefine.h"#import "XSDBaiduMapTools.h"#define LAST_LONG @"last_longitude" // 上次上传位置的经度#define LAST_LATI @"last_latitude" // 上次上传位置的纬度@interface XSDLocationTools ()<CLLocationManagerDelegate>{ //dispatch_source_t _timer; CLLocationCoordinate2D _newCoor;}// 1.设置位置管理者属性@property (nonatomic, strong) CLLocationManager *lcManager;//@property (nonatomic, assign) BOOL isRequest;@property (nonatomic, strong) NSTimer *uploadTimer;@end@implementation XSDLocationTools+ (XSDLocationTools *)shareInstance { static XSDLocationTools *instance = nil; static dispatch_once_t onceToken; dispatch_once(&onceToken, ^{ instance = [[XSDLocationTools alloc] init]; [instance p_addNSNotificationObserver]; }); return instance;}// 开启定位- (void)startLocationService { if ([CLLocationManager locationServicesEnabled]) { // 创建位置管理者对象 self.lcManager = [[CLLocationManager alloc] init]; self.lcManager.delegate = self; // 设置代理 // 设置定位距离过滤参数 (当本次定位和上次定位之间的距离大于或等于这个值时,调用代理方法) self.lcManager.distanceFilter = 50; self.lcManager.desiredAccuracy = kCLLocationAccuracyBest; // 设置定位精度(精度越高越耗电) // 2、在Info.plist文件中添加如下配置: //(1)NSLocationAlwaysUsageDescription 授权使应用在前台后台都能使用定位服务 //(2)NSLocationWhenInUseUsageDescription 授权使应用只能在前台使用定位服务 // 两者也可以都写 if ([[UIDevice currentDevice].systemVersion floatValue] >=8.0 ) { // iOS0.0:如果当前的授权状态是使用是授权,那么App退到后台后,将不能获取用户位置,即使勾选后台模式:location [self.lcManager requestAlwaysAuthorization]; [self.lcManager requestWhenInUseAuthorization]; } // iOS9.0+ 要想继续获取位置,需要使用以下属性进行设置(注意勾选后台模式:location)但会出现蓝条 if ([self.lcManager respondsToSelector:@selector(allowsBackgroundLocationUpdates)]) { // self.lcManager.allowsBackgroundLocationUpdates = YES; } [self.lcManager startUpdatingLocation]; // 开始更新位置 [self.uploadTimer setFireDate:[NSDate distantPast]]; // 开启定时器 }}/** 获取到新的位置信息时调用*/-(void)locationManager:(CLLocationManager *)manager didUpdateLocations:(NSArray *)locations { CLLocation *tempLocation = locations[0]; // 将坐标转化为百度坐标 方法来源于百度sdk NSDictionary *temp = BMKConvertBaiduCoorFrom(tempLocation.coordinate, BMK_COORDTYPE_GPS); CLLocationCoordinate2D nowLocation = BMKCoorDictionaryDecode(temp); //if (self.isRequest) return; //self.isRequest = YES; //[self uploadUserLocationHandle:nowLocation]; //[self uploadLocationTimer:nowLocation]; _newCoor = nowLocation;}/** 不能获取位置信息时调用*/-(void)locationManager:(CLLocationManager *)manager didFailWithError:(NSError *)error { NSLog(@"获取定位失败");}/** 定位服务状态改变时调用*/- (void)locationManager:(CLLocationManager *)manager didChangeAuthorizationStatus:(CLAuthorizationStatus)status{ switch (status) { case kCLAuthorizationStatusNotDetermined: { NSLog(@"用户还未决定授权"); break; } case kCLAuthorizationStatusRestricted: { NSLog(@"访问受限"); break; } case kCLAuthorizationStatusDenied: { // 类方法,判断是否开启定位服务 if ([CLLocationManager locationServicesEnabled]) { NSLog(@"定位服务开启,被拒绝"); } else { NSLog(@"定位服务关闭,不可用"); } break; } case kCLAuthorizationStatusAuthorizedAlways: { NSLog(@"获得前后台授权"); break; } case kCLAuthorizationStatusAuthorizedWhenInUse: { NSLog(@"获得前台授权"); break; } default: break; }}// 直接上传用户位置static NSInteger uploadCount = 1;- (void)uploadUserLocationHandle:(CLLocationCoordinate2D)coor { NSDictionary *dic = @{@"longitude":@(coor.longitude), @"latitude":@(coor.latitude)}; __weak typeof(self)weakSelf = self; [[UserManager shareInstance] uploadUserLocation:dic block:^(BOOL success) { if (!success) { if (uploadCount > 3) return ; uploadCount ++; [weakSelf uploadUserLocationHandle:coor]; XSDLog(@"上传位置不ok"); return; } // if (uploadCount != 1) uploadCount = 1; XSDLog(@"上传位置ok"); }]; }// 定时上传位置- (void)uploadLocationTimer { BOOL canUpload = [self isCanUpload:_newCoor]; if (canUpload) { NSDictionary *dic = @{@"longitude":@(_newCoor.longitude), @"latitude":@(_newCoor.latitude)}; __weak typeof(self)weakSelf = self; // 和后台服务器进行交互 上传位置 [[UserManager shareInstance] uploadUserLocation:dic block:^(BOOL success) { if (success) { XSDLog(@"上传位置ok"); return ; } XSDLog(@"上传位置不ok"); [weakSelf uploadUserLocationHandle:_newCoor]; }]; } }// 监听用户登录的通知- (void)p_addNSNotificationObserver { [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(p_loginNotification) name:kLoginNotification object:nil];}- (void)p_loginNotification { // 用户登录, 就开始上传位置 NSString *latitude = [XSDTools objectForKey:TCPFLocationlatitude]; NSString *longitude = [XSDTools objectForKey:TCPFLocationlongitude]; if (!latitude || !longitude) return; // 读取本地的经纬度 CLLocationCoordinate2D location = CLLocationCoordinate2DMake(latitude.doubleValue, longitude.doubleValue); [self uploadUserLocationHandle:location];}// 是否达到条件(判断距离 大于一定距离)上传位置- (BOOL)isCanUpload:(CLLocationCoordinate2D)coor { // 下面代码相当于 NSUserDefaults 存取数据 NSString *latitude = [XSDTools objectForKey:LAST_LATI]; NSString *longitude = [XSDTools objectForKey:LAST_LONG]; if (!latitude || !longitude) { // 下面代码相当于 NSUserDefaults 存取数据 [XSDTools setValue:[NSString stringWithFormat:@"%f",coor.latitude] forKey:LAST_LATI]; [XSDTools setValue:[NSString stringWithFormat:@"%f",coor.longitude] forKey:LAST_LONG]; return YES; } // 下面代码来源于百度sdk 计算两点间的距离 NSNumber *distence = [XSDBaiduMapTools calculateTwoPointLongWithStart:CLLocationCoordinate2DMake(latitude.doubleValue, longitude.doubleValue) end:coor]; if (distence.integerValue >= 100) { // 下面代码相当于 NSUserDefaults 存取数据 [XSDTools setValue:[NSString stringWithFormat:@"%f",coor.latitude] forKey:LAST_LATI]; [XSDTools setValue:[NSString stringWithFormat:@"%f",coor.longitude] forKey:LAST_LONG]; return YES; } return NO;}// 懒加载- (NSTimer *)uploadTimer { if (!_uploadTimer) { _uploadTimer = [NSTimer scheduledTimerWithTimeInterval:10.0 target:self selector:@selector(uploadLocationTimer) userInfo:nil repeats:YES]; } return _uploadTimer;}@end里面用到了一些自定义的类,不过不影响,各位可以根据需求修改,挺简单的;
在AppDelegate的- (BOOL)application:(UIApplication *)application willFinishLaunchingWithOptions:(NSDictionary *)launchOptions 方法里
直接调用即可:[[XSDLocationTools shareInstance] startLocationService];
还有,是必须在如图所示,勾选location updates;
图:
最后,审核的时候,一定要说明清楚,为啥要用这个后台上传位置功能;这个审核被拒概率很大,也没有好的解决方法;
0 0
- iOS开发 程序后台上传位置CLLocationManager
- Ios开发之定位CLLocationManager
- iOS开发之定位CLLocationManager
- ios开发 CLLocationManager获取位置信息时遇到的一个小问题
- ios开发 后台定位上传
- iOS开发--CoreMotion和CLLocationManager教程
- CLLocationManager 位置定位
- CLLocationManager 位置定位
- iOS后台报告位置
- iOS开发:通过CLLocationManager拿到坐标居中显示
- IOS开发教程--Xcode6,CLLocationManager无法定位解决方案
- ios开发中的官方地图(CLLocationManager)使用
- iOS 后台上传文件
- IOS开发Swift使用NSURLSessionUploadTask实现后台上传功能
- iOS开发:后台定位并上传数据到服务器
- iOS开发中上传JSON字符串到后台服务器
- ios定位CLLocationManager
- ios CLLocationManager定位
- [LeetCode] 75. Sort Colors
- caffe Windows 使用caffelib出错
- Cordova 应用程序创建入门指南
- Sensor信号输出YUV、RGB、RAW DATA、JPEG 4种方式区别
- Runtime 10种用法
- iOS开发 程序后台上传位置CLLocationManager
- ACM--大数阶乘--HDOJ 1042--N!--Java
- html5最新浏览器支持程度比较
- scanning for model in Activeandroid—TableInfo TypeSerializer
- struts2登录验证返回页面跳转
- 数据结构实验之队列一:排队买饭
- Html屏蔽鼠标键盘的几种办法
- MySQL Cluster初步学习资料整理
- 验证手机号的正则表达式