Android学习之使用高德地图高航

点击下载demo

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<NaviLatLng> startList = new ArrayList<NaviLatLng>();
	
	/** 终点坐标 */
	private final List<NaviLatLng> endList = new ArrayList<NaviLatLng>();
	
	/** 途经点坐标 */
	private List<NaviLatLng> mWayPointList = new ArrayList<NaviLatLng>();
	
	/** 声明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) {
	}
}

点击下载demo


评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值