天天看點

基于百度地圖sdk的地圖app開發(四)——顯示地圖定位1 配置AndroidManifest.xml檔案2 開啟地圖的定位圖層3 構造地圖資料4 通過LocationClient發起定位5 添加定位按鈕6 銷毀location7遇到定位失敗問題及解決辦法

這是基于百度地圖sdk的地圖app開發系列部落格第四篇

代碼倉庫位置:https://github.com/YanhuiLu89/lmap.git

上一篇 基于百度地圖sdk的地圖app開發(三)——優化地圖顯示

下一篇基于百度地圖sdk的地圖app開發(五)——poi檢索

因為本人是做C++開發,android和java都不熟,這方面知識有說錯或者不好的習慣,歡迎賜較。

官方參考文檔顯示定位

基于百度地圖sdk的地圖app開發(四)——顯示地圖定位1 配置AndroidManifest.xml檔案2 開啟地圖的定位圖層3 構造地圖資料4 通過LocationClient發起定位5 添加定位按鈕6 銷毀location7遇到定位失敗問題及解決辦法

地圖預設是在北京天安門位置,我們要把它定位到目前我們的實際位置。

1 配置AndroidManifest.xml檔案

加入權限聲明,如下

<!-- 這個權限用于進行網絡定位 -->
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />
<!-- 這個權限用于通路GPS定位 -->
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
           

在Application标簽中聲明定位的service元件

<service android:name="com.baidu.location.f"
    android:enabled="true"
    android:process=":remote"/>
           

2 開啟地圖的定位圖層

在MainActivity的onCreate函數開啟地圖的定位圖層 

//擷取地圖控件引用
        mMapView = (MapView) findViewById(R.id.bmapView);
        //開啟定位
        mMapView.getMap().setMyLocationEnabled(true);
           

3 構造地圖資料

将MainActivity類中添加内部類MyLocationListener繼承自BDAbstractListener并重寫其onReceieveLocation方法來擷取定位資料,并将其傳給MapView。

@Override
        public void onReceiveLocation(BDLocation bdLocation) {
            //mapView 銷毀後不在處理新接收的位置
            if (bdLocation == null || mMapView == null){
                return;
            }
            mCurLocation=bdLocation;//儲存目前定位,後面檢索算路要用
            int type=bdLocation.getLocType();
            MyLocationData locData = new MyLocationData.Builder()
                    .accuracy(bdLocation.getRadius())
                    // 此處設定開發者擷取到的方向資訊,順時針0-360
                    .direction(bdLocation.getDirection()).latitude(bdLocation.getLatitude())
                    .longitude(bdLocation.getLongitude()).build();
            BaiduMap bmap=mMapView.getMap();
            bmap.setMyLocationData(locData);
        }
           

4 通過LocationClient發起定位

 在MainActivity中添加成員變量mLocationClient代碼如下

private  LocationClient  mLocationClient=null;
           

在onCreate函數中 ,初始化定位,開啟定位,代碼如下

//定位初始化
        mLocationClient = new LocationClient(this);

        //通過LocationClientOption設定LocationClient相關參數
        LocationClientOption option = new LocationClientOption();
        option.setOpenGps(true); // 打開gps
        option.setIsNeedAddress(true);
        option.setCoorType("bd09ll"); // 設定坐标類型
        option.setScanSpan(1000);
        //設定locationClientOption
        mLocationClient.setLocOption(option);
        //注冊LocationListener監聽器
        MyLocationListener myLocationListener = new MyLocationListener();
        mLocationClient.registerLocationListener(myLocationListener);
        //開啟地圖定位圖層
        mLocationClient.start();
           

5 添加定位按鈕

我們使用百度地圖或者高德地圖時會用一個常用的場景:拖動地圖,浏覽地圖,之後點選左下角圓圈按鈕,會回到目前位置。下面添加定位按鈕,實作該功能。

往布局中添加定位按鈕,布局代碼如下

<ImageButton
        android:id="@+id/mylocation"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_marginTop="630dp"
        app:srcCompat="@android:drawable/ic_menu_mylocation" />
           

在定位按鈕的click函數中,發起定位,代碼如下

ImageButton locationBtn=this.findViewById(R.id.mylocation);
        locationBtn.setOnClickListener(new View.OnClickListener(){
            @Override
            public void onClick(View v) {
                mLocationClient.start();
            }
        });
           

6 銷毀location

在onDestroy函數,mapView銷毀前,銷毀location,代碼如下

@Override
    protected void onDestroy() {
        super.onDestroy();
        //在activity執行onDestroy時執行mMapView.onDestroy(),實作地圖生命周期管理
        mLocationClient.stop();
        mMapView.getMap().setMyLocationEnabled(false);
        mMapView.onDestroy();
    }
           

7遇到定位失敗問題及解決辦法

以上是按照官方文檔一步步開發的,但是完成後遇到了問題:位沒有成功,調試發現獲得經緯度的值都是一個無效的值

調查及解決方法如下

1、bdLocation.getLocType()值為62

在sdk中可以看到62的描述為“"Location failed beacuse we can not get any loc information!”。

原因:是app沒有真正獲得定位權限,去手機設定-》應用-》權限管理-》權限-》位置資訊中,找到app設為應用期間允許。

2、第一步改完後還是定位沒有成功,bdLocation.getLocType()值為505

在sdk中可以看到505的描述為“"NetWork location failed because baidu location service check the key is unlegal, please check the key in AndroidManifest.xml !‘

原因:AndroidManifest.xml中ak寫成了我的另外一個應用的key,改成正确的ak後(下面代碼第2行),type傳回值正确,經緯度也是有效值了。關于ak的擷取請參考 基于百度地圖sdk的地圖app開發(一)——開發環境配置與sdk下載下傳第三部分

<meta-data
            android:name="com.baidu.lbsapi.API_KEY"
            android:value="2IT56XoP7GW3G7saSAtcPq6QhQLVNcjr" />
           

3、經過上面兩部能獲得有效的經緯度值了,但是地圖還是沒有到我的目前位置

繼續調查發現

原因:通過網上調查需要調用 BadiduMap的animateMapStatus接口,重新刷地圖,另外為了顯示定位效果明顯,設定地圖縮放比例為18級。

解決辦法:修改MyLocationListener代碼,修改後代碼如下,主要添加了當手動定位(即點選定位按鈕)或者第一次定位成功時,縮放比例尺且調用 BadiduMap的animateMapStatus接口

class MyLocationListener extends BDAbstractLocationListener {
        private boolean isFirstLoc=true;
        private boolean autoLocation=false;
        public void setAutoLocation(boolean b){
            autoLocation=b;
        }
        @Override
        public void onReceiveLocation(BDLocation bdLocation) {
            //mapView 銷毀後不在處理新接收的位置
            if (bdLocation == null || mMapView == null){
                return;
            }
            int type=bdLocation.getLocType();
            MyLocationData locData = new MyLocationData.Builder()
                    .accuracy(bdLocation.getRadius())
                    // 此處設定開發者擷取到的方向資訊,順時針0-360
                    .direction(bdLocation.getDirection()).latitude(bdLocation.getLatitude())
                    .longitude(bdLocation.getLongitude()).build();
            BaiduMap bmap=mMapView.getMap();
            bmap.setMyLocationData(locData);
            /**
             *當首次定位或手動發起定位時,記得要放大地圖,便于觀察具體的位置
             * LatLng是縮放的中心點,這裡注意一定要和上面設定給地圖的經緯度一緻;
             * MapStatus.Builder 地圖狀态構造器
             */
            if (isFirstLoc||autoLocation) {
                isFirstLoc = false;
                autoLocation=false;
                LatLng ll = new LatLng(bdLocation.getLatitude(), bdLocation.getLongitude());
                MapStatus.Builder builder = new MapStatus.Builder();
                //設定縮放中心點;縮放比例;
                builder.target(ll).zoom(18.0f);
                //給地圖設定狀态
                bmap.animateMapStatus(MapStatusUpdateFactory.newMapStatus(builder.build()));
            }
        }
    }
           

另外定位按鈕的click函數中添加設定手動定位标志位,修改後代碼如下

ImageButton locationBtn=this.findViewById(R.id.mylocation);
        locationBtn.setOnClickListener(new View.OnClickListener(){
            @Override
            public void onClick(View v) {
                //設定手動定位
                myLocationListener.setAutoLocation(true);
                //開啟地圖定位圖層
                mLocationClient.start();
            }
        });
           

最後優化後的app效果如下

第一次啟動時定位到目前位置下圖1,拖動及縮放地圖下圖2,點選左下角Location按鈕下圖3

基于百度地圖sdk的地圖app開發(四)——顯示地圖定位1 配置AndroidManifest.xml檔案2 開啟地圖的定位圖層3 構造地圖資料4 通過LocationClient發起定位5 添加定位按鈕6 銷毀location7遇到定位失敗問題及解決辦法
基于百度地圖sdk的地圖app開發(四)——顯示地圖定位1 配置AndroidManifest.xml檔案2 開啟地圖的定位圖層3 構造地圖資料4 通過LocationClient發起定位5 添加定位按鈕6 銷毀location7遇到定位失敗問題及解決辦法
基于百度地圖sdk的地圖app開發(四)——顯示地圖定位1 配置AndroidManifest.xml檔案2 開啟地圖的定位圖層3 構造地圖資料4 通過LocationClient發起定位5 添加定位按鈕6 銷毀location7遇到定位失敗問題及解決辦法