精华内容
下载资源
问答
  • Android 定位服务和位置权限

    千次阅读 2020-07-27 16:43:33
    做地图功能时,在之前只需要一个位置权限即可,但不知道什么时候加了个定位服务,还是在系统设置里面。 看代码:lm.isProviderEnabled(LocationManager.GPS_PROVIDER);这一句就是定位服务的判断,如果没有开启定位...

    做地图功能时,在之前只需要一个位置权限即可,但不知道什么时候加了个定位服务,还是在系统设置里面。

    看代码:lm.isProviderEnabled(LocationManager.GPS_PROVIDER);这一句就是定位服务的判断,如果没有开启定位服务,就跳到系统定位服务设置界面。

    剩下的就是动态权限和非动态权限的方式了。

    权限申请还是正常的在启动页申请,这一段在定位功能调用的时候使用

    LocationManager lm = (LocationManager) getSystemService(Context.LOCATION_SERVICE);
    boolean ok = lm.isProviderEnabled(LocationManager.GPS_PROVIDER);
    if (ok) {//开启了定位服务
          if (Build.VERSION.SDK_INT >= 23) {
               if (ContextCompat.checkSelfPermission(this, Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED) {
                    //没有权限,现在申请权限
                    ActivityCompat.requestPermissions(this, new String[] {Manifest.permission.ACCESS_FINE_LOCATION}, ChatInputView.BAIDU_READ_PHONE_STATE);
               } else {
                    createGroupMapView();
               }
          } else {
               createGroupMapView();
          }
    } else {//未开启定位服务
         ToastUtil.showToast("系统检测到未开启GPS定位服务,请开启");
         Intent i = new Intent();
         i.setAction(Settings.ACTION_LOCATION_SOURCE_SETTINGS);
         startActivityForResult(i, ChatInputView.PRIVATE_CODE);
    }

     

    展开全文
  • 地图与定位(一)定位服务

    千次阅读 2016-06-20 15:50:33
    定位,CLLocation,LBS

    前言:

    现在很多社交、电商、团购应用都引入了地图和定位功能,似乎地图功能不再是地图应用和导航应用所特有的。的确,有了地图和定位功能确实让我们的生活更加丰富多彩,极大的改变了我们的生活方式。例如你到了一个陌生的地方想要查找附近的酒店、超市等就可以打开软件搜索周边;类似的,还有很多团购软件可以根据你所在的位置自动为你推荐某些商品。总之,目前地图和定位功能已经大量引入到应用开发中。在产品研发中有两个专业术语需要大家知道:一是LBS(Location Based Service)基于定位的服务,二是SoLoMo(Social Local Mobile )社交本地的移动应用,这都是需要我们提供地图和定位服务。

    在后面的课程里就和大家一起看一下iOS如何进行地图和定位开发。iOS系统为了方便我们开发,提供了地图服务的框架。除此之外,实际的开发工作中,我们常常会使用一些第三发的SDK来实现地图服务,主要有高德地图和百度地图,这些我们后在后面的几节中讲到。

    地图功能的实现离不开定位服务,下面我们还是先来看一下iOS系统的定位功能是如何实现的。


    1. 定位服务

    要实现地图、导航功能,往往需要先熟悉定位功能,iOS中的定位引擎是CoreLocation框架提供的,我们通过CoreLocation框架进行定位操作。CoreLocation自身可以单独使用,和地图开发框架MapKit完全是独立的,但是往往地图开发要配合定位框架使用。在Core Location中主要包含了定位、地理编码(包括反编码)功能。

    我们先介绍一下iOS定位功能的实现。定位是一个很常用的功能,如一些地图软件打开之后如果用户允许软件定位的话,那么打开软件后就会自动锁定到当前位置,如果用户手机移动那么当前位置也会跟随着变化。要实现这个功能需要使用CoreLoaction中CLLocationManager类,首先看一下这个类的一些主要方法和属性:
    类方法

    说明

    • (BOOL)locationServicesEnabled;

    是否启用定位服务,通常如果用户没有启用定位服务可以提示用户打开定位服务

    • (CLAuthorizationStatus)authorizationStatus;

    定位服务授权状态,返回枚举类型:
    kCLAuthorizationStatusNotDetermined: 用户尚未做出决定是否启用定位服务
    kCLAuthorizationStatusRestricted: 没有获得用户授权使用定位服务,可能用户没有自己禁止访问授权
    kCLAuthorizationStatusDenied :用户已经明确禁止应用使用定位服务或者当前系统定位服务处于关闭状态
    kCLAuthorizationStatusAuthorizedAlways: 应用获得授权可以一直使用定位服务,即使应用不在使用状态
    kCLAuthorizationStatusAuthorizedWhenInUse: 使用此应用过程中允许访问定位服务

    属性说明
    desiredAccuracy定位精度,枚举类型:kCLLocationAccuracyBest:最精确定位CLLocationAccuracy kCLLocationAccuracyNearestTenMeters:十米误差范围kCLLocationAccuracyHundredMeters:百米误差范围kCLLocationAccuracyKilometer:千米误差范围kCLLocationAccuracyThreeKilometers:三千米误差范围
    distanceFilter位置信息更新最小距离,只有移动大于这个距离才更新位置信息,默认为kCLDistanceFilterNone:不进行距离限制
    对象方法说明
    startUpdatingLocation开始定位追踪,开始定位后将按照用户设置的更新频率执行-(void)locationManager:(CLLocationManager*)manager didUpdateLocations:(NSArray *)locations;方法反馈定位信息
    stopUpdatingLocation停止定位追踪
    startUpdatingHeading开始导航方向追踪
    stopUpdatingHeading停止导航方向追踪
    startMonitoringForRegion:开始对某个区域进行定位追踪,开始对某个区域进行定位后。如果用户进入或者走出某个区域会调用- (void)locationManager:(CLLocationManager )manager didEnterRegion:(CLRegion )region和- (void)locationManager:(CLLocationManager )manager didExitRegion:(CLRegion )region代理方法反馈相关信息
    stopMonitoringForRegion:对某个区域进行定位追踪
    requestWhenInUseAuthorization请求获得应用使用时的定位服务授权,注意使用此方法前在要在info.plist中配置NSLocationWhenInUseUsageDescription
    requestAlwaysAuthorization请求获得应用一直使用定位服务授权,注意使用此方法前要在info.plist中配置NSLocationAlwaysUsageDescription
    代理方法说明
    -(void)locationManager:(CLLocationManager )manager didUpdateLocations:(NSArray )locations;位置发生改变后执行(第一次定位到某个位置之后也会执行)
    -(void)locationManager:(CLLocationManager )manager didUpdateHeading:(CLHeading )newHeading;导航方向发生变化后执行
    -(void)locationManager:(CLLocationManager )manager didEnterRegion:(CLRegion )region进入某个区域之后执行
    -(void)locationManager:(CLLocationManager )manager didExitRegion:(CLRegion )region走出某个区域之后执行

    除了CLLocationManager之外,CLLocation类也是在我们做定位服务中经常看到的,CLLocation常用来表示某个位置的地理信息,比如经纬度、海拔高度等,当然他也给我们提供了计算两个地理位置之间间距的方法。下面我们看一下CLLocation的常用属性和方法:

    方法说明
    -(instancetype)initWithLatitude:(CLLocationDegrees)latitude longitude:(CLLocationDegrees)longitude;初始化CLLocation,传入经纬度
    -(instancetype)initWithCoordinate:(CLLocationCoordinate2D)coordinate altitude:(CLLocationDistance)altitude horizontalAccuracy:(CLLocationAccuracy)hAccuracy verticalAccuracy:(CLLocationAccuracy)vAccuracy timestamp:(NSDate *)timestamp初始化CLLocation,传入经纬度、定位精度和定位时间
    -(instancetype)initWithCoordinate:(CLLocationCoordinate2D)coordinate altitude:(CLLocationDistance)altitude horizontalAccuracy:(CLLocationAccuracy)hAccuracy verticalAccuracy:(CLLocationAccuracy)vAccuracy course:(CLLocationDirection)course speed:(CLLocationSpeed)speed timestamp:(NSDate *)timestamp;初始化CLLocation,传入经纬度、定位精度和定位时间、定位路线、当前速度
    -(CLLocationDistance) getDistanceFrom:(const CLLocation *);计算两个点之间的距离
    -(CLLocationDistance) distanceFromLocation:(const CLLocation *)计算两个点之间的距离
    属性说明
    @property(readonly, nonatomic) CLLocationCoordinate2D coordinate;经纬度,结构体,一般通过函数CLLocationCoordinate2DMake来创建
    @property(readonly, nonatomic) CLLocationDistance altitude;海拔
    @property(readonly, nonatomic) CLLocationAccuracy horizontalAccuracy;水平定位精度
    @property(readonly, nonatomic) CLLocationAccuracy verticalAccuracy;竖直定位精度
    @property(readonly, nonatomic) CLLocationDirection course;路线,航线(范围在0-359.9之间,0代表正北方向)
    @property(readonly, nonatomic) CLLocationSpeed speed;行走速度(m/s)
    @property(readonly, nonatomic, copy) NSDate *timestamp;时间标记

    一般在开始定位之前,应用会向用户获取授权请求,在iOS7及以前的版本,如果在应用程序中使用定位服务只要在程序中调用startUpdatingLocation方法应用就会询问用户是否允许此应用是否允许使用定位服务,同时在提示过程中可以通过在info.plist中配置通过配置Privacy -Location Usage Description告诉用户使用的目的,当然这个配置是可选的。但是在iOS8中配置配置项发生了变化,我们可以通过配置NSLocationAlwaysUsageDescription或者 NSLocationWhenInUseUsageDescription来告诉用户使用定位服务的目的,并且注意这个配置是必须的,如果不进行配置则默认情况下应用无法使用定位服务,打开应用不会给出打开定位服务的提示,除非安装后自己设置此应用的定位服务。同时,在应用程序中需要根据配置对requestAlwaysAuthorization或locationServicesEnabled方法进行请求。
    iOS8提供了更加人性化的定位服务选项。应用的定位服务不再仅仅是关闭或打开。现在,定位服务的启用提供了三个选项:永不、使用应用程序期间、和始终。同时,考虑到能耗问题,如果一款 App 要求始终能在后台开启定位服务,iOS 8 不仅会在首次打开 App 时主动向你询问,还会在日常使用中弹窗提醒你该 App 一直在后台使用定位服务,并询问你是否继续允许。
    下面我们就来看一看iOS实现定位服务的具体步骤有哪些

    • 判断硬件是否开启了定位服务
    • 判断应用是否获取定位授权
    • 初始化定位管家的对象,注意需要设置为全局变量
    • 设置定位权限:iOS8的新特性,可以实现代理方法获取授权范围。注意需要修改plist文件NSLocationAlwaysUsageDescription/NSLocationWhenInUseUsageDescription。
    • 设置定位服务的属性。
    • 开启定位,实现代理方法,获取定位信息

    示例代码

    #import "ViewController.h"
    #import <CoreLocation/CoreLocation.h>
    
    @interface ViewController ()<CLLocationManagerDelegate>
    
    // 定位服务管家
    @property (nonatomic, strong)CLLocationManager *locationManager;
    
    @end
    
    @implementation ViewController
    /*定位的实现
     1.导入框架 CoreLocation.framework
     2.导入库文件 #import <CoreLocation/CoreLocation.h>
     3.需要将定位管家 CLLocationManager 设置为全区变量
    
     1.判断硬件是否开启了定位服务
     2.初始化定位管家的对象,注意需要设置为全局变量
     3.判断定位服务授权状态,设置定位权限:iOS8的新特性,可以实现代理方法获取授权范围。注意需要修改plist文件 NSLocationAlwaysUsageDescription/NSLocationWhenInUseUsageDescription。
     4.设置定位服务的属性。
     5.开启定位,实现代理方法,获取定位信息
     */
    
    - (void)viewDidLoad {
        [super viewDidLoad];
    
        // 1.判断硬件是否开启了定位服务
        BOOL isOpen = [CLLocationManager locationServicesEnabled];
    
        if (isOpen) {
            NSLog(@"定位服务已经打开");
        }else {
            NSLog(@"定位服务未开启");
    
            UIAlertController *alert = [UIAlertController alertControllerWithTitle:@"你的定位服务未开启" message:@"请到setting开启定位服务" preferredStyle:UIAlertControllerStyleAlert];
            [alert addAction:[UIAlertAction actionWithTitle:@"确定" style:UIAlertActionStyleCancel handler:nil]];
            [self presentViewController:alert animated:YES completion:nil];
            return;
        }
    
        // 判断应用是否获取定位授权
        NSInteger status = [CLLocationManager authorizationStatus];
        switch (status) {
            case 0:
                NSLog(@"kCLAuthorizationStatusNotDetermined--没有决定");//  用户从未选择过权限
                break;
            case 1:
                NSLog(@"kCLAuthorizationStatusRestricted--没有许可");// 无法使用定位服务,该状态用户无法改变
                break;
            case 2:
                NSLog(@"kCLAuthorizationStatusDenied--禁止使用");// 用户拒绝该应用使用定位服务,或是定位服务总开关处于关闭状态
                break;
            case 3:
                NSLog(@"kCLAuthorizationStatusAuthorizedAlways--始终允许");// 大致是用户同意程序在任意时候使用地理位置
                break;
            case 4:
                NSLog(@"kCLAuthorizationStatusAuthorizedWhenInUse--开启允许");// 大致是用户同意程序在可见时使用地理位置
                break;
            default:
                break;
        }
    
        // 2.初始化定位管家的对象,注意需要设置为全局变量,因为我们需要一直持有定位管家的对象,局部变量使用后即被销毁,在代理方法中,无法获得该对象及其属性,所以需要设置为全局变量
        [self locationManager];
    
        // 3.判断定位服务授权状态,设置定位权限:iOS8的新特性,可以实现代理方法获取授权范围。注意需要修改plist文件NSLocationAlwaysUsageDescription/NSLocationWhenInUseUsageDescription。
        if ([CLLocationManager authorizationStatus] == kCLAuthorizationStatusNotDetermined) {
            // 判断授权状态,在授权未确定是获取授权,一旦确定即无法在程序中修改,只能在settings中对app做授权设置
    
            if ([[[UIDevice currentDevice] systemVersion] floatValue] >= 8.0) {// 判断系统版本 大于8.0以上的版本可以手动获取授权
    
                // 请求始终允许访问,包括进入后台后 对应info设置:NSLocationAlwaysUsageDescription
    //            [self.locationManager requestAlwaysAuthorization];
                // 请求当app打开时允许访问 对应info设置:NSLocationWhenInUseUsageDescription
                [self.locationManager requestWhenInUseAuthorization];
    
                // 注意:修改plist文件
                // NSLocationAlwaysUsageDescription---我想在后台还访问您的位置
                // NSLocationWhenInUseUsageDescription---我想在我的app开启的时候使用您的位置,可以吗?
            }
        }else if ([CLLocationManager authorizationStatus] == kCLAuthorizationStatusDenied) {
    
            UIAlertController *alert = [UIAlertController alertControllerWithTitle:@"你没有给该应用的定位服务授权" message:@"请到setting设置定位服务授权" preferredStyle:UIAlertControllerStyleAlert];
            [alert addAction:[UIAlertAction actionWithTitle:@"确定" style:UIAlertActionStyleCancel handler:nil]];
            [self presentViewController:alert animated:YES completion:nil];
    
            return;// 没有给予授权
        }
    
        // 4.设置定位服务的属性。
        [self.locationManager setDesiredAccuracy:kCLLocationAccuracyThreeKilometers];
    
        // 设置定位刷新距离,可以直接是由上面的参数指定
        [self.locationManager setDistanceFilter:100];//移动距离大于distanceFilter就会定位,否则不会,避免频繁的定位,消耗电量
    
        // 5.开启定位,实现代理方法,获取定位信息
        [self.locationManager startUpdatingLocation];
    //    [self.locationManager stopUpdatingLocation];// 获取定位数据后调用
    
        // 开始追踪导航方向,
        [self.locationManager startUpdatingHeading];
    //    [self.locationManager stopUpdatingHeading];// 停止追踪导航方向
    
        // 开启区域追踪,需要传入一个追踪区域
        CLLocationCoordinate2D coordinate = CLLocationCoordinate2DMake(39.0, 116.0);
        CLCircularRegion *region = [[CLCircularRegion alloc] initWithCenter:coordinate radius:1000 identifier:@"找到你了"];
        [self.locationManager startMonitoringForRegion:region];
    }
    // 懒加载定位管家
    - (CLLocationManager *)locationManager {
    
        if (!_locationManager) {
    
            _locationManager = [[CLLocationManager alloc] init];
            _locationManager.delegate = self;// 设置定位服务的代理对象
        }
    
        return _locationManager;
    }
    
    #pragma mark CLLocationManagerDelegate
    /**
     *  方法说明:当用户许可状态发生改变时,调用该方法
     *
     *  @param status:用户的许可状态
     *
     *  @return
     */
    - (void)locationManager:(CLLocationManager *)manager didChangeAuthorizationStatus:(CLAuthorizationStatus)status
    {
        NSLog(@"认证状态改变 status:%d",status);
    }
    
    /**
     *  方法说明:执行定位后调用该方法
     *
     *  @param
     *
     *  @return
     */
    - (void)locationManager:(CLLocationManager *)manager
         didUpdateLocations:(NSArray *)locations {
    
        // 停止定位(省电措施:只要不想用定位服务,或者获取定位信息后,就马上停止定位服务)
        [self.locationManager stopUpdatingLocation];
    
        // 1.取出位置对象(数组中可能会有多个位置对象,取出第一个是最精确的)
        CLLocation *loc = [locations firstObject];
    
        // 2.取出经纬度 coordinate:位置坐标  course:方向
        CLLocationCoordinate2D coordinate = loc.coordinate;
        CLLocationDegrees longitude = coordinate.longitude;
        CLLocationDegrees latitude = coordinate.latitude;
    
    
        // 3.CLLocations的常用属性和方法
        /*
         horizontalAccuracy,用来得到水平上的精确度,它的大小就是定位精度的半径,单位为米。获得的不是用户设置的精度  而是最终定位的精度,如果值为-1,则说明此定位不可信。
         course 方向: 0 ~ 359.9 , 0 代表正北
         speed 速度:m/s
         获取两个位置之间的距离
         - (CLLocationDistance)distanceFromLocation:(const CLLocation *)location
         */
        NSLog(@"经度:%f \n 纬度:%f", longitude, latitude);
        NSLog(@"方向:%f \n 海拔:%f",loc.course, loc.altitude);
        NSLog(@"水平定位精度%f  竖直定位精度%f",loc.horizontalAccuracy,loc.verticalAccuracy);
        NSLog(@"速度:%f",loc.speed);
    
        // 计算2个经纬度之间的直线距离
        CLLocation *loc1 = [[CLLocation alloc] initWithLatitude:40 longitude:116];
        CLLocation *loc2 = [[CLLocation alloc] initWithLatitude:41 longitude:116];
    
        // 计算2个经纬度之间的直线距离
        CGFloat distance = [self countLineDistance:loc1 withLocation:loc2];
        NSLog(@"%f",distance);
    }
    
    /**
     *  计算2个经纬度之间的直线距离
     */
    - (double)countLineDistance:(CLLocation *)loc1 withLocation:(CLLocation *)loc2
    {
        CLLocationDistance distance = [loc1 distanceFromLocation:loc2];
    
        return distance;
    }
    
    /**
     *  方法说明: 导航方向发生变化的时候执行此方法
     *
     *  @param  newHeading 方向: 0 ~ 359.9 , 0 代表正北
     *
     *  @return
     */
    - (void)locationManager:(CLLocationManager *)manager didUpdateHeading:(CLHeading *)newHeading
    {
        NSLog(@"方向改变");
    }
    
    - (void)locationManager:(CLLocationManager *)manager didEnterRegion:(CLRegion *)region
    {
        NSLog(@"进入到该区域");
    }
    
    - (void)locationManager:(CLLocationManager *)manager didExitRegion:(CLRegion *)region{
    
        NSLog(@"离开该区域");
    }
    
    @end

    使用定位功能时,有几点需要我们注意:

    • 定位频率和定位精度并不应当越精确越好,需要视实际情况而定,因为越精确越耗性能,也就越费电。
    • 定位成功后会根据设置情况频繁调用-(void)locationManager:(CLLocationManager )manager didUpdateLocations:(NSArray )locations方法,使用完定位服务后如果不需要实时监控应该立即关闭定位服务以节省资源,所以我们需要在合适的时候停止定位。
    • -(void)locationManager:(CLLocationManager )manager didUpdateLocations:(NSArray )locations方法返回一组地理位置对象数组,每个元素一个CLLocation代表地理位置信息(包含经度、纬度、海报、行走速度等信息),之所以返回数组是因为有些时候一个位置点可能包含多个位置。

    2. 地理编码和反地理编码

    除了提供位置跟踪功能之外,在定位服务中还包含CLGeocoder类用于处理地理编码和逆地理编码功能。这个功能的实现主要是由CLGeocoder类提供的。CLGeocoder最主要的两个方法就是

    • -(void)geocodeAddressString:(NSString *)addressString completionHandler:(CLGeocodeCompletionHandler)completionHandler;// 根据给定的位置(通常是地名)确定地理坐标(经、纬度)。
    • -(void)reverseGeocodeLocation:(CLLocation *)location completionHandler:(CLGeocodeCompletionHandler)completionHandler; // 根据地理坐标(经、纬度)确定位置信息(街道、门牌等)。

    在上面两个方法的方法中,当地理编码或是反编码结束时,会回调CLGeocodeCompletionHandler,当中传递给我们两个参数,一个NSArray,一个NSError。NSError是编码或者反编码错误的详情,数组中则存放着我们地理编码或是反地理编码后获取的地标信息,为什么是数组呢,因为我们可能查询到多个地标,比如“帝都”代表的地标就有多个。在CoreLocation框架中,地标是一个CLPlacemark的实例对象。下面我们先来看一下CLPlacemark的常用属性:

    属性说明
    @property (nonatomic, readonly, copy, nullable) CLLocation *location;地理坐标
    @property (nonatomic, readonly, copy, nullable) CLRegion *region;地理范围
    @property (nonatomic, readonly, copy, nullable) NSTimeZone *timeZone地标所在时区
    @property (nonatomic, readonly, copy, nullable) NSString *name;地名
    @property (nonatomic, readonly, copy, nullable) NSString *thoroughfare;街道
    @property (nonatomic, readonly, copy, nullable) NSString *subThoroughfare;街道相关信息,例如门牌等
    @property (nonatomic, readonly, copy, nullable) NSString *locality;城市
    @property (nonatomic, readonly, copy, nullable) NSString *subLocality;城市相关信息,例如标志性建筑
    @property (nonatomic, readonly, copy, nullable) NSString *administrativeArea;
    @property (nonatomic, readonly, copy, nullable) NSString *subAdministrativeArea;其他行政区域信息
    @property (nonatomic, readonly, copy, nullable) NSString *postalCode;邮编
    @property (nonatomic, readonly, copy, nullable) NSString *ISOcountryCode;国家编码
    @property (nonatomic, readonly, copy, nullable) NSString *country;国家
    @property (nonatomic, readonly, copy, nullable) NSString *inlandWater;水源、湖泊
    @property (nonatomic, readonly, copy, nullable) NSString *ocean;海洋
    @property (nonatomic, readonly, copy, nullable) NSArray *areasOfInterest;关联的或利益相关的地标
    @property (nonatomic, readonly, copy) NSDictionary *addressDictionary;地理的详细信息 包含上面所有的数据

    示例代码

    #import "ViewController.h"
    #import <CoreLocation/CoreLocation.h>
    
    @interface ViewController ()
    
    @property (nonatomic, strong)CLGeocoder *geocoder;//地理编码器
    
    #pragma mark - 地理编码 根据地区名称查询所在的经纬度坐标
    @property (strong, nonatomic) IBOutlet UITextField *addressField;//输入地区名称
    @property (strong, nonatomic) IBOutlet UILabel *longitudeLabel;//显示地区的经度
    @property (strong, nonatomic) IBOutlet UILabel *latitudeLabel;//显示地区的纬度
    @property (strong, nonatomic) IBOutlet UILabel *detailAddressLabel;//显示地区的详细信息
    
    #pragma mark - 反地理编码 根据经纬度获取对应的地区名
    @property (strong, nonatomic) IBOutlet UITextField *reverseLongtitudeField;//查询地区的经度
    @property (strong, nonatomic) IBOutlet UITextField *reverseLatitudeField;//查询地区的纬度
    @property (strong, nonatomic) IBOutlet UILabel *reverseDetailAddressLabel;//查询的地区详细名称
    @end
    
    @implementation ViewController
    
    - (void)viewDidLoad {
        [super viewDidLoad];
        //初始化地理编码器
        if (!_geocoder) {
            _geocoder = [[CLGeocoder alloc] init];
        }
    }
    
    // 地理编码
    - (IBAction)geocoder:(id)sender {
    
        //获取输入的城市名称
        NSString *address = self.addressField.text;
        if (address.length == 0) return;
    
        [self getCoordinateByAddress:address withBlock:^(CLPlacemark *pm) {
    
            // 设置经纬度
            self.latitudeLabel.text = [NSString stringWithFormat:@"%.2f", pm.location.coordinate.latitude];
            self.longitudeLabel.text = [NSString stringWithFormat:@"%.2f", pm.location.coordinate.longitude];
    
            // 设置具体地址
            self.detailAddressLabel.text = pm.name;
    
        } withfaild:^(NSError *error) {
    
            self.detailAddressLabel.text = @"你找的地址可能不存在,请重新输入";
            self.addressField.text = @"";
        }];
    }
    
    - (void)getCoordinateByAddress:(NSString *)address withBlock:(void(^)(CLPlacemark *pm))block withfaild:(void(^)( NSError *error))faild{
    
        [_geocoder geocodeAddressString:address completionHandler:^(NSArray *placemarks, NSError *error) {
    
            if (error) { // 有错误(地址乱输入)
    
                faild(error);
            } else { // 编码成功
    
                // 取出最前面的地址(数组中可能存在过河产讯到的地址)
                CLPlacemark *pm = [placemarks firstObject];
                // 回调数据
                block (pm);
    
                NSLog(@"总共找到%ld个地址", placemarks.count);
                //遍历数组,获取所有查找到的城市
                for (CLPlacemark *pm in placemarks) {
    
                    NSLog(@"-----地址开始----");
                    // 枚举编译出得所有的地理信息
                    [pm.addressDictionary enumerateKeysAndObjectsUsingBlock:^(id key, id obj, BOOL *stop) {
                        NSLog(@"%@:%@", key, obj);
                    }];
                    NSLog(@"-----地址结束----");
                }
            }
        }];
    }
    
    - (IBAction)reverseGeocoder:(id)sender {
    
        // 1.包装位置,将输入的字符串设置为地理坐标
        CLLocationDegrees latitude = [self.reverseLatitudeField.text doubleValue];
        CLLocationDegrees longitude = [self.reverseLongtitudeField.text doubleValue];
        CLLocation *loc = [[CLLocation alloc] initWithLatitude:latitude longitude:longitude];
    
        [self getAddressByLocation:loc withBlock:^(CLPlacemark *pm) {
    
            // 设置具体地址
            self.reverseDetailAddressLabel.text = [NSString stringWithFormat:@"%@ %@ %@ %@ %@",pm.country,pm.locality,pm.subLocality,pm.thoroughfare,pm.subThoroughfare];
        } withFaild:^(NSError *error) {
    
            self.reverseDetailAddressLabel.text = @"你找的地址可能只在火星有!!!";
        }];
    }
    
    - (void)getAddressByLocation:(CLLocation *)loc withBlock:(void(^)(CLPlacemark *pm))block withFaild:(void(^)(NSError *error))faild {
    
        // 2.反地理编码
        [_geocoder reverseGeocodeLocation:loc completionHandler:^(NSArray *placemarks, NSError *error) {
            if (error) { // 有错误(地址乱输入)
    
                faild (error);
            } else { // 编码成功
    
                // 取出最前面的地址
                CLPlacemark *pm = [placemarks firstObject];
    
                block (pm);
    
    
                NSLog(@"总共找到%ld个地址", placemarks.count);
                for (CLPlacemark *pm in placemarks) {
    
                    NSLog(@"-----地址开始----");
                    // 获取所有的地标信息
                    [pm.addressDictionary enumerateKeysAndObjectsUsingBlock:^(id key, id obj, BOOL *stop) {
                        NSLog(@"%@:%@", key, obj);
                    }];
    
                    NSLog(@"-----地址结束----");
                }
            }
        }];
    }
    @end
    展开全文
  • 安卓定位服务API指南

    千次阅读 2017-01-03 16:57:20
    安卓位置策略指南翻译:...官方API英文原文:https://developer.android.com/guide/topics/location/strategies.html注意:本指南中描述的策略仅仅适用于android.location中的定位API。 Google位置服务API是Google Pla

    安卓位置策略指南

    翻译:Lauhoman http://blog.csdn.net/sinat_26599509/
    官方API英文原文:https://developer.android.com/guide/topics/location/strategies.html

    注意:本指南中描述的策略仅仅适用于android.location中的定位API。 Google位置服务API是Google Play服务的一部分,提供了更强大的高级框架,可自动处理位置提供商、用户移动和位置精确度。 它还根据您提供的功耗参数处理位置更新计划。 在大多数情况下,您可以通过使用位置服务API获得更好的电池性能以及更合适的精度。要详细了解位置服务API,请参阅Android版Google定位服务

    目录

    文档

    1. 用户定位服务的挑战
    2. 如何向系统请求定位
    3. 根据情况选择一个最优的定位策略
    4. 处理给定的虚拟定位数据(暂不翻译)

    关键类

    1. LocationManager
    2. LocationListener

    1.用户定位服务的挑战

    从移动设备获得用户位置是极其复杂的,以下几个原因会导致位置读取的错误或不准确:

    1. 多种位置来源:GPS、小区ID和Wi-Fi可以各自提供用户位置的线索,而确定使用哪个服务取决于精度、速度和电池效率的权衡。

    2. 用户移动:因为用户位置有可能改变,所以必须经常重新确定用户位置来检测移动。

    3. 变化精度:来自每个定位方式的位置估计值的准确性并不一致,从一个来源获得的10秒前的位置可能反而比来自另一个或相同来源的最新位置更精确。

    这些挑战都导致了定位服务的困难,本文档提供的信息可帮助您应对这些挑战,以获得可靠的位置读数。它还提供如何在您自己的应用中为用户提供准确、可靠地理位置的经验。

    2.如何向系统请求定位

    在解决上述定位误差之前,我们先来介绍一下如何在安卓设备中获得用户的位置信息。

    安卓中位置信息的获取依赖于回调策略,当你需要获得位置信息的时候,你需要通过requestLocationUpdates()函数向LocationManager(即”Location Manager位置管家”)发出请求,告知它你需要位置信息的更新,并传递一个监听器LocationListener给它。你的LocationListener必须要完成对一系列回调函数的实现,当位置改变或者定位服务的状态改变,这些函数将会被LocationManager调用。

    举个例子来说,下面的代码展示了如何定义一个LocationListener并请求定位更新:

    // 获取对系统位置管理器的引用
    LocationManager locationManager = (LocationManager) this.getSystemService(Context.LOCATION_SERVICE);
    
    // 定义一个回应位置更新的监听器
    LocationListener locationListener = new LocationListener() {
        public void onLocationChanged(Location location) {
          // 当一个新的位置由网络位置提供时调用
          makeUseOfNewLocation(location);
        }
    
        public void onStatusChanged(String provider, int status, Bundle extras) {}
    
        public void onProviderEnabled(String provider) {}
    
        public void onProviderDisabled(String provider) {}
      };
    
    // 把这个监听器注册到Location Manager上来接受位置更新
    locationManager.requestLocationUpdates(LocationManager.NETWORK_PROVIDER, 0, 0, locationListener);
    

    其中requestLocationUpdates()的第一个参数是位置提供来源的类型(在这个例子中定位来源是网络定位—来自于信号塔和WiFi)。你可以通过第二个和第三个参数自定义你的监听器的位置更新接收频率,其中第二个参数是两次定位最短的时间间隔、第三个参数是两次定位最小位置变化,这个例子中设置为0即尽可能的频繁更新位置。而最后一个参数则是你想要注册到LocationManager上的LocationListener

    如果想要通过GPS传感器来获取位置,使用GPS_PROVIDER来代替NETWORK_PROVIDER。你也可以通过调用requestLocationUpdates()函数两次来同时使用GPS和网络请求位置更新—一个使用GPS_PROVIDER,另一个使用NETWORK_PROVIDER

    向用户取得定位权限

    为了从GPS_PROVIDERNETWORK_PROVIDER来定位,你必须在安卓应用manifest文件中分别声明ACCESS_COARSE_LOCATIONACCESS_FINE_LOCATION这两个向用户请求定位的权限。如果没有这些权限,你的应用将会在位置请求上失败。

    如果你正同时使用GPS_PROVIDERNETWORK_PROVIDER,那么你只需要请求一次ACCESS_FINE_LOCATION权限即可,因为这个权限的范围包括了以上两种来源。而ACCESS_COARSE_LOCATION权限则只允许使用NETWORK_PROVIDER

    警告:如果您的应用是针对ndroid 5.0(API级别21)或更高版本,则必须在应用的manifest文件中声明使用android.hardware.location.network或android.hardware.location.gps硬件功能,具体取决于您的应用是否接收来自NETWORK_PROVIDER或GPS_PROVIDER的位置更新。 如果您的应用从这些位置来源中获取位置信息,则需要在您的manifest文件中声明您的应用使用了这些硬件功能。 对于运行Android 5.0(API 21)之前版本的设备,请求ACCESS_FINE_LOCATION或ACCESS_COARSE_LOCATION权限包含了位置硬件功能的隐含请求。 但是,请求这些权限不会自动请求Android 5.0(API级别21)及更高版本上的位置硬件功能。

    下面的代码样例演示了一个从GPS传感器获取数据的应用如何在manifest文件中声明权限和硬件信息:

    <manifest ... >
        <uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
        ...
        <!-- Needed only if your app targets Android 5.0 (API level 21) or higher. -->
        <uses-feature android:name="android.hardware.location.gps" />
        ...
    </manifest>
    

    3. 根据情况选择一个最优的定位策略

    基于定位服务的应用现在遍地都是了,但是由于总是低于理想的精度、用户的移动、获取位置方式的多样性和节电需求,获取用户位置是极为复杂的。为了跨越节电的情况下提供较准确的定位这个挑战,你必须选择一系列合适的模型来决定你的应用怎么获取位置。这个决策模型包括了你什么时候开始、停止监听位置更新和什么时候使用缓存的位置数据。

    获取用户位置的流程图

    下面是一个典型的获取用户位置程序的流程图:

    1. 打开应用;
    2. 一段时间后,从选择的位置监听器开始监听位置变化;
    3. 通过过滤掉新的但是并不准确的位置来保持“最佳的定位”;
    4. 停止监听位置更新;
    5. 尽其用最好的定位数据。

    Figure 1. A timeline representing the window in which an application listens for location updates.

    这样的窗口模型,需要你在构建需要位置服务的应用程序做出许多重要决定。

    决定什么时候开始监听位置更新

    你一定想要让监听器从你的应用启动开始或者仅仅在用户打开某项功能时就开始监听,但注意较长的定位监听窗口会消耗大量的电量,而短周期的定位服务可能没有那么精确。

    正如上述,你可以通过调用requestLocationUpdates()函数来开始监听位置更新:

    String locationProvider = LocationManager.NETWORK_PROVIDER;
    // 或者使用GPS传感器提供的位置信息:
    // String locationProvider = LocationManager.GPS_PROVIDER;
    
    locationManager.requestLocationUpdates(locationProvider, 0, 0, locationListener);
    

    从最后一个已知的定位快速获取位置信息

    位置监听器接收到第一个准确定位往往需要的时间对于使用者来说太长,所以在得到一个很准确的位置之前最好先通过getLastKnownLocation(String)提供给用户一个缓存好的位置信息:

    String locationProvider = LocationManager.NETWORK_PROVIDER;
    // 或者使用LocationManager.GPS_PROVIDER
    
    Location lastKnownLocation = locationManager.getLastKnownLocation(locationProvider);
    

    决定什么时候停止监听位置更新

    决定什么时候不再需要新的定位的逻辑依赖于你的应用,这可能相当简单也可能十分复杂。在获取位置和使用位置之间的短暂空隙能够提高定位的准确性,并且一定要时刻记住长时间的监听位置更新必然会消耗大量电量,所以一旦你获得了你需要的位置信息,你就应该通过removeUpdates(PendingIntent)来停止监听位置更新:

    // 注销掉注册在LocationManager上的LocationListener
    locationManager.removeUpdates(locationListener);
    

    保持当前最佳的定位数据

    你一定希望最近一次的定位时最准确的,但是由于定位的多样性,大多数最近的定位都不是最佳的。你应该制定一些标准来选择定位数据,这种标准往往也会由于应用和测试的实际情况而呈现出多样性。

    下面是一些用来确定定位精度的步骤:
    1. 检查新得到的位置是否完全比原来的位置数据更新;
    2. 检查新得到的位置在精度上是比原来的位置数据更准确还是更差;
    3. 检查新的位置信息来源于何种位置来源,决定你更愿意相信哪个。

    一个精心准备的例子如下:
    private static final int TWO_MINUTES = 1000 * 60 * 2;

    /** Determines whether one Location reading is better than the current Location fix
      * @param location  The new Location that you want to evaluate
      * @param currentBestLocation  The current Location fix, to which you want to compare the new one
      */
    protected boolean isBetterLocation(Location location, Location currentBestLocation) {
        if (currentBestLocation == null) {
            // A new location is always better than no location
            return true;
        }
    
        // Check whether the new location fix is newer or older
        long timeDelta = location.getTime() - currentBestLocation.getTime();
        boolean isSignificantlyNewer = timeDelta > TWO_MINUTES;
        boolean isSignificantlyOlder = timeDelta < -TWO_MINUTES;
        boolean isNewer = timeDelta > 0;
    
        // If it's been more than two minutes since the current location, use the new location
        // because the user has likely moved
        if (isSignificantlyNewer) {
            return true;
        // If the new location is more than two minutes older, it must be worse
        } else if (isSignificantlyOlder) {
            return false;
        }
    
        // Check whether the new location fix is more or less accurate
        int accuracyDelta = (int) (location.getAccuracy() - currentBestLocation.getAccuracy());
        boolean isLessAccurate = accuracyDelta > 0;
        boolean isMoreAccurate = accuracyDelta < 0;
        boolean isSignificantlyLessAccurate = accuracyDelta > 200;
    
        // Check if the old and new location are from the same provider
        boolean isFromSameProvider = isSameProvider(location.getProvider(),
                currentBestLocation.getProvider());
    
        // Determine location quality using a combination of timeliness and accuracy
        if (isMoreAccurate) {
            return true;
        } else if (isNewer && !isLessAccurate) {
            return true;
        } else if (isNewer && !isSignificantlyLessAccurate && isFromSameProvider) {
            return true;
        }
        return false;
    }
    
    /** Checks whether two providers are the same */
    private boolean isSameProvider(String provider1, String provider2) {
        if (provider1 == null) {
          return provider2 == null;
        }
        return provider1.equals(provider2);
    }
    

    调整软件模型来节省电量和减少数据交换

    当你测试你的应用时,你会发现为了提供较好的位置和较好的性能表现需要经过一系列的调整,下面是一些改变两者之间的平衡的东西:

    减小监听窗口

    一个较小的监听窗口意味着较少与网络或GPS服务的交互,同时,能节省电量。但是它必须保证仍然允许从较少的定位信息中获得最佳的数据。

    让位置更新的返回不那么频繁

    减少新位置更新的出现频率同样能改善电池的表现,但是代价是准确度。更新频率取决于你的应用程序是怎样使用定位信息的。你可以通过更改requestLocationUpdates()中的参数来减少更新率—即增大间隔时间或者间隔距离。

    限制一种位置来源

    根据你的应用的使用环境,你要选择仅仅使用网络定位或者仅仅使用GPS定位来取代两者都用。只使用一种服务能有效的在较为潜在的精准度风险中减少电池消耗。

    常见的应用情况

    有很多原因可能需要在应用程序中获取用户位置。 以下是一些情况,您可以使用用户位置丰富您的应用程序。 每个场景还描述了当您应该开始和停止监听位置时的良好做法,以便获得良好的定位数据并帮助保持电池寿命。

    为用户创建的内容打上位置标记

    您可能正在创建一个应用程序,其中用户创建的内容标记有位置信息。 用户能分享他们的本地体验、发布对餐厅的评论或记录一些可以用他们当前位置增强的内容。 关于位置服务的这种交互应该如何处理的模型可以参考下图:

    Figure 2. A timeline representing the window in which the user location is obtained and listening stops when the user consumes the current location.

    这与之前在代码中如何获得用户位置的模型相呼应。 为了获得最佳的位置精确度,您可以选择在用户开始创建内容时或甚至在应用程序启动时开始监听位置更新,然后在内容准备发布或记录时停止监听更新。 您可能需要考虑创建内容的典型任务需要花费多长时间,并判断此持续时间是否允许收集新的位置数据。

    帮助用户决定去哪里的应用

    您可能正在创建一个应用程序,试图向用户提供一组有关去哪里的选项。 例如,您希望提供附近的餐馆,商店和娱乐的列表,并且根据用户位置更改建议顺序。

    为了达成如下的流程,你可能要选择:

    1. 当一个新的位置到来的时候,重新安排推荐服务的顺序;
    2. 每当推荐序列被确定的时候停止监听位置更新。

    这样的模型在下图中可以体现:

    Figure 3. A timeline representing the window in which a dynamic set of data is updated each time the user location updates.

    展开全文
  • 国行安卓手机Google定位服务解决方案前言转载请注明出处:http://blog.csdn.net/u010067411/article/details/79090500Demo和源码请移步点击打开链接简介相信很多Android开发人员都有这样的痛点,当国内Android用户在...

    国行安卓手机Google定位服务解决方案

    前言

    转载请注明出处:http://blog.csdn.net/u010067411/article/details/79090500

    Demo和源码请移步点击打开链接

    简介
    • 相信很多Android开发人员都有这样的痛点,当国内Android用户在国外要使用地图时,好像十分尴尬,没有非常成熟的地图解决方案。
    • 由于众所周知的原因,谷歌的很多优秀服务在国内无法使用,其中国行手机由于阉割无法使用谷歌地图服务是一个非常让人头痛的问题。主要问题有:
      • 一方面,国内地图服务提供商(百度地图、高德地图、腾讯地图)在境外的地图资源少得可怜。
      • 另一方面,国行安卓手机由于系统缺少谷歌三大件,使得国行手机使用谷歌地图服务几乎变得不可能。
    • 本项目是为了解决地图定位建立,围绕Google给出的API接口资源,通过一系列技术方案,使得国行手机在没有谷歌三大件的情况下也可以使用谷歌的地图服务。主要特征有:
      • 包含WIFI信号、基站和GPS的多重定位方案,具有定位误差小、适用性广、低消耗、速度快等特点。
      • 基于谷歌数据的定位,在国外实地测试定位准确率要明显高于国内定位服务。
      • 封装后的库体积小、逻辑清晰、使用简单,项目内还有多种相关实用工具可供使用。
    • 国行安卓手机Google地图服务解决方案,请移步点击打开链接

    使用前准备

    需要的权限

    <uses-permission android:name="android.permission.CHANGE_WIFI_STATE" />
    <uses-permission android:name="android.permission.INTERNET" />
    <uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />
    <uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />

    获取Google Location API KEY

    <meta-data
        android:name="GOOGLE_LOCATION_API_KEY"
        android:value="YOUR_API_KEY" />

    使用过程

    切换定位域名(非必须)

    GetLocation.getInstance().setNetworkLocationUrl("https://googleapis.xxxxxx.com/");
    • 虽然该方案最主要的目标用户是在境外的国行手机,那么访问谷歌接口理应没有太大问题,但是不排除调试或者部分人需要在国内使用,特意封装了修改定位域名的方法。

    使用多重定位(需访问谷歌服务器,境内网络需翻墙)

    GetLocation.getInstance().setMultiLocationListener(new GetLocation.OnMultiLocationListener() {
        @Override
        public void onMultiLocation(double multilatitude, double multilongitude, long multiupdateTime, float multiaccuracy, float multibearing) {
            Double latitude, longitude;
            MyLocation myLocation = new MyLocation(multilatitude, multilongitude);
            //由于坐标系差异,中国大陆坐标需要转换
            if(BoundaryCheck.getInstance().IsInsideChina(myLocation)) {
                Point point = CoordinateConversion.wgs_gcj_encrypts(multilatitude, multilongitude);
                latitude = point.getLat();
                longitude = point.getLng();
            }else {
                latitude = multilatitude;
                longitude = multilongitude;
            }
            //经度:longitude,纬度:latitude,精度:multiaccuracy,方位:multiaccuracy,更新时间:multiupdateTime
        }
    
        @Override
        public void onFailed(int errorCode, String msg) {
    
        }
    });
    GetLocation.getInstance().startMultiLocation(getApplication(), this, false);

    使用网络定位(需访问谷歌服务器,境内网络需翻墙)

    GetLocation.getInstance().setNetworkLocationListener(new GetLocation.OnNetworkLocationListener() {
        @Override
        public void onNetworkLocation(double latitude, double longitude, long updateTime, float accuracy) {
            Double lat, lon;
            MyLocation myLocation = new MyLocation(latitude, longitude);
            //由于坐标系差异,中国大陆坐标需要转换
            if(BoundaryCheck.getInstance().IsInsideChina(myLocation)) {
                Point point = CoordinateConversion.wgs_gcj_encrypts(latitude, longitude);
                lat = point.getLat();
                lon = point.getLng();
            }else {
                lat = latitude;
                lon = longitude;
            }
            //经度:longitude,纬度:latitude,精度:accuracy,更新时间:updateTime
        }
    
        @Override
        public void onFailed(int errorCode, String msg) {
            
        }
    });
    GetLocation.getInstance().startNetworkLocation(getApplication());

    使用GPS定位(需要在室外能搜索到GPS信号的地方使用)

    GetLocation.getInstance().setGPSLocationListener(new GetLocation.OnGPSLocationListener() {
        @Override
        public void onGPSLocation(double latitude, double longitude, long updateTime, float accuracy, float bearing) {
            Double lat, lon;
            MyLocation myLocation = new MyLocation(latitude, longitude);
            //由于坐标系差异,中国大陆坐标需要转换
            if(BoundaryCheck.getInstance().IsInsideChina(myLocation)) {
                Point point = CoordinateConversion.wgs_gcj_encrypts(latitude, longitude);
                lat = point.getLat();
                lon = point.getLng();
            }else {
                lat = latitude;
                lon = longitude;
            }
            //经度:longitude,纬度:latitude,精度:accuracy,方位:accuracy,更新时间:updateTime
        }
    
        @Override
        public void onFailed(int errorCode, String msg) {
            
        }
    });
    GetLocation.getInstance().startGPSLocation(getApplication(),this);

    释放资源

    无论哪种的定位方式,在activity生命周期stop中一定要释放资源并且停止定位,以防资源浪费和异常奔溃

    @Override
    protected void onStop() {
        super.onStop();
        GetLocation.getInstance().onStop();
    }

    关于

    展开全文
  • 哎,最近的一次上线,业务功能点很少,本以为稳稳的,肯定没事,谁知晚上十点半刚上完线,服务突然自动重启了,运维人员认为风险极高,回滚了。运维这么一快速回滚,没有dump出堆栈信息,研发这边定位问题,也只能靠...
  • AndroidQ新增定位权限: ...定位服务的判断和开启: /** * ============================================== * author : carl * e-mail : 991579741@qq.com * time : 2020/05/29 * desc : 权
  • 使用google service定位服务

    千次阅读 2016-08-21 22:21:40
    使用google service定位服务概述使用google service的API实现定位功能,封装成一个小模块。需要安装google service相关的sdk包,手机需要装有google服务框架等。主要是国外产品使用,国内需要翻墙,这里做下记录。 ...
  • Android使用Google定位服务定位并将经纬度转换为详细地址信息
  • Android基于高德地图实时定位服务

    千次阅读 2017-03-27 14:07:54
    Service功能有:实时...判断服务是否在开启的状态服务代码:LocationService(Android Studio 2.3环境下) 实时定位(30秒间隔) 判断是否在规定的时间段内 判断距离是否大于规定的距离 这三个功能我都写在了一
  • uni-app调手机系统的GPS定位服务

    千次阅读 2019-05-30 14:29:39
    做个记录,在做签到功能时需要用到,强制用户开启GPS定位。目前在vue页面的安卓上面是没有问题的,在wexx上面的页面还不行,也就是nuve。 handleNotice(e){ let system = uni.getSystemInfoSync();// 获取系统...
  • 今天集成了高德地图的定位SDK准备搞一下,在华为上定位回调中一直提示:错误码12,定位失败,位置服务未开启,开始还以为是动态权限的问题,看了一下发现权限是开启的,这就纳闷了,换了其他手机发现是正常的,这就...
  • 首先关于这个问题,我真的纠结了很久很久,因为我们的项目请求一些数据的时候需要给后台上传用户的经纬度,然而用户小白并不知道,所以本妹子就是说如果用户关掉了定位服务或者是没有允许我们的项目使用定位服务这个...
  • 最近的一个业务涉及地图相关的服务,由于时间比较紧,所以借鉴了网上一些大神的代码,总算是交了差。现在回想起来,当初的自己是多么的窘迫,上网查看,铺天盖地的博文,每篇都是华丽丽的几大页,功能也都能满足要求...
  • 1.导入类库: #import ...2.判断APP用户手机是否开启了定位服务: 这里就要查看CLLocationManager的授权状态,此方法会返回当前授权状态: [CLLocationManager authorizationStatus] 授权状态为枚举值: ...
  • Android定位服务融合了GPS定位、移动通信、导航等多种技术,提供与空间位置相关的综合应用服务。近些年来,基于位置的服务发展更为迅速,涉及商务、医疗、工作和生活的各个方面,为用户提供定位、追踪和敏感区域警告...
  • 高德地图定位服务

    千次阅读 2016-03-31 18:16:14
    项目需要获得位置信息,本来想用百度地图服务呢,无奈百度定位sdk下载不了,不知道什么情况。 下面介绍高德定位SDK的使用 ...添加定位服务 android:name="com.amap.api.location.APSService"> 添加met
  • 安卓手机判断定位服务是否开启

    千次阅读 2018-04-03 14:56:35
    2、定位服务未开启; 问题1的解决思路: 百度一下,网上资料很多; 问题2的解决思路:  获取位置信息之前,先判断定位服务是否开启,如果开启直 接定位;如果未开启,弹出一个对话框提示用户开启; (代码...
  • android定位服务的实现

    热门讨论 2013-08-22 15:44:13
    详细讲解请查看博文,连接地址:http://blog.csdn.net/android_ls/article/details/10179013
  • Q:我刚刚用iOS11 SDK重新构建了应用程序,发现定位服务现在根本不起作用。原因:A:因为苹果现在增加了一项新的隐私保护功能 NSLocationAlwaysAndWhenInUseUsageDeion,并且原有的 NSLocationAlwaysUsageDeion 被...
  • APP首次启动提示开启定位服务

    千次阅读 2017-11-10 10:33:17
    最近在项目中有用到位置,以前都是在进入需要位置信息的地方才去让用户打开定位,或者是在用户安装APP的时候就让用户给APP赋予读取位置的权限,但是现在想要用户在安装完App第一次启动的时候才去询问用户是否开启...
  • 高德地图 定位服务启动失败

    千次阅读 2016-04-21 14:02:25
    start : (20160421) 在Android 6.0中,使用定位权限需要...在我成功申请了权限之后,在onRequestPermissionsResult方法中,调用上述代码开启定位,却报了“定位服务启动失败”。目前也不明白为什么会报这个错,但是
  • 在使用高德地图的时候,根据官方API的代码写出demo后,定位服务无效,并且提示 定位失败,10: 定位服务启动失败。如下图:         解决办法: 在AndroidManifest中添加 &lt;service android:...
  • 服务定位架构模式

    千次阅读 2019-08-23 22:06:23
    1. 服务定位基本理念 系统集成(System Integration)是应用系统架构设计的一个重要课题,无论何种行业和应用,系统都可能需要集成对第三方服务的访问。这些第三方服务可能来自外部供应商,也可能来自于同一组织的...
  • [AMapLocationKit] 要在iOS 11及以上版本使用后台定位服务, 需要实现amapLocationManager:doRequireLocationAuth: 代理方法问题及解决方案 [locationManager requestAlwaysAuthorization];
  • 关于如何集成高德地图的定位,这里不再说了,高德地图官方文档上已经描述的很详细,这里主要说说,我们测试的时候定位正常,但有部分用户会反映定位不了,如何处理这类情况。 高德地图官方集成文档 关于运行时权限 ...
  • Android应用使用百度定位SDK 返回error code : 162 latitude : 4.9E-324 lontitude : 4.9E-324 有以下几种情况会导致这种情况的发生(首先要保证按照官方文档配置环境): ①官方文档不提供armeabi-v7a文件夹对应的.so...
  • 定位服务不可用问题

    千次阅读 2016-04-16 15:33:40
    定位服务不可用的一般步骤: #ping命令检查两台主机之间网络是否是通的 ping 120.25.233.113 #telnet命令检查目标主机端口是否是通的 telnet 120.25.233.113 80 #端口不通的原因一般有两种情况: 1,...
  • 项目中做一个地区定位功能,选用的... 关于百度ip定位服务的介绍以及用法可以在这个链接中找到,主要做的就是开通应用服务以及拿到AK。  我开通的是服务端的应用服务,所以我是通过java代码向百度定位服务发起调用。
  • 在真机测试的时候发现隐私设置里的定位服务列表里没有我的app, 也没有提示我是否允许使用定位, 这样就无法开启定位服务了 请问这是什么问题? 补充:在iphone4s上 隐私设置里是有的,但是到了iphone5 和iphone...
  • arcgis for android 在自己的地图服务定位

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 667,030
精华内容 266,812
关键字:

定位服务