导入框架,导入头文件,引入全局CLLocationManager对象(因为整个工程都要用到它,不能让他死);
//设置代理
self.manager.delegate = self;
// 设置多久获取一次
self.manager.distanceFilter = 500;
// 设置获取位置的精确度
self.manager.desiredAccuracy = kCLLocationAccuracyNearestTenMeters;
/*
注意: iOS7只要开始定位, 系统就会自动要求用户对你的应用程序授权. 但是从iOS8开始, 想要定位必须先"自己""主动"要求用户授权
在iOS8中不仅仅要主动请求授权, 而且必须再info.plist文件中配置一项属性才能弹出授权窗口
NSLocationWhenInUseDescription,允许在前台获取GPS的描述
NSLocationAlwaysUsageDescription,允许在后台获取GPS的描述
*/
if ([[UIDevice currentDevice].systemVersion doubleValue] >= 8.0) {
NSLog(@"是iOS8");
// 主动要求用户对我们的程序授权, 授权状态改变就会通知代理
[self.manager requestAlwaysAuthorization];// 请求前台和后台定位权限
// [self.manager requestWhenInUseAuthorization];// 请求前台定位权限
}
else
{
NSLog(@"是iOS7");
//开始监听(开始获取位置)
[self.manager startUpdatingLocation];
}
#pragma mark - CLLocationManagerDelegate
/**
* 授权状态发生改变时调用
status:当前授权的状态
iOS8以下和iOS8以上都可以用,但是iOS8以下的时候可能有时候不需要,但是当>=iOS8的时候就需要这个方法了,判断状态后开始定位
*/
- (void)locationManager:(CLLocationManager *)manager didChangeAuthorizationStatus:(CLAuthorizationStatus)status
{
/*
用户从未选择过权限
kCLAuthorizationStatusNotDetermined
无法使用定位服务,该状态用户无法改变
kCLAuthorizationStatusRestricted
用户拒绝该应用使用定位服务,或是定位服务总开关处于关闭状态
kCLAuthorizationStatusDenied
已经授权(废弃)
kCLAuthorizationStatusAuthorized
用户允许该程序无论何时都可以使用地理信息
kCLAuthorizationStatusAuthorizedAlways
用户同意程序在可见时使用地理位置
kCLAuthorizationStatusAuthorizedWhenInUse
*/
if (status == kCLAuthorizationStatusNotDetermined) {
NSLog(@"等待用户授权");
}
else if (status == kCLAuthorizationStatusAuthorizedAlways || status == kCLAuthorizationStatusAuthorizedWhenInUse) {
NSLog(@"授权成功");
[self.manager startUpdatingLocation];
}
else{
NSLog(@"授权失败");
}
}
/**
* 获取到位置信息之后就会调用(调用频率非常高)
*/
- (void)locationManager:(CLLocationManager *)manager didUpdateLocations:(NSArray<CLLocation *> *)locations
{
NSLog(@"已经获取到位置了");
//如果只需要获取一次,可以获取到位置之后就停止
[self.manager stopUpdatingLocation];
// 1.获取最后一次的位置
/*
location.coordinate; 坐标, 包含经纬度
location.altitude; 设备海拔高度 单位是米
location.course; 设置前进方向 0表示北 90东 180南 270西
location.horizontalAccuracy; 水平精准度
location.verticalAccuracy; 垂直精准度
location.timestamp; 定位信息返回的时间
location.speed; 设备移动速度 单位是米/秒, 适用于行车速度而不太适用于不行
*/
/*
可以设置模拟器模拟速度
bicycle ride 骑车移动
run 跑动
freeway drive 高速公路驾车
*/
//获取到了经纬度,然后利用地理编码或者反编码技术求取准确中文地址
CLLocation *location = [locations lastObject];
//可以查看到location中的很多信息
NSLog(@"location:%@",location);
NSLog(@"%f, %f speed = %f", location.coordinate.latitude , location.coordinate.longitude, location.speed);
}
2.做汽车导航用到以下两点
//计算两个location之间的距离:distanceFromLocation
CLLocationDistance distance = [newLocation distanceFromLocation:self.previousLocation];
// 计算两次之间的时间(单位只秒)
NSTimeInterval dTime = [newLocation.timestamp timeIntervalSinceDate:self.previousLocation.timestamp];
3.在做指南针的时候,获取的不是用户的位置,而是用户的方向,调用的是如下代码,注意一点,获取用户方向是不需要用户授权的,所以不需要判断是否大于iOS8
// 3.开始获取用户位置
// 注意:获取用户的方向信息是不需要用户授权的
[self.manager startUpdatingHeading];
#pragma mark - CLLocationManagerDelegate
// 当获取到用户方向时就会调用
- (void)locationManager:(CLLocationManager *)manager didUpdateHeading:(CLHeading *)newHeading
{
// NSLog(@"%s", __func__);
/*
magneticHeading 设备与磁北的相对角度
trueHeading 设置与真北的相对角度, 必须和定位一起使用, iOS需要设置的位置来计算真北
真北始终指向地理北极点
*/
// NSLog(@"%f", newHeading.magneticHeading);
// 1.将获取到的角度转为弧度 = (角度 * π) / 180;
CGFloat angle = newHeading.magneticHeading * M_PI / 180;
// 2.旋转图片
/*
顺时针 正
逆时针 负数
*/
// self.compasspointer.transform = CGAffineTransformIdentity;
self.compasspointer.transform = CGAffineTransformMakeRotation(-angle);
}
4.区域检测
在某一个圆形区域中,要是进入或者离开这个区域则会调用相应的代理方法
// 2.成为CoreLocation管理者的代理监听获取到的位置
self.mgr.delegate = self;
// 注意:如果是iOS8, 想进行区域检测, 必须自己主动请求获取用户隐私的权限(因为是要知道用户的地址的呀)
if ([[UIDevice currentDevice].systemVersion doubleValue] >= 8.0 )
{
[self.mgr requestAlwaysAuthorization];
}
// 3.开始检测用户所在的区域
// 3.1创建区域
// CLRegion 有两个子类是专门用于指定区域的
// 一个可以指定蓝牙的范围/ 一个是可以指定圆形的范围
// 创建中心点
CLLocationCoordinate2D center = CLLocationCoordinate2DMake(40.058501, 116.304171);
// c创建圆形区域, 指定区域中心点的经纬度, 以及半径
CLCircularRegion *circular = [[CLCircularRegion alloc] initWithCenter:center radius:500 identifier:@"软件园"];
[self.mgr startMonitoringForRegion:circular];
#pragma mark - CLLocationManagerDelegate
// 进入监听区域时调用
- (void)locationManager:(CLLocationManager *)manager didEnterRegion:(CLRegion *)region
{
NSLog(@"进入监听区域时调用");
}
// 离开监听区域时调用
- (void)locationManager:(CLLocationManager *)manager didExitRegion:(CLRegion *)region
{
NSLog(@"离开监听区域时调用");
}