百度地圖SDK地圖學習——實現定位功能

以前已經完成了百度地圖SDK和百度定位SDK的配置。 java

http://my.oschina.net/u/1051634/blog/180880 android

實現百度定位的功能,最好仔細看看官方的文檔,看了好幾回纔有點明白。 git

開發指南:http://developer.baidu.com/map/geosdk-android-developv3.3.htm api

類參考:http://developer.baidu.com/map/geosdk-android-classv3.3.htm app

我初步想實現以下功能:點擊findme按鈕,進入新的activity,即在地圖上顯示個人位置。 ide

   


首先是完成androidManifest.xml的相關設置 動畫

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
          package="com.example.TraceMe">
    <!--<uses-sdk android:minSdkVersion="19"/>-->
    <application
            android:name="com.example.TraceMe.TraceMe"
            android:icon="@drawable/icon"
            android:label="@string/app_name">
        <activity
                android:name="com.example.TraceMe.Activity_Main"
                android:configChanges="orientation"
                android:label="TraceMe"
                android:screenOrientation="sensor" >
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />

                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
        </activity>
        <activity android:name=".Activity_showMyLocation"/>
        <service
                android:name="com.baidu.location.f"
                android:enabled="true"
                android:process=":remote" >
        </service>

    </application>

    <!--權限設置-->
    <uses-permission android:name="android.permission.GET_ACCOUNTS" />
    <uses-permission android:name="android.permission.USE_CREDENTIALS" />
    <uses-permission android:name="android.permission.MANAGE_ACCOUNTS" />
    <uses-permission android:name="android.permission.AUTHENTICATE_ACCOUNTS" />

    <permission android:name="android.permission.BAIDU_LOCATION_SERVICE" >
    </permission>

    <uses-permission android:name="android.permission.BAIDU_LOCATION_SERVICE" >
    </uses-permission>
    <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" >
    </uses-permission>
    <uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" >
    </uses-permission>
    <uses-permission android:name="android.permission.INTERNET" >
    </uses-permission>
    <uses-permission android:name="android.permission.ACCESS_MOCK_LOCATION" >
    </uses-permission>
    <!-- <uses-permission android:name="android.permission.WRITE_APN_SETTINGS"></uses-permission> -->
    <uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" >
    </uses-permission>
    <uses-permission android:name="com.android.launcher.permission.READ_SETTINGS" />
    <uses-permission android:name="android.permission.WAKE_LOCK" >
    </uses-permission>
    <uses-permission android:name="android.permission.CHANGE_WIFI_STATE" />
    <uses-permission android:name="android.permission.ACCESS_WIFI_STATE" />
    <uses-permission android:name="android.permission.ACCESS_GPS" />
    <uses-permission android:name="android.permission.READ_PHONE_STATE" />
    <uses-permission android:name="android.permission.READ_CONTACTS" />
    <uses-permission android:name="android.permission.CALL_PHONE" />
    <uses-permission android:name="android.permission.READ_SMS" />
    <uses-permission android:name="android.permission.SEND_SMS" />
    <!-- SDK1.5須要android.permission.GET_TASKS權限判斷本程序是否爲當前運行的應用? -->
    <uses-permission android:name="android.permission.GET_TASKS" />
    <uses-permission android:name="android.permission.CAMERA" >
    </uses-permission>
    <uses-permission android:name="android.permission.RECORD_AUDIO" >
    </uses-permission>
    <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" >
    </uses-permission>
    <uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED" />
    <uses-permission android:name="android.permission.BROADCAST_STICKY" />
    <uses-permission android:name="android.permission.WRITE_SETTINGS" />
    <!-- 來電消音 -->
    <uses-permission android:name="android.permission.PROCESS_OUTGOING_CALLS" >
    </uses-permission>
    <uses-permission android:name="android.permission.READ_PHONE_STATE" />
    <uses-permission android:name="android.permission.MODIFY_AUDIO_SETTINGS" />

    <supports-screens
            android:anyDensity="true"
            android:largeScreens="true"
            android:normalScreens="false"
            android:resizeable="true"
            android:smallScreens="true" />

</manifest>




而後在layout目錄下完成相關activtiy的設計 this

其中百度地圖的控件聲明以下: spa

<com.baidu.mapapi.map.MapView android:id="@+id/bmapView"
                                  android:layout_width="fill_parent"
                                  android:layout_height="fill_parent"
                                  android:clickable="true"
                                  android:layout_weight="1"
            />



而後在Activity_showMyLocation中完成定位操做並顯示在地圖上

package com.example.TraceMe;

import android.app.Activity;
import android.content.Intent;
import android.graphics.Bitmap;
import android.graphics.drawable.Drawable;
import android.os.Bundle;
import android.util.Log;
import android.widget.Button;
import android.widget.Toast;
import com.baidu.location.BDLocation;
import com.baidu.location.BDLocationListener;
import com.baidu.location.LocationClient;
import com.baidu.location.LocationClientOption;
import com.baidu.mapapi.BMapManager;
import com.baidu.mapapi.map.*;
import com.baidu.platform.comapi.basestruct.GeoPoint;

/**
 * Created with IntelliJ IDEA.
 * User: mac
 * Date: 12/1/13
 * Time: 5:12 下午
 * To change this template use File | Settings | File Templates.
 */
public class Activity_showMyLocation extends Activity {
    
    private MapView mMapView = null;//MapView 是地圖主控件
    private MapController mMapController = null;//用MapController完成地圖控制
    MKMapViewListener mMapListener = null;//MKMapViewListener 用於處理地圖事件回調

    //定位相關
    LocationClient mLocClient;
    LocationData locData = null;
    public MyLocationListenner myListener = new MyLocationListenner();
//定位圖層
    locationOverlay myLocationOverlay = null;

//    Button map_FindMe = null;
    boolean isRequest = false;//是否手動觸發請求定位
    boolean isFirstLoc = true;//是否首次定位
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_map);

/**
 * 使用地圖sdk前需先初始化BMapManager.
 * BMapManager是全局的,可爲多個MapView共用,它須要地圖模塊建立前建立,
 * 並在地圖地圖模塊銷燬後銷燬,只要還有地圖模塊在使用,BMapManager就不該該銷燬
 */
        TraceMe app = (TraceMe)this.getApplication();
        if (app.mBMapManager == null) {
            app.mBMapManager = new BMapManager(this);
            app.mBMapManager.init(TraceMe.strKey,new TraceMe.MyGeneralListener());
        }
       mMapView = (MapView)findViewById(R.id.bmapView);
        /**
         * 獲取地圖控制器
         */
        mMapController = mMapView.getController();
        /**
         *  設置地圖是否響應點擊事件  .
         */
        mMapController.enableClick(true);
        /**
         * 設置地圖縮放級別
         */
        mMapController.setZoom(18);

        
        /**
         *  MapView的生命週期與Activity同步,當activity掛起時需調用MapView.onPause()
         */
        mMapListener = new MKMapViewListener() {
            @Override
            public void onMapMoveFinish() {
                /**
                 * 在此處理地圖移動完成回調
                 * 縮放,平移等操做完成後,此回調被觸發
                 */
            }

            @Override
            public void onClickMapPoi(MapPoi mapPoiInfo) {
                /**
                 * 在此處理底圖poi點擊事件
                 * 顯示底圖poi名稱並移動至該點
                 * 設置過: mMapController.enableClick(true); 時,此回調才能被觸發
                 *
                 */
                String title = "";
                if (mapPoiInfo != null){
                    title = mapPoiInfo.strText;
                    Toast.makeText(Activity_showMyLocation.this, title, Toast.LENGTH_SHORT).show();
                    mMapController.animateTo(mapPoiInfo.geoPt);
                }
            }

            @Override
            public void onGetCurrentMap(Bitmap b) {
                /**
                 *  當調用過 mMapView.getCurrentMap()後,此回調會被觸發
                 *  可在此保存截圖至存儲設備
                 */
            }

            @Override
            public void onMapAnimationFinish() {
                /**
                 *  地圖完成帶動畫的操做(如: animationTo())後,此回調被觸發
                 */
            }
            /**
             * 在此處理地圖載完成事件
             */
            @Override
            public void onMapLoadFinish() {
                Toast.makeText(Activity_showMyLocation.this,
                        "地圖加載完成",
                        Toast.LENGTH_SHORT).show();

            }
        };
        mMapView.regMapViewListener(TraceMe.getInstance().mBMapManager, mMapListener);

        mLocClient = new LocationClient( this );
        locData = new LocationData();
        mLocClient.registerLocationListener( myListener );
        LocationClientOption option = new LocationClientOption();
        option.setOpenGps(true);//打開gps
        option.setCoorType("bd09ll");     //設置座標類型
        option.setScanSpan(5000);
        mLocClient.setLocOption(option);
        mLocClient.start();

        //定位圖層初始化
        myLocationOverlay = new locationOverlay(mMapView);
        //設置定位數據
        myLocationOverlay.setData(locData);
        //添加定位圖層
        mMapView.getOverlays().add(myLocationOverlay);
        myLocationOverlay.enableCompass();
        //修改定位數據後刷新圖層生效
        mMapView.refresh();
    }
//    /**
//     * 修改位置圖標
//     * @param marker
//     */
//    public void modifyLocationOverlayIcon(Drawable marker){
//        //當傳入marker爲null時,使用默認圖標繪製
//        myLocationOverlay.setMarker(marker);
//        //修改圖層,須要刷新MapView生效
//        mMapView.refresh();
//    }

    @Override
    protected void onPause() {
        /**
         *  MapView的生命週期與Activity同步,當activity掛起時需調用MapView.onPause()
         */
        mMapView.onPause();
        super.onPause();
    }

    @Override
    protected void onResume() {
        /**
         *  MapView的生命週期與Activity同步,當activity恢復時需調用MapView.onResume()
         */
        mMapView.onResume();
        super.onResume();
    }

    @Override
    protected void onDestroy() {
        /**
         *  MapView的生命週期與Activity同步,當activity銷燬時需調用MapView.destroy()
         */
        mMapView.destroy();
        super.onDestroy();
    }

    @Override
    protected void onSaveInstanceState(Bundle outState) {
        super.onSaveInstanceState(outState);
        mMapView.onSaveInstanceState(outState);

    }

    @Override
    protected void onRestoreInstanceState(Bundle savedInstanceState) {
        super.onRestoreInstanceState(savedInstanceState);
        mMapView.onRestoreInstanceState(savedInstanceState);
    }

    public class locationOverlay extends MyLocationOverlay{

        public locationOverlay(MapView mapView) {
            super(mapView);
            // TODO Auto-generated constructor stub
        }

    }
    public class MyLocationListenner implements BDLocationListener {

        @Override
        public void onReceiveLocation(BDLocation location) {
            if (location == null)
                return ;

            locData.latitude = location.getLatitude();
            locData.longitude = location.getLongitude();
            //若是不顯示定位精度圈,將accuracy賦值爲0便可
            locData.accuracy = location.getRadius();
            // 此處能夠設置 locData的方向信息, 若是定位 SDK 未返回方向信息,用戶能夠本身實現羅盤功能添加方向信息。
            locData.direction = location.getDerect();
            //更新定位數據
            myLocationOverlay.setData(locData);
            //更新圖層數據執行刷新後生效
            mMapView.refresh();
            //是手動觸發請求或首次定位時,移動到定位點
            if (isRequest || isFirstLoc){
                //移動地圖到定位點
//                Log.d("LocationOverlay", "receive location, animate to it");
                mMapController.animateTo(new GeoPoint((int)(locData.latitude* 1e6), (int)(locData.longitude *  1e6)));
                isRequest = false;


            }
            //首次定位完成
            isFirstLoc = false;
        }

        public void onReceivePoi(BDLocation poiLocation) {
            if (poiLocation == null){
                return ;
            }
        }
    }

}
相關文章
相關標籤/搜索