学习记录 2020/12/15
- 之前过程:Android Studio工程配置、百度API的简单应用——显示地图
- 百度API的简单应用——更改地图类型
在原本的代码上增加两行即可
// 更改地图类型 BaiduMap baiduMap = mapView.getMap(); baiduMap.setMapType(BaiduMap.MAP_TYPE_SATELLITE);
- 百度API的简单应用——显示定位
参考资料:
坐标系说明
Android定位SDK产品,支持全球定位,能够精准的获取经纬度信息。根据开发者的设置,在国内获得的坐标系类型可以是:国测局坐标、百度墨卡托坐标 和 百度经纬度坐标。在海外地区,只能获得
WGS84
坐标。请开发者在使用过程中注意坐标选择。定位SDK默认输出GCJ02
坐标,地图SDK默认输出BD09ll
坐标。显示定位
通过如下几步您便可以在自己的地图中展示当前所在位置的定位点。
确保您的开发包中包含基本定位功能,该选项在您下载开发包时默认不会被选中
配置
AndroidManifest.xml
文件1.加入如下权限使用声明
<!-- 这个权限用于进行网络定位 --> <uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" /> <!-- 这个权限用于访问GPS定位 --> <uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
2.在Application标签中声明定位的service组件
<service android:name="com.baidu.location.f" android:enabled="true" android:process=":remote"/>
开启地图的定位图层
在调用baiduMap的地方增加以下语句:
mBaiduMap.setMyLocationEnabled(true);
构造地图数据
我们通过继承抽象类BDAbstractListener并重写其onReceieveLocation方法来获取定位数据,并将其传给MapView。
所以先新建一个java文件并按以下方式编写代码:
public class MyLocationListener extends BDAbstractLocationListener { private boolean isFirstLocate = true; @Override public void onReceiveLocation(BDLocation location) { //mapView 销毁后不在处理新接收的位置 Log.d("22", "onReceiveLocation: in"); if (location == null || mMapView == null){ return; } // 如果是第一次定位 LatLng ll = new LatLng(location.getLatitude(), location.getLongitude()); if (isFirstLocate) { isFirstLocate = false; //给地图设置状态 mBaiduMap.animateMapStatus(MapStatusUpdateFactory.newLatLng(ll)); } MyLocationData locData = new MyLocationData.Builder() .accuracy(location.getRadius()) // 此处设置开发者获取到的方向信息,顺时针0-360 .direction(location.getDirection()).latitude(location.getLatitude()) .longitude(location.getLongitude()).build(); mBaiduMap.setMyLocationData(locData); Log.d("0", "onReceiveLocation: 定位到 " + location.getAddrStr()); Toast.makeText(MainActivity.this, "定位到" + locData.toString(), Toast.LENGTH_SHORT).show(); // 显示当前信息 StringBuilder stringBuilder = new StringBuilder(); stringBuilder.append(" 经度:" + location.getLatitude()); stringBuilder.append(" 纬度:"+ location.getLongitude()); stringBuilder.append(" 状态码:"+ location.getLocType()); stringBuilder.append(" 国家:" + location.getCountry()); stringBuilder.append(" 城市:"+ location.getCity()); stringBuilder.append(" 区:" + location.getDistrict()); stringBuilder.append(" 街道:" + location.getStreet()); stringBuilder.append(" 地址:" + location.getAddrStr()); mTextView.setText(stringBuilder.toString()); } }
通过LocationClient发起定位
//定位初始化 mLocationClient = new LocationClient(getApplicationContext()); //通过LocationClientOption设置LocationClient相关参数 LocationClientOption option = new LocationClientOption(); option.setLocationMode(LocationClientOption.LocationMode.Device_Sensors); // 定位模式是仅限设备模式,也就是仅允许GPS来定位。 option.setOpenGps(true); // 打开gps option.setCoorType("bd09ll"); // 设置坐标类型 option.setScanSpan(1000); //设置打开自动回调位置模式,该开关打开后,期间只要定位SDK检测到位置变化就会主动回调给开发者 option.setIsNeedAddress(true); //可选,是否需要地址信息,默认为不需要,即参数为false //如果开发者需要获得当前点的地址信息,此处必须为true option.setNeedNewVersionRgc(true); //可选,设置是否需要最新版本的地址信息。默认需要,即参数为true //设置locationClientOption mLocationClient.setLocOption(option); //注册LocationListener监听器 MyLocationListener myLocationListener = new MyLocationListener(); mLocationClient.registerLocationListener(myLocationListener); //开启地图定位图层 mLocationClient.start();
正确管理各部分的生命周期
@Override protected void onResume() { mMapView.onResume(); super.onResume(); } @Override protected void onPause() { mMapView.onPause(); super.onPause(); } @Override protected void onDestroy() { mLocationClient.stop(); mBaiduMap.setMyLocationEnabled(false); mMapView.onDestroy(); mMapView = null; super.onDestroy(); }
至此,我们就可以获得正确的定位显示了
还可以自定义显示的样式
// 自定义定位指针 MyLocationConfiguration.LocationMode mCurrentMode = MyLocationConfiguration.LocationMode.COMPASS; BitmapDescriptor mCurrentMarker = BitmapDescriptorFactory.fromResource(R.drawable.ic_launcher_background); MyLocationConfiguration myLocationConfiguration = new MyLocationConfiguration(mCurrentMode, true, mCurrentMarker, 0xAAFFFF88, 0xAA00FF00); mBaiduMap.setMyLocationConfiguration(myLocationConfiguration);
在
OnCreate()
中加入以上代码即可但是我们在模拟器上的定位出了点问题,模拟器似乎是不自带GPS的,所以我们使用真机来运行。
- 运行结果
显示定位 | 自定义内容 |
---|---|
- bug report
- 在模拟器上运行一直定位在北京
主要是因为模拟器上是没有GPS的(也可能有但我不知道怎么用),所以在模拟定位和动态获取权限中,我选择了偷懒选择真机进行模拟,真机模拟的教程在参考资料中有。
- 在模拟器上权限的获取他不会自动弹窗提醒,但在真机上可以运行
使用真机啊(应该香)
- 百度API文档中给出的代码,即使在真机模拟的情况下依然不能正确定位
是因为在第一次定位时我们要需要增加以下代码:
// 如果是第一次定位 LatLng ll = new LatLng(location.getLatitude(), location.getLongitude()); if (isFirstLocate) { isFirstLocate = false; //给地图设置状态 mBaiduMap.animateMapStatus(MapStatusUpdateFactory.newLatLng(ll)); }
如果时第一次定位,要给地图设置新状态,否则地图不会自动绘制,导致即使我们对地图设置了新位置也不会进行渲染一样。