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 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 tipList, int rcode) {
if (rcode == 0 ){
List listString = new ArrayList();
for (int i = 0; i < tipList.size(); i++) {
listString.add(tipList.get(i).getName());
}
ArrayAdapter aAdapter = new ArrayAdapter(
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即可
<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