中级实训Android学习记录——百度地图API显示定位

学习记录 2020/12/15

  • 之前过程:Android Studio工程配置、百度API的简单应用——显示地图
  • 百度API的简单应用——更改地图类型

在原本的代码上增加两行即可

// 更改地图类型
BaiduMap baiduMap = mapView.getMap();
baiduMap.setMapType(BaiduMap.MAP_TYPE_SATELLITE);
  • 百度API的简单应用——显示定位

参考资料:

Android 百度地图定位显示当前位置

显示定位

坐标系说明

Android定位SDK产品,支持全球定位,能够精准的获取经纬度信息。根据开发者的设置,在国内获得的坐标系类型可以是:国测局坐标、百度墨卡托坐标 和 百度经纬度坐标。在海外地区,只能获得WGS84坐标。请开发者在使用过程中注意坐标选择。定位SDK默认输出GCJ02坐标,地图SDK默认输出BD09ll坐标。

显示定位

通过如下几步您便可以在自己的地图中展示当前所在位置的定位点。

  1. 确保您的开发包中包含基本定位功能,该选项在您下载开发包时默认不会被选中

  2. 配置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"/>
    
  3. 开启地图的定位图层

    在调用baiduMap的地方增加以下语句:

    mBaiduMap.setMyLocationEnabled(true);
    
  4. 构造地图数据

    我们通过继承抽象类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("\n经度:" + location.getLatitude());
    stringBuilder.append("\n纬度:"+ location.getLongitude());
    stringBuilder.append("\n状态码:"+ location.getLocType());
    stringBuilder.append("\n国家:" + location.getCountry());
    stringBuilder.append("\n城市:"+ location.getCity());
    stringBuilder.append("\n区:" + location.getDistrict());
    stringBuilder.append("\n街道:" + location.getStreet());
    stringBuilder.append("\n地址:" + location.getAddrStr());
    
    mTextView.setText(stringBuilder.toString());
    }
    }
    
  5. 通过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();
    
  6. 正确管理各部分的生命周期

    @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();
    }
    

    至此,我们就可以获得正确的定位显示了

  7. 还可以自定义显示的样式

    // 自定义定位指针
    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的,所以我们使用真机来运行。

  • 运行结果
显示定位 自定义内容
image-20201216011626908 image-20201216011709346
  • bug report
  • 在模拟器上运行一直定位在北京

主要是因为模拟器上是没有GPS的(也可能有但我不知道怎么用),所以在模拟定位和动态获取权限中,我选择了偷懒选择真机进行模拟,真机模拟的教程在参考资料中有。

  • 在模拟器上权限的获取他不会自动弹窗提醒,但在真机上可以运行

使用真机啊(应该香)

  • 百度API文档中给出的代码,即使在真机模拟的情况下依然不能正确定位

是因为在第一次定位时我们要需要增加以下代码:

// 如果是第一次定位
LatLng ll = new LatLng(location.getLatitude(), location.getLongitude());
if (isFirstLocate) {
    isFirstLocate = false;
    //给地图设置状态
    mBaiduMap.animateMapStatus(MapStatusUpdateFactory.newLatLng(ll));
}

如果时第一次定位,要给地图设置新状态,否则地图不会自动绘制,导致即使我们对地图设置了新位置也不会进行渲染一样。

posted @ 2020-12-20 16:57  沐锋丶  阅读(101)  评论(1编辑  收藏  举报