android-4集成高德地圖的搜索和導航功能

1.準備工作
1.1在高德地圖導航包中用到的語音庫爲科大訊飛的,要使用的話也要在科大訊飛的開源平臺上註冊一個個人使用者key
1.2在使用高德地圖的lib庫時,最好使用導航和地圖的合成庫,如果導航庫和地圖庫不匹配的話,在導航頁面上就會出現不同步的情況(自己就遇到過兩個包不匹配,地圖庫版本比較老,導致導航頁面最後只有聲音而圖標不走的情況)
lib目錄如下

2.關鍵字搜索功能的實現
實現PoiSearch.OnPoiSearchListener

@Override
    public void onPoiSearched(PoiResult result, int rCode) {
        if (rCode == 0){
            if (result !=null && result.getQuery()!= null){
                if (result.getQuery().equals(query)){
                    poiResult = result;

                    List<PoiItem> poiItems = poiResult.getPois();
                    List<SuggestionCity> suggestionCities = poiResult
                            .getSearchSuggestionCitys();

                    if (poiItems != null && poiItems.size()>0){

                        MyPoiOverlay myPoiOverlay = new MyPoiOverlay(aMap,poiItems);
                        myPoiOverlay.removeFromMap();
                        myPoiOverlay.addToMap();
                        myPoiOverlay.zoomToSpan();

                        for (int i = 0 ; i<poiItems.size();i++){
                            list.add(" "+(i+1)+"."+poiItems.get(i).toString());
                        }
                        ArrayAdapter<String> adapter=new ArrayAdapter<String>(MainActivity.this,
                                R.layout.main_listview_item,getData());
                        listView.setAdapter(adapter);

                    }else {
                        Log.i(TAG,"onPoiSearched error");
                    }
                }
            }
        }else {
            Log.i(TAG,"onSearchPoi + rcode = "+rCode);
        }
    }

其中MyPoiOverlay類是重寫了PoiOverlay類的getBitmapDescriptor方法,目的是爲了讓搜索回調的poiItems中的各個marker使用不同的圖標,當然如果要實現更多的效果,可以直接寫一個新的Overlay

public class MyPoiOverlay extends PoiOverlay {

    public MyPoiOverlay(AMap aMap, List<PoiItem> list) {
        super(aMap, list);
    }

    @Override
    protected BitmapDescriptor getBitmapDescriptor(int i) {
        //return super.getBitmapDescriptor(i);
        switch (i){
            case 0:
                return BitmapDescriptorFactory.fromResource(R.drawable.marker_1);
            case 1:
                return BitmapDescriptorFactory.fromResource(R.drawable.marker_2);
            case 2:
                return BitmapDescriptorFactory.fromResource(R.drawable.marker_3);
            case 3:
                return BitmapDescriptorFactory.fromResource(R.drawable.marker_4);
            case 4:
                return BitmapDescriptorFactory.fromResource(R.drawable.marker_5);
            case 5:
                return BitmapDescriptorFactory.fromResource(R.drawable.marker_6);
            case 6:
                return BitmapDescriptorFactory.fromResource(R.drawable.marker_7);
            case 7:
                return BitmapDescriptorFactory.fromResource(R.drawable.marker_8);
            case 8:
                return BitmapDescriptorFactory.fromResource(R.drawable.marker_9);
            case 9:
                return BitmapDescriptorFactory.fromResource(R.drawable.marker_10);
        }
        return BitmapDescriptorFactory.fromResource(R.drawable.map);
    }
}

關鍵字的模糊提示用的是AutoCompleteTextView,重寫TextWatcher的onTextChanged。

@Override
    public void onTextChanged(CharSequence s, int start, int before, int count) {
        String newText = s.toString().trim();
        Inputtips inputtips = new Inputtips(this, new Inputtips.InputtipsListener() {
            @Override
            public void onGetInputtips(List<Tip> tipList, int rcode) {
                if (rcode == 0 ){
                    List<String> listString = new ArrayList<String>();
                    for (int i = 0; i < tipList.size(); i++) {
                        listString.add(tipList.get(i).getName());
                    }
                    ArrayAdapter<String> aAdapter = new ArrayAdapter<String>(
                            getApplicationContext(),
                            R.layout.route_inputs, listString);
                    searchText.setAdapter(aAdapter);
                    aAdapter.notifyDataSetChanged();
                }
            }
        });
        try {
            inputtips.requestInputtips(newText,"杭州");
        } catch (AMapException e) {
            e.printStackTrace();
        }
    }

R.layout.route_inputs爲下拉框每個條目的xml

搜索關鍵字,其中Query中的第一個參數是關鍵字,第三個參數是範圍

public void doSearch(){
        query = new PoiSearch.Query(searchText.getText().toString(),"","杭州");
        query.setPageSize(10);
        query.setPageNum(0);

        poiSearch = new PoiSearch(this,query);
        poiSearch.setOnPoiSearchListener(this);
        poiSearch.searchPOIAsyn();
    }

3.路徑規劃
實現AMapNaviListener,同時添加監聽對象
aMapNavi = AMapNavi.getInstance(this);
aMapNavi.addAMapNaviListener(this);
mRouteOverlay = new com.amap.api.navi.view.RouteOverLay(aMap,null);
這個選擇的模式PathPlanningStrategy.DRIVING_DEFAULT爲駕駛模式,高德地圖還提供步行路線的規劃。
calculateDriveRoute這個函數實現。導航的時候起點,終點輸入的都是經緯度。

private void calculateDriveRoute(){
        mStartPoints.clear();
        mEndPoints.clear();

        NaviLatLng naviLatLng = new NaviLatLng(localLocation.getLatitude(),
                localLocation.getLongitude());
        mStartPoints.add(naviLatLng);
        mEndPoints.add(mNavEnd);

        boolean isSuccess = aMapNavi.calculateDriveRoute(mStartPoints,mEndPoints,
                null, PathPlanningStrategy.DRIVING_DEFAULT);
        if (!isSuccess){
            Log.i(TAG,"driving calculateDriveRoute error");
        }
}

路徑計算成功或者失敗都會有回調

@Override
    public void onCalculateRouteSuccess() {
        AMapNaviPath naviPath = aMapNavi.getNaviPath();
        if (naviPath == null){
            return;
        }
        Log.i(TAG,"navi路徑規劃成功");
        mRouteOverlay.setAMapNaviPath(naviPath);
        mRouteOverlay.addToMap();

        aMap.moveCamera(CameraUpdateFactory.zoomTo(18.0f));
    }

    @Override
    public void onCalculateRouteFailure(int i) {
        Log.i(TAG,"navi路徑規劃錯誤+"+i);
    }

4.導航功能的實現
佈局文件直接加載com.amap.api.navi.AMapNaviView即可

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent">

    <com.amap.api.navi.AMapNaviView
        android:id="@+id/navi_view"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        />
</LinearLayout>

主要實現了AMapNaviListener,AMapNaviViewListener
在路徑規劃成功後調用mAMapNavi.startNavi(AMapNavi.EmulatorNaviMode),這裏使用的是模擬導航模式,主要在onCreate中做了如下配置。

@Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        requestWindowFeature(Window.FEATURE_NO_TITLE);

        mTtsManager = TTSController.getInstance(getApplicationContext());
        mTtsManager.init();
        mTtsManager.startSpeaking();

        mAMapNavi = AMapNavi.getInstance(getApplicationContext());
        mAMapNavi.addAMapNaviListener(this);
        mAMapNavi.addAMapNaviListener(mTtsManager);
        mAMapNavi.setEmulatorNaviSpeed(150);



        Intent intent = getIntent();
        mStartLatlng = new NaviLatLng(intent.getDoubleExtra("startLatitude",30),
                intent.getDoubleExtra("startLongitude",120));
        mEndLatlng = new NaviLatLng(intent.getDoubleExtra("endLatitude",30.001),
                intent.getDoubleExtra("endLongitude",120.0001));

        mStartList.add(mStartLatlng);
        mEndList.add(mEndLatlng);

        mAMapNavi.calculateDriveRoute(mStartList, mEndList, mWayPointList, PathPlanningStrategy.DRIVING_DEFAULT);
    }

源碼已經上傳,比較簡單。只是一個demo。僅供參考
https://github.com/runyyf/android_gaode_demo.git

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章