美文网首页Android
安卓百度地图(一)定位功能的实现、周边POI的检索

安卓百度地图(一)定位功能的实现、周边POI的检索

作者: Active_Loser | 来源:发表于2018-01-11 13:07 被阅读5124次

    其他文章:
    安卓百度离线地图的下载以及使用
    安卓百度地图(二)地图显示以及离线地图的下载使用
    安卓百度地图(三)绘制点、线等图层信息
    安卓百度地图(四)城市,周边,区域检索
    安卓百度地图(五)百度地图路线规划
    安卓百度地图(六)鹰眼轨迹的上传,历史轨迹的显示
    安卓百度地图(七)地理围栏的建立与使用

    本文主要针对百度定位sdk的api进行整理

    一 定位简介

    百度地图Android定位SDK提供GPS、基站、WiFi、地磁、蓝牙、传感器等多种定位方式,适用于室内、室外多种定位场景,具有出色的定位性能:定位精度高、覆盖率广、网络定位请求流量小、定位速度快。 引用官方的图片

    在室内无gps时,百度定位就是利用的WiFi和基站定位的,在室外有gps时,百度是利用的android自带的LocationManager进行定位,当然室外也可以用WiFi基站定位。

    • GPS定位:精度很高,几米到十几米,但是耗电严重。
    • WiFi定位:精度相对于GPS差一点,但是也能到十几米、几十米,也有上百米的误差的,低耗电。
    • 基站定位:精度很差,一般都有几百米,上千米的误差。

    二 百度地图配置

    关于百度地图的配置,可以查看官网的详解教程:传送门

    • 登录API控制台,创建应用,获取应用的AK。
    • 下载所需要的开发资源传送门,解压文件,将lib下的文件copy至app下的lib中,在app的buid文件中输入
    android {
        sourceSets {
            main {
                jniLibs.srcDirs = ['libs']
            }
        }
    }
    
    • 添加AK
    <meta-data
        android:name="com.baidu.lbsapi.API_KEY"
        android:value="开发者申请的AK" >
    </meta-data>
    
    • 添加所需服务
    //Application标签中声明service组件,每个App拥有自己单独的定位service
    <service
         android:name="com.baidu.location.f" 
        android:enabled="true" 
        android:process=":remote"> 
    </service>
    
    • 添加功能权限:
    <!-- 这个权限用于进行网络定位-->
    <uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION"></uses-permission>
    <!-- 这个权限用于访问GPS定位-->
    <uses-permission android:name="android.permission.ACCESS_FINE_LOCATION"></uses-permission>
    <!-- 用于访问wifi网络信息,wifi信息会用于进行网络定位-->
    <uses-permission android:name="android.permission.ACCESS_WIFI_STATE"></uses-permission>
    <!-- 获取运营商信息,用于支持提供运营商信息相关的接口-->
    <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE"></uses-permission>
    <!-- 这个权限用于获取wifi的获取权限,wifi信息会用来进行网络定位-->
    <uses-permission android:name="android.permission.CHANGE_WIFI_STATE"></uses-permission>
    <!-- 用于读取手机当前的状态-->
    <uses-permission android:name="android.permission.READ_PHONE_STATE"></uses-permission>
    <!-- 写入扩展存储,向扩展卡写入数据,用于写入离线定位数据-->
    <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"></uses-permission>
    <!-- 访问网络,网络定位需要上网-->
    <uses-permission android:name="android.permission.INTERNET" />
    <!-- SD卡读取权限,用户写入离线定位数据-->
    <uses-permission android:name="android.permission.MOUNT_UNMOUNT_FILESYSTEMS"></uses-permission>
    

    注意:安卓6.0系统以上,一些权限需要动态申请

    三 百度地图定位

    1. 初始化LocationClient类

    public LocationClient mLocationClient = null;;
    public void onCreate()
    {
         mLocationClient = new LocationClient(getApplicationContext());//声明LocationClient类
         mLocationClient.registerLocationListener(myListener);//注册监听函数
    }
    

    2. 配置定位SDK参数

    LocationClientOption mOption = new LocationClientOption();
    
    /**
    * 默认高精度,设置定位模式
    * LocationMode.Hight_Accuracy 高精度定位模式:这种定位模式下,会同时使用
    * LocationMode.Battery_Saving 低功耗定位模式:这种定位模式下,不会使用GPS,只会使用网络定位。
    * LocationMode.Device_Sensors 仅用设备定位模式:这种定位模式下,
    */
    mOption.setLocationMode(LocationMode.Hight_Accuracy);
    
    /**
    * 默认是true,设置是否使用gps定位
    * 如果设置为false,即使mOption.setLocationMode(LocationMode.Hight_Accuracy)也不会gps定位
    */
    mOption.setOpenGps(true);
    
    /**
    * 默认gcj02,设置返回的定位结果坐标系,如果配合百度地图使用,建议设置为bd09ll;
    * 目前国内主要有以下三种坐标系:
    1. wgs84:目前广泛使用的GPS全球卫星定位系统使用的标准坐标系;
    2. gcj02:经过国测局加密的坐标;
    3. bd09:为百度坐标系,其中bd09ll表示百度经纬度坐标,bd09mc表示百度墨卡托米制坐标;
    * 在国内获得的坐标系类型可以是:国测局坐标、百度墨卡托坐标 和 百度经纬度坐标。
      在海外地区,只能获得WGS84坐标。请在使用过程中注意选择坐标。
    */
    mOption.setCoorType("bd09ll");
    
    /**
    * 默认0,即仅定位一次;设置间隔需大于等于1000ms,表示周期性定位
    * 如果不在AndroidManifest.xml声明百度指定的Service,周期性请求无法正常工作
    * 这里需要注意的是:如果是室外gps定位,不用访问服务器,设置的间隔是3秒,那么就是3秒返回一次位置
      如果是WiFi基站定位,需要访问服务器,这个时候每次网络请求时间差异很大,设置的间隔是3秒,
      只能大概保证3秒左右会返回就一次位置,有时某次定位可能会5秒才返回
    */
    mOption.setScanSpan(3000);
    
    /**
    * 默认false,设置是否需要地址信息
    * 返回省、市、区、街道等地址信息,这个api用处很大,
      很多新闻类app会根据定位返回的市区信息推送用户所在市的新闻
    */
    mOption.setIsNeedAddress(true);
    
    /**
    * 默认false,设置是否需要位置语义化结果
    * 可以在BDLocation.getLocationDescribe里得到,结果类似于“在北京天安门附近”
    */
    mOption.setIsNeedLocationDescribe(true);
    
    /**
    * 默认false,设置是否需要设备方向传感器的方向结果
    * 一般在室外gps定位时,返回的位置信息是带有方向的,但是有时候gps返回的位置也不带方向,
      这个时候可以获取设备方向传感器的方向
    * wifi基站定位的位置信息是不带方向的,如果需要可以获取设备方向传感器的方向
    */
    mOption.setNeedDeviceDirect(false);
    
    /**
    * 默认false,设置是否当gps有效时按照设定的周期频率输出GPS结果
    * 室外gps有效时,周期性1秒返回一次位置信息,其实就是设置了
    locationManager.requestLocationUpdates中的minTime参数为1000ms,1秒回调一个gps位置
    * 如果设置了mOption.setScanSpan(3000),那minTime就是3000ms了,3秒回调一个gps位置
    */
    mOption.setLocationNotify(false);
    
    /**
    * 默认true,定位SDK内部是一个SERVICE,并放到了独立进程,设置是否在stop的时候杀死这个进程,默认不杀死
    * 如果你已经拿到了你要的位置信息,不需要再定位了,不杀死留着干嘛
    */
    mOption.setIgnoreKillProcess(true);
    
    /**
    * 默认false,设置是否需要POI结果,可以在BDLocation.getPoiList里得到
    * POI就是获取到的位置附近的一些商场、饭店、银行等信息
    */
    mOption.setIsNeedLocationPoiList(true);
    
    /**
    * 默认false,设置是否收集CRASH信息,默认收集
    */
    mOption.SetIgnoreCacheException(false);
    
    /**
    * 默认false,设置定位时是否需要海拔高度信息,默认不需要,除基础定位版本都可用
    */
    mOption.setIsNeedAltitude(false);
    
    mLocationClient.setLocOption(mOption);//设置定位参数
    
    

    3. 发起定位

    发起定位,便能够从BDAbstractLocationListener监听接口中获取定位结果信息。

    //mLocationClient为第二步初始化过的LocationClient对象
    //调用LocationClient的start()方法,便可发起定位请求
    mLocationClient.start();
    //tart():启动定位SDK;stop():关闭定位SDK。调用start()之后只需要等待定位结果自动回调即可。
    //开发者定位场景如果是单次定位的场景,在收到定位结果之后直接调用stop()函数即可。
    //如果stop()之后仍然想进行定位,可以再次start()等待定位结果回调即可。
    //自v7.2版本起,新增LocationClient.reStart()方法,用于在某些特定的异常环境下重启定位。
    

    4.实现BDAbstractLocationListener接口

    发起定位后,即可获取所需要的信息

    private class MyBDAbstractLocationListener extends BDAbstractLocationListener {
            @Override
            public void onReceiveLocation(BDLocation bdLocation) {
                //此处的BDLocation为定位结果信息类,通过它的各种get方法可获取定位相关的全部结果    
               if (null != location && location.getLocType() != BDLocation.TypeServerError) {
                 
               }   
            }
    }
    

    4.1 获取基本定位信息

    bdLocation.getLatitude();//纬度
    bdLocation.getLongitude();//经度
    bdLocation.getDirection();//定位方向
    bdLocation.getRadius();//定位精度
    bdLocation.getCoorType();//定位坐标类型
    bdLocation.getLocType();//定位类型、定位错误返回码
    bdLocation.getLocTypeDescription();//对应的定位类型说明
    bdLocation.getTime();//获取经纬度服务器时间
    //判断用户是在室内,还是在室外1:室内,0:室外,这个判断不一定是100%准确的
    bdLocation.getUserIndoorState();
    

    4.2 获取地址信息

    注意:配置定位SDK参数中,添加获取地址信息option.setIsNeedAddress(true);

    bdLocation.getAddrStr();    //获取详细地址信息
    bdLocation.getCountry();    //获取国家
    bdLocation.getProvince();    //获取省份
    bdLocation.getCity();    //获取城市
    bdLocation.getDistrict();    //获取区县
    bdLocation.getStreet();    //获取街道信息
    

    4.3 获取位置信息描述

    注意:首先在配置定位SDK参数中,添加获取位置信息描述option.setIsNeedLocationDescribe(true);

    location.getLocationDescribe();    //获取位置描述信息
    

    4.4 周边POI信息

    获取位置附近的一些商场、饭店、银行等信息
    注意:首先在配置定位SDK参数中,添加获取周边信息option.setIsNeedLocationPoiList(true);
    在实现的BDAbstractLocationListener接口中,通过getPoiList()方法,即可获取周边信息

    List<Poi> poiList = bdLocation.getPoiList(); //POI信息包括POI ID、名称等,具体信息请参照类参考中POI类的相关说明
    

    4.5 判断定位类型

    if (bdLocation.getLocType() == BDLocation.TypeGpsLocation) {// GPS定位结果
            bdLocation.getSpeed();// 速度 单位:km/h
            bdLocation.getSatelliteNumber();// 卫星数目
            bdLocation.getAltitude();// 海拔高度 单位:米
            bdLocation.getGpsAccuracyStatus();// *****gps质量判断*****
            Toast.makeText(MainActivity.this, "gps定位成功", Toast.LENGTH_SHORT).show();
    
    } else if (bdLocation.getLocType() == BDLocation.TypeNetWorkLocation) {// 网络定位结果
           // 运营商信息
            if (bdLocation.hasAltitude()) {// *****如果有海拔高度*****
                bdLocation.getAltitude();// 单位:米
            }
            (bdLocation.getOperators();   // 运营商信息
            Toast.makeText(MainActivity.this, "网络定位成功", Toast.LENGTH_SHORT).show();
    
    } else if (bdLocation.getLocType() == BDLocation.TypeOffLineLocation) {// 离线定位结果
            Toast.makeText(MainActivity.this, "离线定位成功,离线定位结果也是有效的", Toast.LENGTH_SHORT).show();
    
    } else if (bdLocation.getLocType() == BDLocation.TypeServerError) {
            Toast.makeText(MainActivity.this, "服务端网络定位失败,可以反馈IMEI号和大体定位时间到loc-bugs@baidu.com,会有人追查原因", Toast.LENGTH_SHORT).show();
    
    } else if (bdLocation.getLocType() == BDLocation.TypeNetWorkException) {
            Toast.makeText(MainActivity.this, "网络不通导致定位失败,请检查网络是否通畅", Toast.LENGTH_SHORT).show();
    
    } else if (bdLocation.getLocType() == BDLocation.TypeCriteriaException) {
                  
            Toast.makeText(MainActivity.this, "法获取有效定位依据导致定位失败,一般是由于手机的原因,处于飞行模式下一般会造成这种结
    果,可以试着重启手机", Toast.LENGTH_SHORT).show();
    }
    

    4.6 国内外位置判断

    //此处的BDLocation为定位结果信息类,通过它的各种get方法可获取定位相关的全部结果
    //以下只列举与国内外判断相关的内容
    //更多结果信息获取说明,请参照类参考中BDLocation类中的说明
    //BDLocation.getLocationWhere()方法可获得当前定位点是否是国内,它的取值及含义如下:
    //BDLocation.LOCATION_WHERE_IN_CN:当前定位点在国内;
    //BDLocation.LOCATION_WHERE_OUT_CN:当前定位点在海外;
    //其他:无法判定。
    

    4.7 位置提醒

    定位SDK支持位置提醒功能,位置提醒最多提醒3次,3次过后将不再提醒。假如需要再次提醒、或者要修改提醒点坐标,都可通过函数SetNotifyLocation()来实现。

    4.7.1 注册监听函数

     //注册监听函数
     mLocationClient.registerNotify(myListener);    
    

    4.7.2 实现位置监听的回调

    定义MyNotifyLister类,继承BDNotifyListener,实现位置监听的回调。
    public class MyNotifyLister extends BDNotifyListener {
        public void onNotify(BDLocation mlocation, float distance){
            //已到达设置监听位置附近
        }           
    }
    

    4.7.3 实现设置位置消息提醒

    调用BDNotifyListener的setNotifyLocation方法,实现设置位置消息提醒。
    myListener.setNotifyLocation(40.0f, 116.0f, 3000, mLocationClient.getLocOption().getCoorType());
    //设置位置提醒,四个参数分别是:纬度,经度,距离范围,坐标系类型(gcj02,gps,bd09,bd09ll)
    

    4.7.4 启动定位

    启动定位,SDK便会自动开启位置消息提醒的监听。
    调用LocationClient的start()方法,启动定位。核心代码如下:
    mLocationClient.start();
    //mLocationClient为第二步初始化过的LocationClient对象
    //调用LocationClient的start()方法,开启定位
    

    4.7.5 取消监听

    调用BDNotifyListener的removeNotifyEvent方法,实现取消位置监听。核心代码如下:
    myListener.removeNotifyEvent(myListener);
    //myListener为第二步中定义过的BDNotifyListener对象
    //调用执行removeNotifyEvent方法,即可实现取消监听
    

    5. 释放资源

    mLocationClient.unregisterListener(myLocationListener); //注销掉监听
    mLocationClient.stop(); //停止定位
    

    本文主要做于收集整理笔记使用,关于文章的源码,请移步我的GitHub

    相关文章

      网友评论

        本文标题:安卓百度地图(一)定位功能的实现、周边POI的检索

        本文链接:https://www.haomeiwen.com/subject/xuhznxtx.html