1.準備工作
1.1在高德地圖導航包中用到的語音庫爲科大訊飛的,要使用的話也要在科大訊飛的開源平臺上註冊一個個人使用者key
1.2在使用高德地圖的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