Android百度地圖API實現定位與目的地導航

jopen 13年前發布 | 333K 次閱讀 Android Android開發 移動開發

前幾天百度舉辦了百度世界大會,可惜沒去參加,之前參加了百度的開發者大會,在會上也了解了百度的產品,百度現在朝著平臺化的方向在發展,感覺很不錯,也試用了百度的產品,現在就用著百度的網盤,今天看了下百度地圖的開放API,然后做了個Demo,這里分享出來。如果應用主要針對國內市場的話,用百度地圖還是一個比較不錯的選擇。另外,百度還有一個PCS(Personal cloud storage)個人云存儲,我比較感興趣,之后也會繼續研究,然后做個Demo分享給大家。今天就先看看這個利用百度地圖定位并實現目的地導航的Demo。首先看實現效果:

                      Android百度地圖API實現定位與目的地導航                         Android百度地圖API實現定位與目的地導航

進入后首先會得到當前位置,在地圖上顯示出來,在輸入框中輸入目的地后,就會在地圖上出現最佳線路,我這里設置的是距離最小的駕車線路,另外還有公交線路、步行線路,在代碼中都有詳細注釋。另外,在控制臺還輸出了線路上每一個節點的信息以及起始位置和目的地的距離,信息顯示的是在當前節點的導航信息。如下圖:

                      Android百度地圖API實現定位與目的地導航

 

接下來就看如何實現了,首先,注冊百度開發者賬號,并進入百度地圖API查看相關資料百度地圖API,然后就是為需要加入地圖的應用注冊APP KEY,注冊完后,下載百度地圖jar文件,新建工程,并導入即可,下面看實現具體代碼,在代碼中有詳細注釋:

public class NavigationDemoActivity extends MapActivity {
    private String mMapKey = "注冊自己的key";
    private EditText destinationEditText = null;
    private Button startNaviButton = null;
    private MapView mapView = null;
    private BMapManager mMapManager = null;
    private MyLocationOverlay myLocationOverlay = null;
    //onResume時注冊此listener,onPause時需要Remove,注意此listener不是Android自帶的,是百度API中的
    private LocationListener locationListener;
    private MKSearch searchModel;
    GeoPoint pt;

@Override
public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    requestWindowFeature(Window.FEATURE_NO_TITLE);
    setContentView(R.layout.main);
    destinationEditText = (EditText) this.findViewById(R.id.et_destination);
    startNaviButton = (Button) this.findViewById(R.id.btn_navi);

    mMapManager = new BMapManager(getApplication());
    mMapManager.init(mMapKey, new MyGeneralListener());
    super.initMapActivity(mMapManager);

    mapView = (MapView) this.findViewById(R.id.bmapsView);
    //設置啟用內置的縮放控件
    mapView.setBuiltInZoomControls(true);  
    //設置在縮放動畫過程中也顯示overlay,默認為不繪制

// mapView.setDrawOverlayWhenZooming(true); //獲取當前位置層 myLocationOverlay = new MyLocationOverlay(this, mapView); //將當前位置的層添加到地圖底層中 mapView.getOverlays().add(myLocationOverlay);

    // 注冊定位事件
    locationListener = new LocationListener(){

        @Override
        public void onLocationChanged(Location location) {
            if (location != null){
                //生成GEO類型坐標并在地圖上定位到該坐標標示的地點
                 pt = new GeoPoint((int)(location.getLatitude()*1e6),
                        (int)(location.getLongitude()*1e6));

// System.out.println("---"+location.getLatitude() +":"+location.getLongitude()); mapView.getController().animateTo(pt); } } };

    //初始化搜索模塊
    searchModel = new MKSearch();
    //設置路線策略為最短距離
    searchModel.setDrivingPolicy(MKSearch.ECAR_DIS_FIRST);
    searchModel.init(mMapManager, new MKSearchListener() {
        //獲取駕車路線回調方法
        @Override
        public void onGetDrivingRouteResult(MKDrivingRouteResult res, int error) {
            // 錯誤號可參考MKEvent中的定義
            if (error != 0 || res == null) {
                Toast.makeText(NavigationDemoActivity.this, "抱歉,未找到結果", Toast.LENGTH_SHORT).show();
                return;
            }
            RouteOverlay routeOverlay = new RouteOverlay(NavigationDemoActivity.this, mapView);

            // 此處僅展示一個方案作為示例
            MKRoute route = res.getPlan(0).getRoute(0);
            int distanceM = route.getDistance();
            String distanceKm = String.valueOf(distanceM / 1000) +"."+String.valueOf(distanceM % 1000);
            System.out.println("距離:"+distanceKm+"公里---節點數量:"+route.getNumSteps());
            for (int i = 0; i < route.getNumSteps(); i++) {
                MKStep step = route.getStep(i);
                System.out.println("節點信息:"+step.getContent());
            }
            routeOverlay.setData(route);
            mapView.getOverlays().clear();
            mapView.getOverlays().add(routeOverlay);
            mapView.invalidate();
            mapView.getController().animateTo(res.getStart().pt);
        }

        //以下兩種方式和上面的駕車方案實現方法一樣
        @Override
        public void onGetWalkingRouteResult(MKWalkingRouteResult res, int error) {
            //獲取步行路線
        }

        @Override
        public void onGetTransitRouteResult(MKTransitRouteResult arg0, int arg1) {
            //獲取公交線路
        }

        @Override
        public void onGetBusDetailResult(MKBusLineResult arg0, int arg1) {
        }
        @Override
        public void onGetAddrResult(MKAddrInfo arg0, int arg1) {
        }
        @Override
        public void onGetSuggestionResult(MKSuggestionResult arg0, int arg1) {
        }
        @Override
        public void onGetPoiResult(MKPoiResult arg0, int arg1, int arg2) {
        }
    });

    startNaviButton.setOnClickListener(new OnClickListener() {

        @Override
        public void onClick(View v) {
            String destination = destinationEditText.getText().toString();

            //設置起始地(當前位置)
            MKPlanNode startNode = new MKPlanNode();
            startNode.pt = pt;
            //設置目的地
            MKPlanNode endNode = new MKPlanNode(); 
            endNode.name = destination;

            //展開搜索的城市
            String city = getResources().getString(R.string.beijing);

// System.out.println("----"+city+"---"+destination+"---"+pt); searchModel.drivingSearch(city, startNode, city, endNode); //步行路線 // searchModel.walkingSearch(city, startNode, city, endNode); //公交路線 // searchModel.transitSearch(city, startNode, endNode); } });

}

@Override
protected void onResume() {
    mMapManager.getLocationManager().requestLocationUpdates(locationListener);
    myLocationOverlay.enableMyLocation();
    myLocationOverlay.enableCompass(); // 打開指南針
    mMapManager.start();
    super.onResume();
}

@Override
protected void onPause() {
    mMapManager.getLocationManager().removeUpdates(locationListener);
    myLocationOverlay.disableMyLocation();//顯示當前位置
    myLocationOverlay.disableCompass(); // 關閉指南針
    mMapManager.stop();
    super.onPause();
}

@Override
protected boolean isRouteDisplayed() {
    // TODO Auto-generated method stub
    return false;
}

// 常用事件監聽,用來處理通常的網絡錯誤,授權驗證錯誤等
class MyGeneralListener implements MKGeneralListener {
        @Override
        public void onGetNetworkState(int iError) {
            Log.d("MyGeneralListener", "onGetNetworkState error is "+ iError);
            Toast.makeText(NavigationDemoActivity.this, "您的網絡出錯啦!",
                    Toast.LENGTH_LONG).show();
        }

        @Override
        public void onGetPermissionState(int iError) {
            Log.d("MyGeneralListener", "onGetPermissionState error is "+ iError);
            if (iError ==  MKEvent.ERROR_PERMISSION_DENIED) {
                // 授權Key錯誤:
                Toast.makeText(NavigationDemoActivity.this, 
                        "請在BMapApiDemoApp.java文件輸入正確的授權Key!",
                        Toast.LENGTH_LONG).show();
            }
        }
    }

}</pre>

然后是布局文件:

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="

<LinearLayout
    android:layout_width="fill_parent"
    android:layout_height="wrap_content"
    android:orientation="horizontal" >

    <TextView
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:textSize="18sp"
        android:text="Destination:" />

    <EditText
        android:id="@+id/et_destination"
        android:layout_width="fill_parent"
        android:layout_height="wrap_content" />
</LinearLayout>

<Button 
    android:id="@+id/btn_navi"
    android:layout_width="fill_parent"
       android:layout_height="wrap_content"
       android:text="Start navigate"/>

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

</LinearLayout></pre>
AndroidMainifest.xml

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="

<uses-sdk android:minSdkVersion="8" />

<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE"></uses-permission>
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION"></uses-permission>
<uses-permission android:name="android.permission.INTERNET"></uses-permission>
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"></uses-permission>
<uses-permission android:name="android.permission.ACCESS_WIFI_STATE"></uses-permission>  
<uses-permission android:name="android.permission.CHANGE_WIFI_STATE"></uses-permission> 
<uses-permission android:name="android.permission.READ_PHONE_STATE"></uses-permission>

<supports-screens android:largeScreens="true"
    android:normalScreens="true" android:smallScreens="true"
    android:resizeable="true" android:anyDensity="true"/>
<uses-sdk android:minSdkVersion="3"></uses-sdk>

<application
    android:icon="@drawable/ic_launcher"
    android:label="@string/app_name" >
    <activity
        android:name=".NavigationDemoActivity"
        android:label="@string/app_name" >
        <intent-filter>
            <action android:name="android.intent.action.MAIN" />

            <category android:name="android.intent.category.LAUNCHER" />
        </intent-filter>
    </activity>
</application>

</manifest></pre>轉自:http://blog.csdn.net/tangren03/article/details/7948648

 本文由用戶 jopen 自行上傳分享,僅供網友學習交流。所有權歸原作者,若您的權利被侵害,請聯系管理員。
 轉載本站原創文章,請注明出處,并保留原始鏈接、圖片水印。
 本站是一個以用戶分享為主的開源技術平臺,歡迎各類分享!