天天看點

安卓高德地圖開發之引入導航功能

    高德地圖導航添加需要添加特定的navi包。

    高德地圖開發中添加導航功能的簡單實作原理是引入自定義起點和終點資料後調用官方給出的demo代碼。

    首先需要一個baseactivity類,給出代碼:

package com.example.maptest;

import android.app.Activity;
import android.os.Bundle;
import android.util.Log;
import android.view.Window;
import android.widget.Toast;

import com.amap.api.navi.AMapNavi;
import com.amap.api.navi.AMapNaviListener;
import com.amap.api.navi.AMapNaviView;
import com.amap.api.navi.AMapNaviViewListener;
import com.amap.api.navi.model.AMapLaneInfo;
import com.amap.api.navi.model.AMapNaviCross;
import com.amap.api.navi.model.AMapNaviInfo;
import com.amap.api.navi.model.AMapNaviLocation;
import com.amap.api.navi.model.AMapNaviStaticInfo;
import com.amap.api.navi.model.AMapNaviTrafficFacilityInfo;
import com.amap.api.navi.model.AimLessModeCongestionInfo;
import com.amap.api.navi.model.AimLessModeStat;
import com.amap.api.navi.model.NaviInfo;
import com.amap.api.navi.model.NaviLatLng;
import com.amap.navi.demo.util.TTSController;
import com.autonavi.tbt.NaviStaticInfo;
import com.autonavi.tbt.TrafficFacilityInfo;

import java.util.ArrayList;
import java.util.List;

public class BaseActivity extends Activity implements AMapNaviListener,
		AMapNaviViewListener {

	protected AMapNaviView mAMapNaviView;
	protected AMapNavi mAMapNavi;
	protected TTSController mTtsManager;
	protected NaviLatLng mEndLatlng = new NaviLatLng(32.1194970000,
			118.9709290000);//自定義的起點
	protected NaviLatLng mStartLatlng = new NaviLatLng(32.0865760000,
			118.7775490000);//自定義的終點
	protected final List<NaviLatLng> sList = new ArrayList<NaviLatLng>();
	protected final List<NaviLatLng> eList = new ArrayList<NaviLatLng>();
	protected List<NaviLatLng> mWayPointList;

	@Override
	protected void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		requestWindowFeature(Window.FEATURE_NO_TITLE);
		mTtsManager = TTSController.getInstance(getApplicationContext());
		mTtsManager.init();

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

		// 設定模拟導航的行車速度
		mAMapNavi.setEmulatorNaviSpeed(75);
		sList.add(mStartLatlng);//自定義起點加入起點集合
		eList.add(mEndLatlng);//自定義終點加入終點集合
	}

	@Override
	protected void onResume() {
		super.onResume();
		mAMapNaviView.onResume();
	}

	@Override
	protected void onPause() {
		super.onPause();
		mAMapNaviView.onPause();

		// 僅僅是停止你目前在說的這句話,一會到新的路口還是會再說的
		mTtsManager.stopSpeaking();
		//
		// 停止導航之後,會觸及底層stop,然後就不會再有回調了,但是訊飛目前還是沒有說完的半句話還是會說完
		// mAMapNavi.stopNavi();
	}

	@Override
	protected void onDestroy() {
		super.onDestroy();
		mAMapNaviView.onDestroy();
		// since 1.6.0 不再在naviview destroy的時候自動執行AMapNavi.stopNavi();請自行執行
		mAMapNavi.stopNavi();
		mAMapNavi.destroy();
		mTtsManager.destroy();
	}

	@Override
	public void onInitNaviFailure() {
		Toast.makeText(this, "init navi Failed", Toast.LENGTH_SHORT).show();
	}

	@Override
	public void onInitNaviSuccess() {
		// 初始化成功
	}

	@Override
	public void onStartNavi(int type) {
		// 開始導航回調
	}

	@Override
	public void onTrafficStatusUpdate() {
		//
	}

	@Override
	public void onLocationChange(AMapNaviLocation location) {
		// 目前位置回調
	}

	@Override
	public void onGetNavigationText(int type, String text) {
		// 播報類型和播封包字回調
	}

	@Override
	public void onEndEmulatorNavi() {
		// 結束模拟導航
	}

	@Override
	public void onArriveDestination() {
		// 到達目的地
	}

	@Override
	public void onArriveDestination(NaviStaticInfo naviStaticInfo) {
		// 到達目的地,有統計資訊回調
	}

	@Override
	public void onArriveDestination(AMapNaviStaticInfo aMapNaviStaticInfo) {

	}

	@Override
	public void onCalculateRouteSuccess() {
		// 路線計算成功
	}

	@Override
	public void onCalculateRouteFailure(int errorInfo) {
		// 路線計算失敗
		Log.i("dm", "errorInfo=" + errorInfo);
		Toast.makeText(this, "錯誤資訊:" + errorInfo, Toast.LENGTH_SHORT).show();
	}

	@Override
	public void onReCalculateRouteForYaw() {
		// 偏航後重新計算路線回調
	}

	@Override
	public void onReCalculateRouteForTrafficJam() {
		// 擁堵後重新計算路線回調
	}

	@Override
	public void onArrivedWayPoint(int wayID) {
		// 到達途徑點
	}

	@Override
	public void onGpsOpenStatus(boolean enabled) {
		// GPS開關狀态回調
	}

	@Override
	public void onNaviSetting() {
		// 底部導航設定點選回調
	}

	@Override
	public void onNaviMapMode(int isLock) {
		// 地圖的模式,鎖屏或鎖車
	}

	@Override
	public void onNaviCancel() {
		finish();
	}

	@Override
	public void onNaviTurnClick() {
		// 轉彎view的點選回調
	}

	@Override
	public void onNextRoadClick() {
		// 下一個道路View點選回調
	}

	@Override
	public void onScanViewButtonClick() {
		// 全覽按鈕點選回調
	}

	@Deprecated
	@Override
	public void onNaviInfoUpdated(AMapNaviInfo naviInfo) {
		// 過時
	}

	@Override
	public void onNaviInfoUpdate(NaviInfo naviinfo) {
		// 導航過程中的資訊更新,請看NaviInfo的具體說明
	}

	@Override
	public void OnUpdateTrafficFacility(TrafficFacilityInfo trafficFacilityInfo) {
		// 已過時
	}

	@Override
	public void OnUpdateTrafficFacility(
			AMapNaviTrafficFacilityInfo aMapNaviTrafficFacilityInfo) {
		// 已過時
	}

	@Override
	public void showCross(AMapNaviCross aMapNaviCross) {
		// 顯示轉彎回調
	}

	@Override
	public void hideCross() {
		// 隐藏轉彎回調
	}

	@Override
	public void showLaneInfo(AMapLaneInfo[] laneInfos,
			byte[] laneBackgroundInfo, byte[] laneRecommendedInfo) {
		// 顯示車道資訊

	}

	@Override
	public void hideLaneInfo() {
		// 隐藏車道資訊
	}

	@Override
	public void onCalculateMultipleRoutesSuccess(int[] ints) {
		// 多路徑算路成功回調
	}

	@Override
	public void notifyParallelRoad(int i) {
		if (i == 0) {
			Toast.makeText(this, "目前在主輔路過渡", Toast.LENGTH_SHORT).show();
			Log.d("wlx", "目前在主輔路過渡");
			return;
		}
		if (i == 1) {
			Toast.makeText(this, "目前在主路", Toast.LENGTH_SHORT).show();

			Log.d("wlx", "目前在主路");
			return;
		}
		if (i == 2) {
			Toast.makeText(this, "目前在輔路", Toast.LENGTH_SHORT).show();

			Log.d("wlx", "目前在輔路");
		}
	}

	@Override
	public void OnUpdateTrafficFacility(
			AMapNaviTrafficFacilityInfo[] aMapNaviTrafficFacilityInfos) {
		// 更新交通設施資訊
	}

	@Override
	public void updateAimlessModeStatistics(AimLessModeStat aimLessModeStat) {
		// 更新巡航模式的統計資訊
	}

	@Override
	public void updateAimlessModeCongestionInfo(
			AimLessModeCongestionInfo aimLessModeCongestionInfo) {
		// 更新巡航模式的擁堵資訊
	}

	@Override
	public void onLockMap(boolean isLock) {
		// 鎖地圖狀态發生變化時回調
	}

	@Override
	public void onNaviViewLoaded() {
		Log.d("wlx", "導航頁面加載成功");
		Log.d("wlx",
				"請不要使用AMapNaviView.getMap().setOnMapLoadedListener();會overwrite導航SDK内部畫線邏輯");
	}

	@Override
	public boolean onNaviBackClick() {
		return false;
	}

}
           

          在我們自己定義的導航類中,我們需要繼承baseactivity類來實作功能,從跳轉來的頁面擷取起點和終點的經度和緯度資訊,在onInitNaviSuccess方法中清空起點和終點集合分别放入起點和終點坐标即可。給出GPSNaviActivity類代碼:

package com.example.maptest;

import android.content.Intent;
import android.os.Bundle;
import android.util.Log;

import com.amap.api.navi.AMapNaviView;
import com.amap.api.navi.enums.NaviType;
import com.amap.api.navi.model.NaviLatLng;

public class GPSNaviActivity extends BaseActivity {
	// 繼承的是baseactivity
	private double sj;
	private double sw;
	private double ej;
	private double ew;
	private String ssj;
	private String ssw;
	private String sej;
	private String sew;

	@Override
	protected void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		Intent intent = getIntent();  
		ssj = intent.getStringExtra("sj");
		sj = Double.parseDouble(ssj);
		ssw = intent.getStringExtra("sw");
		sw = Double.parseDouble(ssw);
		sej = intent.getStringExtra("ej");
		ej = Double.parseDouble(sej);
		sew = intent.getStringExtra("ew");
		ew = Double.parseDouble(sew);


		setContentView(R.layout.activity_basic_navi);
		mAMapNaviView = (AMapNaviView) findViewById(R.id.navi_view);
		mAMapNaviView.onCreate(savedInstanceState);
		mAMapNaviView.setAMapNaviViewListener(this);

	}

	@Override
	public void onInitNaviSuccess() {
		super.onInitNaviSuccess();
		/**
		 * 方法: int strategy=mAMapNavi.strategyConvert(congestion,
		 * avoidhightspeed, cost, hightspeed, multipleroute); 參數:
		 * 
		 * @congestion 躲避擁堵
		 * @avoidhightspeed 不走高速
		 * @cost 避免收費
		 * @hightspeed 高速優先
		 * @multipleroute 多路徑
		 * 
		 *                說明: 以上參數都是boolean類型,其中multipleroute參數表示是否多條路線,
		 *                如果為true則此政策會算出多條路線。 注意: 不走高速與高速優先不能同時為true
		 *                高速優先與避免收費不能同時為true
		 */
		// 重置起點
		this.sList.clear();
		this.mStartLatlng = new NaviLatLng(sw, sj);
		this.sList.add(mStartLatlng);
		// 重置了終點
		this.eList.clear();
		this.mEndLatlng = new NaviLatLng(ew, ej);
		this.eList.add(mEndLatlng);

		int strategy = 0;
		try {
			// 再次強調,最後一個參數為true時代表多路徑,否則代表單路徑
			strategy = mAMapNavi.strategyConvert(true, false, false, false,
					false);
		} catch (Exception e) {
			e.printStackTrace();
		}
		mAMapNavi.calculateDriveRoute(sList, eList, mWayPointList, strategy);

	}

	@Override
	public void onCalculateRouteSuccess() {
		super.onCalculateRouteSuccess();
		mAMapNavi.startNavi(NaviType.GPS);
	}
}
           

    在上述代碼中,我根據前一頁面傳入的起點和終點的值調用gps導航,具體原理參見代碼。

    特記下,以備後日回顧。