Android教程網
  1. 首頁
  2. Android 技術
  3. Android 手機
  4. Android 系統教程
  5. Android 游戲
 Android教程網 >> Android技術 >> 關於Android編程 >> Android學習之使用高德地圖高航

Android學習之使用高德地圖高航

編輯:關於Android編程

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

import org.json.JSONArray;
import org.json.JSONObject;

import android.annotation.SuppressLint;
import android.app.Activity;
import android.os.Bundle;
import android.os.Handler;
import android.util.Log;
import android.widget.FrameLayout;
import android.widget.FrameLayout.LayoutParams;
import android.widget.Toast;

import com.amap.api.location.AMapLocation;
import com.amap.api.location.AMapLocationClient;
import com.amap.api.location.AMapLocationClientOption;
import com.amap.api.location.AMapLocationClientOption.AMapLocationMode;
import com.amap.api.location.AMapLocationListener;
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.AMapNaviViewOptions;
import com.amap.api.navi.enums.NaviType;
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.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.autonavi.tbt.TrafficFacilityInfo;

/**
 * 高德地圖導航Activity
 *
 */
@SuppressWarnings("deprecation")
public class AmapNaviActivity extends Activity implements AMapNaviListener,
		AMapNaviViewListener, AMapLocationListener {

	private static final String TAG = AmapNaviActivity.class.getName();	
	
	/** 3D導航地圖對象 */
	private AMapNaviView mAMapNaviView;
	
	/** 導航對象 */
	private AMapNavi mAMapNavi;
	
	/** 語音對象 */
	private TTSController mTtsManager;
	
	/** 起點坐標 */
	private final List startList = new ArrayList();
	
	/** 終點坐標 */
	private final List endList = new ArrayList();
	
	/** 途經點坐標 */
	private List mWayPointList = new ArrayList();
	
	/** 聲明mLocationOption對象 */
	private AMapLocationClientOption mLocationOption = null;
	
	/** 聲明mlocationClient對象 */
	private AMapLocationClient mlocationClient = null;
	
	/** 導航方式 */
	private NaviWay naviWay;
	
	/** 導航參數 */
	private JSONArray naviData;
	
	/** 線程句柄 */
	private Handler handler = new Handler();
	
	@Override
	protected void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		
		mAMapNaviView = new AMapNaviView(this);
		FrameLayout.LayoutParams layoutParams = new FrameLayout.LayoutParams(LayoutParams.MATCH_PARENT, LayoutParams.MATCH_PARENT);
		mAMapNaviView.setLayoutParams(layoutParams);
		setContentView(mAMapNaviView);
		
		naviWay = (NaviWay) getIntent().getSerializableExtra(AMapNaviPlugin.NAVI_WAY);
		try {
			naviData = new JSONArray(getIntent().getStringExtra(AMapNaviPlugin.NAVI_DATA));
		} catch (Exception e) {
			Log.e(TAG, e.getMessage());
			finish();
		}
		
		initNaviData();
		try { 
			// 起點坐標為空,則獲取設備當前坐標作為起點
			JSONObject startPos = naviData.getJSONObject(0);
			startList.add(new NaviLatLng(startPos.optDouble("latitude"), startPos.optDouble("longitude"))); 
			initNavi();
		} catch (Exception e) {
			// 使用定位,獲取當前坐標
			Log.i(TAG, "起點坐標為空,獲取設備定位坐標作為起點.");
			initLocation();
		}
		
		mAMapNaviView.onCreate(savedInstanceState);
		setAmapNaviViewOptions();
		mAMapNaviView.setAMapNaviViewListener(this);
	}

	/**
	 * 初始化導航起始點、途經點參數
	 */
	public void initNaviData() {
		JSONObject endPos = null;
		if (naviWay == AMapNaviPlugin.NaviWay.WALK) { 
			// 步行導航方式
			endPos = naviData.optJSONObject(1);
			endList.add(new NaviLatLng(endPos.optDouble("latitude"), endPos.optDouble("longitude"))); 
		} else {
			// 駕車導航方式
			endPos = naviData.optJSONObject(2);
			endList.add(new NaviLatLng(endPos.optDouble("latitude"), endPos.optDouble("longitude"))); 
			// 途經點,最多設置3個
			JSONArray wayPosArray = naviData.optJSONArray(1) == null ? new JSONArray() : naviData.optJSONArray(1);
			int length = wayPosArray.length() > 3 ? 3 : wayPosArray.length();
			for (int i = 0; i < length; i++) {
				JSONObject wayPos = naviData.optJSONObject(i);
				mWayPointList.add(new NaviLatLng(wayPos.optDouble("latitude"), wayPos.optDouble("longitude"))); 
			}
		}
	}
	
	/**
	 * 初始化導航
	 */
	public void initNavi() {
		// 實例化語音引擎
		mTtsManager = TTSController.getInstance(getApplicationContext());
		mTtsManager.init();
		mTtsManager.startSpeaking();

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

		// 設置模擬導航的行車速度
		mAMapNavi.setEmulatorNaviSpeed(75);
	}
	
	/**
	 * 設置導航參數
	 */
	private void setAmapNaviViewOptions() {
	    if (mAMapNaviView == null) {
	        return;
	    }
		AMapNaviViewOptions viewOptions = new AMapNaviViewOptions();
		// viewOptions.setTilt(0); // 0 表示使用2D地圖
		// viewOptions.setSettingMenuEnabled(true);//設置菜單按鈕是否在導航界面顯示
		// viewOptions.setNaviNight(mDayNightFlag);//設置導航界面是否顯示黑夜模式
		viewOptions.setReCalculateRouteForYaw(true);// 設置偏航時是否重新計算路徑mDeviationFlag
		// viewOptions.setReCalculateRouteForTrafficJam(mJamFlag);//前方擁堵時是否重新計算路徑
		// viewOptions.setTrafficInfoUpdateEnabled(mTrafficFlag);//設置交通播報是否打開
		// viewOptions.setCameraInfoUpdateEnabled(mCameraFlag);//設置攝像頭播報是否打開
		// viewOptions.setScreenAlwaysBright(mScreenFlag);//設置導航狀態下屏幕是否一直開啟。
		// viewOptions.setNaviViewTopic(mThemeStle);//設置導航界面的主題
	    mAMapNaviView.setViewOptions(viewOptions);
	}

	/**
	 * 獲取定位坐標
	 */
	public void initLocation() {
		mlocationClient = new AMapLocationClient(this);
		//初始化定位參數
		mLocationOption = new AMapLocationClientOption();
		//設置定位監聽
		mlocationClient.setLocationListener(this);
		//設置定位模式為高精度模式,Battery_Saving為低功耗模式,Device_Sensors是僅設備模式
		mLocationOption.setLocationMode(AMapLocationMode.Hight_Accuracy);
		//設置是否只定位一次,默認為false
		mLocationOption.setOnceLocation(true);
		//設置setOnceLocationLatest(boolean b)接口為true,啟動定位時SDK會返回最近3s內精度最高的一次定位結果。
		//如果設置其為true,setOnceLocation(boolean b)接口也會被設置為true,反之不會。
		mLocationOption.setOnceLocationLatest(true);
		//設置定位間隔,單位毫秒,默認為2000ms
		mLocationOption.setInterval(2000);
		//設置定位參數
		mlocationClient.setLocationOption(mLocationOption);
		// 此方法為每隔固定時間會發起一次定位請求,為了減少電量消耗或網絡流量消耗,
		// 注意設置合適的定位時間的間隔(最小間隔支持為2000ms),並且在合適時間調用stopLocation()方法來取消定位請求
		// 在定位結束後,在合適的生命周期調用onDestroy()方法
		// 在單次定位情況下,定位無論成功與否,都無需調用stopLocation()方法移除請求,定位sdk內部會移除
		//啟動定位
		mlocationClient.startLocation();
	}

	/**
	 * 定位回調接口實現 
	 */
	@SuppressLint("SimpleDateFormat")
	@Override
	public void onLocationChanged(AMapLocation amapLocation) {
		if (amapLocation != null) {
	        if (amapLocation.getErrorCode() == 0) {
		        //定位成功回調信息,設置相關消息
		        startList.add(new NaviLatLng(amapLocation.getLatitude(), amapLocation.getLongitude())); 
		        initNavi();
		        onInitNaviSuccess();
		    } else {
		        //顯示錯誤信息ErrCode是錯誤碼,errInfo是錯誤信息,詳見錯誤碼表。
		        Log.e("AmapError","location Error, ErrCode:" + amapLocation.getErrorCode() + 
		        		", errInfo:" + amapLocation.getErrorInfo());
		        Toast.makeText(AmapNaviActivity.this, "location Error, ErrCode:" + amapLocation.getErrorCode() + 
		        		", errInfo:" + amapLocation.getErrorInfo(), Toast.LENGTH_LONG).show();
		    }
	    }
	}

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

	@Override
	protected void onPause() {
		super.onPause();
		try {
			mAMapNaviView.onPause();
			// 僅僅是停止你當前在說的這句話,一會到新的路口還是會再說的
			mTtsManager.stopSpeaking();
			// 停止導航之後,會觸及底層stop,然後就不會再有回調了,但是訊飛當前還是沒有說完的半句話還是會說完
			// mAMapNavi.stopNavi();
		} catch (Exception e) {
		}
	}

	@Override
	protected void onDestroy() {
		super.onDestroy();
		try {
			mAMapNaviView.onDestroy();
			// since 1.6.0 不再在naviview destroy的時候自動執行AMapNavi.stopNavi();請自行執行
			mAMapNavi.stopNavi();
			mAMapNavi.destroy();
			mTtsManager.destroy();
			if (null != mlocationClient) {
				/**
				 * 如果AMapLocationClient是在當前Activity實例化的,
				 * 在Activity的onDestroy中一定要執行AMapLocationClient的onDestroy
				 */
				mlocationClient.onDestroy();
				mlocationClient = null;
				mLocationOption = null;
			}
		} catch (Exception e) {
		}
	}

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

	@Override
	public void onInitNaviSuccess() {
		/**
		 * 方法: int strategy=mAMapNavi.strategyConvert(congestion,
		 * avoidhightspeed, cost, hightspeed, multipleroute); 參數:
		 * 
		 * @congestion 躲避擁堵
		 * @avoidhightspeed 不走高速
		 * @cost 避免收費
		 * @hightspeed 高速優先
		 * @multipleroute 多路徑
		 * 
		 * 	說明:
		 *		以上參數都是boolean類型,其中multipleroute參數表示是否多條路線,如果為true則此策略會算出多條路線。
		 *		注意: 不走高速與高速優先不能同時為true 高速優先與避免收費不能同時為true
		 */
		int strategy = 0;
		try {
			strategy = mAMapNavi.strategyConvert(true, false, false, false, false);
		} catch (Exception e) {
			e.printStackTrace();
		}
		if(naviWay == AMapNaviPlugin.NaviWay.WALK) {
			mAMapNavi.calculateWalkRoute(startList.get(0), endList.get(0)); // 步行導航
		} else {
			mAMapNavi.calculateDriveRoute(startList, endList, mWayPointList, strategy);
		}
	}

	@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 onCalculateRouteSuccess() {
		Log.i(TAG, "路徑規劃完畢,開始導航.");
		handler.postDelayed(new Runnable() {
			
			@Override
			public void run() {
				boolean naviType = true; // true表示模擬導航,false表示真實GPS導航(默認true)
				if(naviWay == AMapNaviPlugin.NaviWay.WALK) {
					naviType = naviData.optBoolean(2, true);
				} else {
					naviType = naviData.optBoolean(3, true);
				}
				if(naviType) {
					mAMapNavi.startNavi(NaviType.EMULATOR);
				} else {
					mAMapNavi.startNavi(NaviType.GPS);
				}				
			}
		}, 3000);
	}

	@Override
	public void onCalculateRouteFailure(int errorInfo) {
		Toast.makeText(AmapNaviActivity.this, "onCalculateRouteFailure code : " + errorInfo, Toast.LENGTH_LONG).show();
	}

	@Override
	public void onReCalculateRouteForYaw() {
	}

	@Override
	public void onReCalculateRouteForTrafficJam() {
	}

	@Override
	public void onArrivedWayPoint(int wayID) {
	}

	@Override
	public void onGpsOpenStatus(boolean enabled) {
	}

	@Override
	public void onNaviSetting() {
	}

	@Override
	public void onNaviMapMode(int isLock) {
	}

	/**
	 * 導航結束
	 */
	@Override
	public void onNaviCancel() {
		Log.i(TAG, "導航結束.");
		finish();
	}

	@Override
	public void onNaviTurnClick() {
	}

	@Override
	public void onNextRoadClick() {
	}

	@Override
	public void onScanViewButtonClick() {
	}

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

	@Override
	public void onNaviInfoUpdate(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) {
	}

	@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;
	}
}

import android.content.Context;
import android.os.Bundle;

import com.amap.api.navi.AMapNaviListener;
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.AMapNaviTrafficFacilityInfo;
import com.amap.api.navi.model.AimLessModeCongestionInfo;
import com.amap.api.navi.model.AimLessModeStat;
import com.amap.api.navi.model.NaviInfo;
import com.autonavi.tbt.TrafficFacilityInfo;
import com.iflytek.cloud.speech.SpeechError;
import com.iflytek.cloud.speech.SpeechListener;
import com.iflytek.cloud.speech.SpeechSynthesizer;
import com.iflytek.cloud.speech.SpeechUser;
import com.iflytek.cloud.speech.SynthesizerListener;

/**
 * 導航語音播報(訊飛)
 *
 */
@SuppressWarnings("deprecation")
public class TTSController implements SynthesizerListener, AMapNaviListener {

	public static TTSController ttsManager;
	boolean isfinish = true;
	private Context mContext;
	// 合成對象.
	private SpeechSynthesizer mSpeechSynthesizer;
	/**
	 * 用戶登錄回調監聽器.
	 */
	private SpeechListener listener = new SpeechListener() {

		@Override
		public void onData(byte[] arg0) {
		}

		@Override
		public void onCompleted(SpeechError error) {
			if (error != null) {
			}
		}

		@Override
		public void onEvent(int arg0, Bundle arg1) {
		}
	};

	TTSController(Context context) {
		mContext = context;
	}

	public static TTSController getInstance(Context context) {
		if (ttsManager == null) {
			ttsManager = new TTSController(context);
		}
		return ttsManager;
	}

	public void init() {
		SpeechUser.getUser().login(mContext, null, null, "appid=" + "輸入您訊飛的appid", listener);
		// 初始化合成對象.
		mSpeechSynthesizer = SpeechSynthesizer.createSynthesizer(mContext);
		initSpeechSynthesizer();
	}

	/**
	 * 使用SpeechSynthesizer合成語音,不彈出合成Dialog.
	 * 
	 * @param
	 */
	public void playText(String playText) {
		if (!isfinish) {
			return;
		}
		if (null == mSpeechSynthesizer) {
			// 創建合成對象.
			mSpeechSynthesizer = SpeechSynthesizer.createSynthesizer(mContext);
			initSpeechSynthesizer();
		}
		// 進行語音合成.
		mSpeechSynthesizer.startSpeaking(playText, this);
	}

	public void stopSpeaking() {
		if (mSpeechSynthesizer != null) {
			mSpeechSynthesizer.stopSpeaking();
		}
	}

	public void startSpeaking() {
		isfinish = true;
	}

	private void initSpeechSynthesizer() {
//		// 設置發音人
//		mSpeechSynthesizer.setParameter(SpeechConstant.VOICE_NAME, "xiaoyan");
//		// 設置語速
//		mSpeechSynthesizer.setParameter(SpeechConstant.SPEED, "tts_speed");
//		// 設置音量
//		mSpeechSynthesizer.setParameter(SpeechConstant.VOLUME, "tts_volume");
//		// 設置語調
//		mSpeechSynthesizer.setParameter(SpeechConstant.PITCH, "tts_pitch");
	}

	@Override
	public void onBufferProgress(int arg0, int arg1, int arg2, String arg3) {
	}

	@Override
	public void onCompleted(SpeechError arg0) {
		isfinish = true;
	}

	@Override
	public void onSpeakBegin() {
		isfinish = false;
	}

	@Override
	public void onSpeakPaused() {
	}

	@Override
	public void onSpeakProgress(int arg0, int arg1, int arg2) {
	}

	@Override
	public void onSpeakResumed() {
	}

	public void destroy() {
		if (mSpeechSynthesizer != null) {
			mSpeechSynthesizer.stopSpeaking();
		}
	}

	@Override
	public void onArriveDestination() {
		this.playText("到達目的地");
	}

	@Override
	public void onArrivedWayPoint(int arg0) {
	}

	@Override
	public void onCalculateRouteFailure(int arg0) {
		this.playText("路徑計算失敗,請檢查網絡或輸入參數");
	}

	@Override
	public void onCalculateRouteSuccess() {
		String calculateResult = "路徑計算就緒";
		this.playText(calculateResult);
	}

	@Override
	public void onEndEmulatorNavi() {
		this.playText("導航結束");
	}

	@Override
	public void onGetNavigationText(int arg0, String arg1) {
		this.playText(arg1);
	}

	@Override
	public void onInitNaviFailure() {
	}

	@Override
	public void onInitNaviSuccess() {
	}

	@Override
	public void onLocationChange(AMapNaviLocation arg0) {
	}

	@Override
	public void onReCalculateRouteForTrafficJam() {
		this.playText("前方路線擁堵,路線重新規劃");
	}

	@Override
	public void onReCalculateRouteForYaw() {
		this.playText("您已偏航");
	}

	@Override
	public void onStartNavi(int arg0) {
	}

	@Override
	public void onTrafficStatusUpdate() {
	}

	@Override
	public void onGpsOpenStatus(boolean arg0) {
	}

	@Override
	public void onNaviInfoUpdated(AMapNaviInfo arg0) {
	}

	@Override
	public void onNaviInfoUpdate(NaviInfo arg0) {
	}

	@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[] aMapLaneInfos, byte[] bytes, byte[] bytes1) {
	}

	@Override
	public void hideLaneInfo() {
	}

	@Override
	public void onCalculateMultipleRoutesSuccess(int[] ints) {
	}

	@Override
	public void notifyParallelRoad(int i) {
	}

	@Override
	public void OnUpdateTrafficFacility(AMapNaviTrafficFacilityInfo[] aMapNaviTrafficFacilityInfos) {
	}

	@Override
	public void updateAimlessModeStatistics(AimLessModeStat aimLessModeStat) {
	}

	@Override
	public void updateAimlessModeCongestionInfo(AimLessModeCongestionInfo aimLessModeCongestionInfo) {
	}
}


  1. 上一頁:
  2. 下一頁:
熱門文章
閱讀排行版
Copyright © Android教程網 All Rights Reserved