1. 程式人生 > 實用技巧 >中級實訓Android學習記錄——百度地圖API顯示定位

中級實訓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的,所以我們使用真機來執行。

  • 執行結果
顯示定位 自定義內容
  • bug report
  • 在模擬器上執行一直定位在北京

主要是因為模擬器上是沒有GPS的(也可能有但我不知道怎麼用),所以在模擬定位和動態獲取許可權中,我選擇了偷懶選擇真機進行模擬,真機模擬的教程在參考資料中有。

  • 在模擬器上許可權的獲取他不會自動彈窗提醒,但在真機上可以執行

使用真機啊(應該香)

  • 百度API文件中給出的程式碼,即使在真機模擬的情況下依然不能正確定位

是因為在第一次定位時我們要需要增加以下程式碼:

// 如果是第一次定位
LatLng ll = new LatLng(location.getLatitude(), location.getLongitude());
if (isFirstLocate) {
    isFirstLocate = false;
    //給地圖設定狀態
    mBaiduMap.animateMapStatus(MapStatusUpdateFactory.newLatLng(ll));
}

如果時第一次定位,要給地圖設定新狀態,否則地圖不會自動繪製,導致即使我們對地圖設定了新位置也不會進行渲染一樣。