本来这里应该继续讲述百度地图相关的知识,但继续向前会遇到定位相关的内容,所以我们先来讲解如何处理定位的内容。
1 导入库文件
- 我们去http://developer.baidu.com/map/geosdk-android-download.htm找到相关下载内容,找到4.0版本SDK并下载下来;
- 解压,将locaSDK_4.0.jar拷贝到工程的/libs目录;
- 将liblocSDK4.so拷贝到工程的/libs/armeabi目录;
2 设置AndroidManifest.xml文件
- 在Application标签中声明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>
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" >
</uses-permission>
<uses-permission android:name="android.permission.ACCESS_WIFI_STATE" >
</uses-permission>
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" >
</uses-permission>
<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" />
<uses-permission android:name="android.permission.MOUNT_UNMOUNT_FILESYSTEMS" >
</uses-permission>
<uses-permission android:name="android.permission.READ_LOGS" >
</uses-permission>
3 开始定位
- 在Activity中import相关类,添加成员变量:
private LocationClient locationClient = null;
private MyLocationListener listener = new MyLocationListener();
- 在onCreate中启动定位服务:
// 构造函数中的Context参数需要指定对整个进程有效的Context,所以使用Application的Context
locationClient = new LocationClient(getApplicationContext());
locationClient.setAK(KEY);
locationClient.registerLocationListener(listener);
// 设置定位参数
LocationClientOption option = new LocationClientOption();
option.setOpenGps(true);
option.setAddrType("all");// 返回的定位结果包含地址信息
option.setCoorType("bd09ll");// 返回的定位结果是百度经纬度,默认值gcj02
option.setScanSpan(5000);// 设置发起定位请求的间隔时间为5000ms
option.disableCache(true);// 禁止启用缓存定位
option.setPoiNumber(5); // 最多返回POI个数
option.setPoiDistance(1000); // poi查询距离
option.setPoiExtraInfo(true); // 是否需要POI的电话和地址等详细信息
locationClient.setLocOption(option);
// 启动定位服务
locationClient.start();
- 异步定位回调处理:
public class MyLocationListener implements BDLocationListener {
@Override
public void onReceiveLocation(BDLocation location) {
if (location == null)
return;
StringBuffer sb = new StringBuffer(256);
sb.append("time : ");
// 时间
sb.append(location.getTime());
sb.append("\nLoc Type : ");
// 定位类型:
// 61 : GPS定位结果
// 62 : 扫描整合定位依据失败。此时定位结果无效。
// 63 : 网络异常,没有成功向服务器发起请求。此时定位结果无效。
// 65 : 定位缓存的结果。
// 66 : 离线定位结果。通过requestOfflineLocaiton调用时对应的返回结果
// 67 : 离线定位失败。通过requestOfflineLocaiton调用时对应的返回结果
// 68 : 网络连接失败时,查找本地离线定位时对应的返回结果
// 161: 表示网络定位结果
// 162~167: 服务端定位失败。
sb.append(location.getLocType());
sb.append("\nlatitude : ");
// 纬度
sb.append(location.getLatitude());
sb.append("\nlontitude : ");
// 经度
sb.append(location.getLongitude());
sb.append("\nradius : ");
// 半径
sb.append(location.getRadius());
if (location.getLocType() == BDLocation.TypeGpsLocation) {
sb.append("\nspeed : ");
sb.append(location.getSpeed());
sb.append("\nsatellite : ");
sb.append(location.getSatelliteNumber());
} else if (location.getLocType() == BDLocation.TypeNetWorkLocation) {
sb.append("\naddr : ");
// 只有使用网络定位的情况下,才能获取当前位置的反地理编码描述。
sb.append(location.getAddrStr());
// 2.6以上版本SDK支持单独获取省份城市区县信息
sb.append("\n省份 : " + location.getProvince() + "; 城市:" + location.getCity() + "; 区县:" + location.getDistrict());
}
System.out.println(sb.toString());
}
@Override
public void onReceivePoi(BDLocation poiLocation) {
if (poiLocation == null) {
return;
}
StringBuffer sb = new StringBuffer(256);
sb.append("Poi time : ");
sb.append(poiLocation.getTime());
sb.append("\nerror code : ");
sb.append(poiLocation.getLocType());
sb.append("\nlatitude : ");
sb.append(poiLocation.getLatitude());
sb.append("\nlontitude : ");
sb.append(poiLocation.getLongitude());
sb.append("\nradius : ");
sb.append(poiLocation.getRadius());
if (poiLocation.getLocType() == BDLocation.TypeNetWorkLocation) {
sb.append("\naddr : ");
sb.append(poiLocation.getAddrStr());
}
if (poiLocation.hasPoi()) {
sb.append("\nPoi:");
sb.append(poiLocation.getPoi());
} else {
sb.append("noPoi information");
}
System.out.println(sb.toString());
}
}
- 上面的onReceivePoi只有在调用getPoi方法后才可能产生异步回调。
4 设置位置提醒
对于某些应用(例如导航),需要在到达某位置之后振动提醒用户,可设置位置提醒。
相关代码:
// 位置提醒相关代码
notifyListener = new MyNotifyListener();
// 4个参数代表要位置提醒的点的坐标,具体含义依次为:纬度,经度,距离范围,坐标系类型(gcj02,gps,bd09,bd09ll)
notifyListener.SetNotifyLocation(31.209294,121.472471,3000,"gps");
// 注册位置提醒监听事件后,可以通过SetNotifyLocation 来修改位置提醒设置,修改后立刻生效。
// 位置提醒最多提醒3次,3次过后将不再提醒。 假如需要再次提醒,或者要修改提醒点坐标,都可通过函数SetNotifyLocation()来实现。
locationClient.registerNotify(notifyListener);
// 取消位置提醒
// locationClient.removeNotifyEvent(notifyListener);
用于提醒的Listener:
public class MyNotifyListener extends BDNotifyListener {
/**
* mlocation表示当前位置,distance是当前坐标中心点与设定位置提醒的坐标点之间的距离值。
*/
@Override
public void onNotify(BDLocation mlocation, float distance) {
super.onNotify(mlocation, distance);
System.out.println("已经到设定位置附近。");
}
}
5 地理围栏
地理围栏服务目前处于Beta阶段,主要用于提供比Notify更低功耗的提醒,使用上和Notify差不多,暂不做介绍。
6 注意事项
- 定位SDK必须注册GPS和网络的使用权限。
- 使用定位SDK请保证网络连接通畅(GPS定位方式不需要连网)。
- 我们强烈建议您设置自己的prodName,并保管好,这样方便我们为您提供更好的定位服务。
- 若需要返回的定位结果里包含地址信息,请保证网络连接。
- 定位SDK可以返回bd09、bd09ll、gcj02三种类型坐标,若需要将定位点的位置通过百度Android地图 SDK进行地图展示,请返回bd09ll,将无偏差的叠加在百度地图上。
- 有的移动设备锁屏后为了省电会自动关闭网络连接,此时网络定位模式的定位失效。此外,锁屏后移动设备若进入cpu休眠,定时定位功能也失效。若您需要实现在cpu休眠状态仍需定时定位,可以用alarmManager 实现1个cpu可叫醒的timer,定时请求定位。
- 使用SDK4.0需要设置Accesskey,设置有误会引起定位和地理围栏服务不能正常使用,必须进行Accesskey的正确设置。