您当前的位置: Android定位SDK > 开发指南 > 获取位置
获取位置

获取当前位置信息

综合定位功能指的是根据用户实际需求,返回用户当前位置的基础定位服务,包含GPS和网络定位(WiFi定位和基站定位)功能。基本定位功能同时还支持位置描述信息功能,离线定位功能,位置提醒功能和位置语义化功能。

第一步,初始化LocationClient类

此处需要注意:LocationClient类必须在主线程中声明,需要Context类型的参数。

Context需要时全进程有效的Context,推荐用getApplicationConext获取全进程有效的Context。

public LocationClient mLocationClient = null;
 
public BDAbstractLocationListener myListener = new MyLocationListener();
//BDAbstractLocationListener为7.2版本新增的Abstract类型的监听接口,原有BDLocationListener接口暂时同步保留。具体介绍请参考后文中的说明
 
public void onCreate() {
    mLocationClient = new LocationClient(getApplicationContext());     
    //声明LocationClient类
    mLocationClient.registerLocationListener( myListener );    
    //注册监听函数
}

LocationClient类是定位SDK的核心类,具体方法请参见类参考部分的介绍。

第二步,配置定位SDK参数

设置定位参数包括:定位模式(高精度定位模式、低功耗定位模式和仅用设备定位模式),返回坐标类型,是否打开GPS,是否返回地址信息、位置语义化信息、POI信息等等。

返回坐标类型包括:

1. gcj02:国测局坐标;

2. bd09:百度墨卡托坐标;

3. bd09ll:百度经纬度坐标;

注意:海外地区定位结果默认、且只能是WGS84类型坐标。

LocationClientOption类,该类用来设置定位SDK的定位方式,例如:

private void initLocation(){
 
    LocationClientOption option = new LocationClientOption();
    option.setLocationMode(LocationMode.Hight_Accuracy);
    //可选,默认高精度,设置定位模式,高精度,低功耗,仅设备
 
    option.setCoorType("bd09ll");
    //可选,默认gcj02,设置返回的定位结果坐标系
 
    int span=1000;
    option.setScanSpan(span);
    //可选,默认0,即仅定位一次,设置发起定位请求的间隔需要大于等于1000ms才是有效的
 
    option.setIsNeedAddress(true);
    //可选,设置是否需要地址信息,默认不需要
 
    option.setOpenGps(true);
    //可选,默认false,设置是否使用gps
 
    option.setLocationNotify(true);
    //可选,默认false,设置是否当GPS有效时按照1S/1次频率输出GPS结果
 
    option.setIsNeedLocationDescribe(true);
    //可选,默认false,设置是否需要位置语义化结果,可以在BDLocation.getLocationDescribe里得到,结果类似于“在北京天安门附近”
 
    option.setIsNeedLocationPoiList(true);
    //可选,默认false,设置是否需要POI结果,可以在BDLocation.getPoiList里得到
 
    option.setIgnoreKillProcess(false);
    //可选,默认true,定位SDK内部是一个SERVICE,并放到了独立进程,设置是否在stop的时候杀死这个进程,默认不杀死  
 
    option.setIgnoreCacheException(false);
    //可选,默认false,设置是否收集CRASH信息,默认收集
 
    option.setEnableSimulateGps(false);
    //可选,默认false,设置是否需要过滤GPS仿真结果,默认需要
 
    option.setWifiValidTime(5*60*1000);
    //可选,7.2版本新增能力,如果您设置了这个接口,首次启动定位时,会先判断当前WiFi是否超出有效期,超出有效期的话,会先重新扫描WiFi,然后再定位
 
    mLocationClient.setLocOption(option);
}

高精度定位模式:这种定位模式下,会同时使用网络定位和GPS定位,优先返回最高精度的定位结果;

低功耗定位模式:这种定位模式下,不会使用GPS进行定位,只会使用网络定位(WiFi定位和基站定位);

仅用设备定位模式:这种定位模式下,不需要连接网络,只使用GPS进行定位,这种模式下不支持室内环境的定位。

第三步,实现BDAbstractLocationListener接口

Android定位SDK自v7.2版本起,对外提供了Abstract类型的监听接口BDAbstractLocationListener,用于实现定位监听。原有BDLocationListener暂时保留,推荐开发者升级到Abstract类型的新监听接口使用,该接口会异步获取定位结果,实现方式如下:

public class MyLocationListener extends BDAbstractLocationListener {
 
    @Override
    public void onReceiveLocation(BDLocation location) {
 
        //获取定位结果
        location.getTime();    //获取定位时间
        location.getLocationID();    //获取定位唯一ID,v7.2版本新增,用于排查定位问题
        location.getLocType();    //获取定位类型
        location.getLatitude();    //获取纬度信息
        location.getLongitude();    //获取经度信息
        location.getRadius();    //获取定位精准度
        location.getAddrStr();    //获取地址信息
        location.getCountry();    //获取国家信息
        location.getCountryCode();    //获取国家码
        location.getCity();    //获取城市信息
        location.getCityCode();    //获取城市码
        location.getDistrict();    //获取区县信息
        location.getStreet();    //获取街道信息
        location.getStreetNumber();    //获取街道码
        location.getLocationDescribe();    //获取当前位置描述信息
        location.getPoiList();    //获取当前位置周边POI信息
 
        location.getBuildingID();    //室内精准定位下,获取楼宇ID
        location.getBuildingName();    //室内精准定位下,获取楼宇名称
        location.getFloor();    //室内精准定位下,获取当前位置所处的楼层信息
 
        if (location.getLocType() == BDLocation.TypeGpsLocation){
 
            //当前为GPS定位结果,可获取以下信息
            location.getSpeed();    //获取当前速度,单位:公里每小时
            location.getSatelliteNumber();    //获取当前卫星数
            location.getAltitude();    //获取海拔高度信息,单位米
            location.getDirection();    //获取方向信息,单位度
            location.
 
        } else if (location.getLocType() == BDLocation.TypeNetWorkLocation){
 
            //当前为网络定位结果,可获取以下信息
            location.getOperators();    //获取运营商信息
 
        } else if (location.getLocType() == BDLocation.TypeOffLineLocation) {
 
            //当前为网络定位结果
 
        } else if (location.getLocType() == BDLocation.TypeServerError) {
 
            //当前网络定位失败
            //可将定位唯一ID、IMEI、定位失败时间反馈至loc-bugs@baidu.com
 
        } else if (location.getLocType() == BDLocation.TypeNetWorkException) {
 
            //当前网络不通
 
        } else if (location.getLocType() == BDLocation.TypeCriteriaException) {
 
            //当前缺少定位依据,可能是用户没有授权,建议弹出提示框让用户开启权限
            //可进一步参考onLocDiagnosticMessage中的错误返回码
 
        }
    }
 
    /**
    * 回调定位诊断信息,开发者可以根据相关信息解决定位遇到的一些问题
    * 自动回调,相同的diagnosticType只会回调一次
    *
    * @param locType           当前定位类型
    * @param diagnosticType    诊断类型(1~9)
    * @param diagnosticMessage 具体的诊断信息释义
    */
    public void onLocDiagnosticMessage(int locType, int diagnosticType, String diagnosticMessage) {
 
        if (diagnosticType == LocationClient.LOC_DIAGNOSTIC_TYPE_BETTER_OPEN_GPS) {
 
            //建议打开GPS
 
        } else if (diagnosticType == LocationClient.LOC_DIAGNOSTIC_TYPE_BETTER_OPEN_WIFI) {
 
            //建议打开wifi,不必连接,这样有助于提高网络定位精度!
 
        } else if (diagnosticType == LocationClient.LOC_DIAGNOSTIC_TYPE_NEED_CHECK_LOC_PERMISSION) {
 
            //定位权限受限,建议提示用户授予APP定位权限!
 
        } else if (diagnosticType == LocationClient.LOC_DIAGNOSTIC_TYPE_NEED_CHECK_NET) {
 
            //网络异常造成定位失败,建议用户确认网络状态是否异常!
 
        } else if (diagnosticType == LocationClient.LOC_DIAGNOSTIC_TYPE_NEED_CLOSE_FLYMODE) {
 
            //手机飞行模式造成定位失败,建议用户关闭飞行模式后再重试定位!
 
        } else if (diagnosticType == LocationClient.LOC_DIAGNOSTIC_TYPE_NEED_INSERT_SIMCARD_OR_OPEN_WIFI) {
 
            //无法获取任何定位依据,建议用户打开wifi或者插入sim卡重试!
 
        } else if (diagnosticType == LocationClient.LOC_DIAGNOSTIC_TYPE_NEED_OPEN_PHONE_LOC_SWITCH) {
 
            //无法获取有效定位依据,建议用户打开手机设置里的定位开关后重试!
 
        } else if (diagnosticType == LocationClient.LOC_DIAGNOSTIC_TYPE_SERVER_FAIL) {
 
            //百度定位服务端定位失败
            //建议反馈location.getLocationID()和大体定位时间到loc-bugs@baidu.com
 
        } else if (diagnosticType == LocationClient.LOC_DIAGNOSTIC_TYPE_FAIL_UNKNOWN) {
 
            //无法获取有效定位依据,但无法确定具体原因
            //建议检查是否有安全软件屏蔽相关定位权限
            //或调用LocationClient.restart()重新启动后重试!
 
        }
    }
 
}

如上只列举了BDLocation的部分核心结果,更多详细说明请参见类参考中的介绍。

第四步,开始定位

启动定位,代码如下:

mLocationClient.start();

start:启动定位SDK。 stop:关闭定位SDK。调用start之后只需要等待定位结果自动回调即可。

自v7.2版本起,新增LocationClient.reStart()方法,用于在某些特定的异常环境下重启定位,具体异常环境请参见《开发指南 – 错误码》部分的介绍。

开发者定位场景如果是单次定位的场景,在收到定位结果之后直接调用stop函数即可。

如果stop之后仍然想进行定位,可以再次start等待定位结果回调即可。

如果开发者想按照自己逻辑请求定位,可以在start之后按照自己的逻辑请求LocationClient.requestLocation()函数,会主动触发定位SDK内部定位逻辑,等待定位回调即可。

位置提醒使用

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

//位置提醒相关代码
mNotifyer = new NotifyLister();
 
mNotifyer.SetNotifyLocation(42.03249652949337,113.3129895882556,3000,"gps");
//4个参数代表要位置提醒的点的坐标,具体含义依次为:纬度,经度,距离范围,坐标系类型(gcj02,gps,bd09,bd09ll)
 
mLocationClient.registerNotify(mNotifyer);
//注册位置提醒监听事件后,可以通过SetNotifyLocation 来修改位置提醒设置,修改后立刻生效。
 
//BDNotifyListner实现
public class NotifyLister extends BDNotifyListener{
 
    public void onNotify(BDLocation mlocation, float distance){
 
        mVibrator01.vibrate(1000);
        //振动提醒已到设定位置附近
    }
}
 
//取消位置提醒
mLocationClient.removeNotifyEvent(mNotifyer);