MainActivity
package com.example.gaodedemo;
import android.app.Activity;
import android.content.Intent;
import android.os.Bundle;
import android.view.View;
import android.widget.Button;
public class MainActivity extends Activity implements View.OnClickListener {
/**
* 基础地图
*/
private Button mBt1;
/**
* 定位
*/
private Button mBt2;
/**
* 导航
*/
private Button mBt3;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
initView();
}
private void initView() {
mBt1 = (Button) findViewById(R.id.bt1);
mBt1.setOnClickListener(this);
mBt2 = (Button) findViewById(R.id.bt2);
mBt2.setOnClickListener(this);
mBt3 = (Button) findViewById(R.id.bt3);
mBt3.setOnClickListener(this);
}
@Override
public void onClick(View v) {
switch (v.getId()) {
default:
break;
case R.id.bt1:
//跳转到基础地图
Intent intent1 = new Intent(MainActivity.this, BasicMapActivity.class);
startActivity(intent1);
break;
case R.id.bt2:
//跳转到定位页面
Intent intent2 = new Intent(MainActivity.this, LocationActivity.class);
startActivity(intent2);
break;
case R.id.bt3:
//跳转到导航页面
Intent intent3 = new Intent(MainActivity.this,NaviActivity.class);
startActivity(intent3);
break;
}
}
}
--------------------------------------------------------------------------------------------------------------------------
NaviActivity
package com.example.gaodedemo;
import android.os.Bundle;
import android.support.v7.app.AppCompatActivity;
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.enums.NaviType;
import com.amap.api.navi.model.AMapLaneInfo;
import com.amap.api.navi.model.AMapModelCross;
import com.amap.api.navi.model.AMapNaviCameraInfo;
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.AMapServiceAreaInfo;
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;
import com.example.gaodedemo.util.TTSController;
import java.util.ArrayList;
import java.util.List;
public class NaviActivity extends AppCompatActivity implements AMapNaviListener, AMapNaviViewListener {
private AMapNavi mAMapNavi;
private final List<NaviLatLng> sList = new ArrayList<NaviLatLng>();
private final List<NaviLatLng> eList = new ArrayList<NaviLatLng>();
private AMapNaviView mAMapNaviView;
protected TTSController mTtsManager;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_navi);
mAMapNaviView = (AMapNaviView) findViewById(R.id.navi_view);
mAMapNaviView.onCreate(savedInstanceState);
mAMapNaviView.setAMapNaviViewListener(this);
//获取AMapNavi实例
mAMapNavi = AMapNavi.getInstance(getApplicationContext());
//添加监听回调,用于处理算路成功
mAMapNavi.addAMapNaviListener(this);
//添加导航声音
mAMapNavi.addAMapNaviListener(mTtsManager);
mAMapNavi.setUseInnerVoice(true);
//设置模拟导航的行车速度
mAMapNavi.setEmulatorNaviSpeed(75);
}
@Override
protected void onDestroy() {
super.onDestroy();
mAMapNavi.stopNavi();
mAMapNavi.destroy();
}
@Override
public void onInitNaviFailure() {
}
//当 AMapNavi 对象初始化成功后,会进入 onInitNaviSuccess 回调函数,在该回调函数中调用路径规划方法计算路径。
@Override
public void onInitNaviSuccess() {
int strategy=0;
try {
strategy = mAMapNavi.strategyConvert(true, false, false, false, false);
} catch (Exception e) {
e.printStackTrace();
}
sList.clear();
eList.clear();
NaviLatLng mStartLatlng = new NaviLatLng(39.894914, 116.322062);
NaviLatLng mEndLatlng = new NaviLatLng(39.903785, 116.423285);
sList.add(mStartLatlng);
eList.add(mEndLatlng);
mAMapNavi.calculateDriveRoute(sList, eList, null, strategy);
}
@Override
public void onStartNavi(int i) {
}
@Override
public void onTrafficStatusUpdate() {
}
@Override
public void onLocationChange(AMapNaviLocation aMapNaviLocation) {
}
@Override
public void onGetNavigationText(int i, String s) {
}
@Override
public void onGetNavigationText(String s) {
}
@Override
public void onEndEmulatorNavi() {
}
@Override
public void onArriveDestination() {
}
@Override
public void onCalculateRouteFailure(int i) {
}
@Override
public void onReCalculateRouteForYaw() {
}
@Override
public void onReCalculateRouteForTrafficJam() {
}
@Override
public void onArrivedWayPoint(int i) {
}
@Override
public void onGpsOpenStatus(boolean b) {
}
@Override
public void onNaviInfoUpdate(NaviInfo naviInfo) {
}
@Override
public void onNaviInfoUpdated(AMapNaviInfo aMapNaviInfo) {
}
@Override
public void updateCameraInfo(AMapNaviCameraInfo[] aMapNaviCameraInfos) {
}
@Override
public void updateIntervalCameraInfo(AMapNaviCameraInfo aMapNaviCameraInfo, AMapNaviCameraInfo
aMapNaviCameraInfo1, int i) {
}
@Override
public void onServiceAreaUpdate(AMapServiceAreaInfo[] aMapServiceAreaInfos) {
}
@Override
public void showCross(AMapNaviCross aMapNaviCross) {
}
@Override
public void hideCross() {
}
@Override
public void showModeCross(AMapModelCross aMapModelCross) {
}
@Override
public void hideModeCross() {
}
@Override
public void showLaneInfo(AMapLaneInfo[] aMapLaneInfos, byte[] bytes, byte[] bytes1) {
}
@Override
public void showLaneInfo(AMapLaneInfo aMapLaneInfo) {
}
@Override
public void hideLaneInfo() {
}
@Override
public void onCalculateRouteSuccess(int[] ints) {
//开始导航
mAMapNavi.startNavi(NaviType.EMULATOR);
}
@Override
public void notifyParallelRoad(int i) {
}
@Override
public void OnUpdateTrafficFacility(AMapNaviTrafficFacilityInfo aMapNaviTrafficFacilityInfo) {
}
@Override
public void OnUpdateTrafficFacility(AMapNaviTrafficFacilityInfo[] aMapNaviTrafficFacilityInfos) {
}
@Override
public void OnUpdateTrafficFacility(TrafficFacilityInfo trafficFacilityInfo) {
}
@Override
public void updateAimlessModeStatistics(AimLessModeStat aimLessModeStat) {
}
@Override
public void updateAimlessModeCongestionInfo(AimLessModeCongestionInfo aimLessModeCongestionInfo) {
}
@Override
public void onPlayRing(int i) {
}
@Override
public void onNaviSetting() {
}
@Override
public void onNaviCancel() {
}
@Override
public boolean onNaviBackClick() {
return false;
}
@Override
public void onNaviMapMode(int i) {
}
@Override
public void onNaviTurnClick() {
}
@Override
public void onNextRoadClick() {
}
@Override
public void onScanViewButtonClick() {
}
@Override
public void onLockMap(boolean b) {
}
@Override
public void onNaviViewLoaded() {
}
}
----------------------------------------------------------------------------------------------------------------------------
LocationActivity
package com.example.gaodedemo;
import android.os.Bundle;
import android.support.v7.app.AppCompatActivity;
import android.util.Log;
import android.view.View;
import android.widget.ImageView;
import com.amap.api.location.AMapLocation;
import com.amap.api.location.AMapLocationClient;
import com.amap.api.location.AMapLocationClientOption;
import com.amap.api.location.AMapLocationListener;
import com.amap.api.maps.AMap;
import com.amap.api.maps.CameraUpdateFactory;
import com.amap.api.maps.MapView;
import com.amap.api.maps.model.BitmapDescriptorFactory;
import com.amap.api.maps.model.LatLng;
import com.amap.api.maps.model.Marker;
import com.amap.api.maps.model.MarkerOptions;
import java.text.SimpleDateFormat;
import java.util.Date;
public class LocationActivity extends AppCompatActivity implements AMapLocationListener {
//声明aMapLocationClient类对象
public AMapLocationClient mLocationClient = null;
//声明AMapLocationClientOption对象
public AMapLocationClientOption mLocationOption = null;
private MapView mMapView = null;
private AMap aMap;
private Marker locationMarker;
private LatLng latLng;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_location);
//初始化组件
ImageView iv = findViewById(R.id.iv);
iv.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
if (latLng != null) {
aMap.animateCamera(CameraUpdateFactory.newLatLngZoom(latLng, 10));
}
}
});
//获取地图控件引用
mMapView = (MapView) findViewById(R.id.map);
//在activity执行onCreate时执行mMapView.onCreate(savedInstanceState),创建地图
mMapView.onCreate(savedInstanceState);
//初始化地图控制器对象
if (aMap == null) {
aMap = mMapView.getMap();
}
//初始化定位
mLocationClient = new AMapLocationClient(getApplicationContext());
//设置定位回调监听
mLocationClient.setLocationListener(this);
//初始化aMapLocationClientOption对象
mLocationOption = new AMapLocationClientOption();
//设置定位模式为aMapLocationMode.Hight_Accuracy,高精度模式。
mLocationOption.setLocationMode(AMapLocationClientOption.AMapLocationMode.Hight_Accuracy);
//获取一次定位结果:
//该方法默认为false。
mLocationOption.setOnceLocation(true);
//获取最近3s内精度最高的一次定位结果:
//设置setOnceLocationLatest(boolean b)接口为true,启动定位时SDK会返回最近3s内精度最高的一次定位结果。如果设置其为true,setOnceLocation(boolean b)
// 接口也会被设置为true,反之不会,默认为false。
mLocationOption.setOnceLocationLatest(true);
//设置是否返回地址信息(默认返回地址信息)
mLocationOption.setNeedAddress(true);
//给定位客户端对象设置定位参数
mLocationClient.setLocationOption(mLocationOption);
//启动定位
mLocationClient.startLocation();
}
@Override
protected void onDestroy() {
super.onDestroy();
//在activity执行onDestroy时执行mMapView.onDestroy(),销毁地图
mMapView.onDestroy();
}
@Override
protected void onResume() {
super.onResume();
//在activity执行onResume时执行mMapView.onResume (),重新绘制加载地图
mMapView.onResume();
}
@Override
protected void onPause() {
super.onPause();
//在activity执行onPause时执行mMapView.onPause (),暂停地图的绘制
mMapView.onPause();
}
@Override
protected void onSaveInstanceState(Bundle outState) {
super.onSaveInstanceState(outState);
//在activity执行onSaveInstanceState时执行mMapView.onSaveInstanceState (outState),保存地图当前的状态
mMapView.onSaveInstanceState(outState);
}
@Override
public void onLocationChanged(AMapLocation aMapLocation) {
if (aMapLocation != null) {
if (aMapLocation.getErrorCode() == 0) {
//定位获取到的用户位置
latLng = new LatLng(aMapLocation.getLatitude(), aMapLocation.getLongitude());
if (locationMarker == null) {
//添加Marker显示定位位置
locationMarker = aMap.addMarker(new MarkerOptions()
.position(latLng)
.icon(BitmapDescriptorFactory.fromResource(R.drawable.charge_has_net)));
} else {
//已经添加过了,修改位置即可
locationMarker.setPosition(latLng);
}
//然后可以移动到定位点,使用animateCamera就有动画效果
aMap.animateCamera(CameraUpdateFactory.newLatLngZoom(latLng, 10));
} else {
//定位失败时,可通过ErrCode(错误码)信息来确定失败的原因,errInfo是错误信息,详见错误码表。
Log.e("AmapError", "location Error, ErrCode:"
+ aMapLocation.getErrorCode() + ", errInfo:"
+ aMapLocation.getErrorInfo());
}
}
}
private void initView(AMapLocation aMapLocation) {
//可在其中解析aMapLocation获取相应内容。
aMapLocation.getLocationType();//获取当前定位结果来源,如网络定位结果,详见定位类型表
aMapLocation.getLatitude();//获取纬度
aMapLocation.getLongitude();//获取经度
aMapLocation.getAccuracy();//获取精度信息
aMapLocation.getAddress();//地址,如果option中设置isNeedAddress为false,则没有此结果,网络定位结果中会有地址信息,GPS定位不返回地址信息。
aMapLocation.getCountry();//国家信息
aMapLocation.getProvince();//省信息
aMapLocation.getCity();//城市信息
aMapLocation.getDistrict();//城区信息
aMapLocation.getStreet();//街道信息
aMapLocation.getStreetNum();//街道门牌号信息
aMapLocation.getCityCode();//城市编码
aMapLocation.getAdCode();//地区编码
aMapLocation.getAoiName();//获取当前定位点的AOI信息
aMapLocation.getBuildingId();//获取当前室内定位的建筑物Id
aMapLocation.getFloor();//获取当前室内定位的楼层
aMapLocation.getGpsAccuracyStatus();//获取GPS的当前状态
//获取定位时间
SimpleDateFormat df = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
Date date = new Date(aMapLocation.getTime());
df.format(date);
}
}
---------------------------------------------------------------------------------------------------------------------------------
BasicmapActivity
package com.example.gaodedemo;
import android.os.Bundle;
import android.support.v7.app.AppCompatActivity;
import android.view.View;
import android.widget.Button;
import com.amap.api.maps.AMap;
import com.amap.api.maps.MapView;
import com.amap.api.maps.model.MyLocationStyle;
public class BasicMapActivity extends AppCompatActivity implements View.OnClickListener {
private MapView mMapView;
private AMap aMap;
private MyLocationStyle myLocationStyle;
/**
* 卫星图层
*/
private Button mBtSatellite;
/**
* 夜间图层
*/
private Button mBtNight;
/**
* 路况图层
*/
private Button mBtTraffic;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_basci_map);
initView();
//获取地图控件引用
mMapView = (MapView) findViewById(R.id.map);
//在activity执行onCreate时执行mMapView.onCreate(savedInstanceState),创建地图
mMapView.onCreate(savedInstanceState);
//初始化地图控制器对象
if (aMap == null) {
aMap = mMapView.getMap();
}
myLocationStyle = new MyLocationStyle();//初始化定位蓝点样式类myLocationStyle.myLocationType(MyLocationStyle
// .LOCATION_TYPE_LOCATION_ROTATE);//连续定位、且将视角移动到地图中心点,定位点依照设备方向旋转,并且会跟随设备移动。(1秒1次定位)如果不设置myLocationType
// ,默认也会执行此种模式。
myLocationStyle.interval(2000); //设置连续定位模式下的定位间隔,只在连续定位模式下生效,单次定位模式下不会生效。单位为毫秒。
aMap.setMyLocationStyle(myLocationStyle);//设置定位蓝点的Style
//aMap.getUiSettings().setMyLocationButtonEnabled(true);设置默认定位按钮是否显示,非必需设置。
aMap.setMyLocationEnabled(true);// 设置为true表示启动显示定位蓝点,false表示隐藏定位蓝点并不进行定位,默认是false。
}
@Override
protected void onDestroy() {
super.onDestroy();
//在activity执行onDestroy时执行mMapView.onDestroy(),销毁地图
mMapView.onDestroy();
}
@Override
protected void onResume() {
super.onResume();
//在activity执行onResume时执行mMapView.onResume (),重新绘制加载地图
mMapView.onResume();
}
@Override
protected void onPause() {
super.onPause();
//在activity执行onPause时执行mMapView.onPause (),暂停地图的绘制
mMapView.onPause();
}
@Override
protected void onSaveInstanceState(Bundle outState) {
super.onSaveInstanceState(outState);
//在activity执行onSaveInstanceState时执行mMapView.onSaveInstanceState (outState),保存地图当前的状态
mMapView.onSaveInstanceState(outState);
}
private void initView() {
mBtSatellite = (Button) findViewById(R.id.btSatellite);
mBtSatellite.setOnClickListener(this);
mBtNight = (Button) findViewById(R.id.btNight);
mBtNight.setOnClickListener(this);
mBtTraffic = (Button) findViewById(R.id.btTraffic);
mBtTraffic.setOnClickListener(this);
}
@Override
public void onClick(View v) {
switch (v.getId()) {
default:
break;
case R.id.btSatellite:
aMap.setMapType(AMap.MAP_TYPE_SATELLITE);// 设置卫星地图模式,aMap是地图控制器对象。
break;
case R.id.btNight:
aMap.setMapType(AMap.MAP_TYPE_NIGHT);// 设置夜间模式,aMap是地图控制器对象。
break;
case R.id.btTraffic:
aMap.setTrafficEnabled(true);//显示实时路况图层,aMap是地图控制器对象。
break;
}
}
}
---------------------------------------------------------------------------------------------------------------------------
AliTTs
package com.example.gaodedemo.util;
/**
* 包名: com.amap.navi.demo.util
* <p>
* 创建时间:2017/12/1
* 项目名称:NaviDemo
*
* @author guibao.ggb
* @email guibao.ggb@alibaba-inc.com
* <p>
* 类说明:
*/
public class ALiTTS {
}
--------------------------------------------------------------------------------------------------------------------------------
AmapTTSControlle
package com.example.gaodedemo.util;
import android.content.Context;
import android.os.Bundle;
import android.os.Handler;
import android.os.Message;
import android.widget.Toast;
import com.amap.api.navi.AMapNavi;
import com.iflytek.cloud.ErrorCode;
import com.iflytek.cloud.InitListener;
import com.iflytek.cloud.SpeechConstant;
import com.iflytek.cloud.SpeechError;
import com.iflytek.cloud.SpeechSynthesizer;
import com.iflytek.cloud.SpeechUtility;
import com.iflytek.cloud.SynthesizerListener;
import java.util.LinkedList;
/**
* 当前DEMO的播报方式是队列模式。其原理就是依次将需要播报的语音放入链表中,播报过程是从头开始依次往后播报。
* <p>
* 导航SDK原则上是不提供语音播报模块的,如果您觉得此种播报方式不能满足你的需求,请自行优化或改进。
*/
public class AmapTTSController {
/**
* 请替换您自己申请的ID。
*/
private final String appId = "5ae17ec8";
public static AmapTTSController ttsManager;
private Context mContext;
private SpeechSynthesizer mTts;
private boolean isPlaying = false;
private LinkedList<String> wordList = new LinkedList();
private final int TTS_PLAY = 1;
private final int CHECK_TTS_PLAY = 2;
private Handler handler = new Handler() {
@Override
public void handleMessage(Message msg) {
super.handleMessage(msg);
switch (msg.what) {
case TTS_PLAY:
synchronized (mTts) {
if (!isPlaying && mTts != null && wordList.size() > 0) {
isPlaying = true;
String playtts = wordList.removeFirst();
if (mTts == null) {
createSynthesizer();
}
mTts.startSpeaking(playtts, new SynthesizerListener() {
@Override
public void onCompleted(SpeechError arg0) {
AMapNavi.setTtsPlaying(isPlaying = false);
handler.obtainMessage(1).sendToTarget();
}
@Override
public void onEvent(int arg0, int arg1, int arg2, Bundle arg3) {
}
@Override
public void onBufferProgress(int arg0, int arg1, int arg2, String arg3) {
// 合成进度
isPlaying = true;
}
@Override
public void onSpeakBegin() {
//开始播放
AMapNavi.setTtsPlaying(isPlaying = true);
}
@Override
public void onSpeakPaused() {
}
@Override
public void onSpeakProgress(int arg0, int arg1, int arg2) {
//播放进度
isPlaying = true;
}
@Override
public void onSpeakResumed() {
//继续播放
isPlaying = true;
}
});
}
}
break;
case CHECK_TTS_PLAY:
if (!isPlaying) {
handler.obtainMessage(1).sendToTarget();
}
break;
}
}
};
private AmapTTSController(Context context) {
mContext = context.getApplicationContext();
SpeechUtility.createUtility(mContext, SpeechConstant.APPID + "=" + appId);
if (mTts == null) {
createSynthesizer();
}
}
private void createSynthesizer() {
mTts = SpeechSynthesizer.createSynthesizer(mContext,
new InitListener() {
@Override
public void onInit(int errorcode) {
if (ErrorCode.SUCCESS == errorcode) {
} else {
Toast.makeText(mContext, "语音合成初始化失败!", Toast.LENGTH_SHORT);
}
}
});
}
public void init() {
//设置发音人
mTts.setParameter(SpeechConstant.VOICE_NAME, "xiaoyan");
//设置语速,值范围:[0, 100],默认值:50
mTts.setParameter(SpeechConstant.SPEED, "55");
//设置音量
mTts.setParameter(SpeechConstant.VOLUME, "tts_volume");
//设置语调
mTts.setParameter(SpeechConstant.PITCH, "tts_pitch");
}
public static AmapTTSController getInstance(Context context) {
if (ttsManager == null) {
ttsManager = new AmapTTSController(context);
}
return ttsManager;
}
public void stopSpeaking() {
if (wordList != null) {
wordList.clear();
}
if (mTts != null) {
mTts.stopSpeaking();
}
isPlaying = false;
}
public void destroy() {
if (wordList != null) {
wordList.clear();
}
if (mTts != null) {
mTts.destroy();
}
}
public void onGetNavigationText(String arg1) {
if (wordList != null)
wordList.addLast(arg1);
handler.obtainMessage(CHECK_TTS_PLAY).sendToTarget();
}
}
--------------------------------------------------------------------------------------------------------------------------
CheckPermissionActivity
/**
*
*/
package com.example.gaodedemo.util;
import android.Manifest;
import android.app.Activity;
import android.app.AlertDialog;
import android.content.DialogInterface;
import android.content.Intent;
import android.content.pm.PackageManager;
import android.net.Uri;
import android.provider.Settings;
import android.support.v4.app.ActivityCompat;
import android.support.v4.content.ContextCompat;
import android.view.KeyEvent;
import java.util.ArrayList;
import java.util.List;
/**
* 继承了Activity,实现Android6.0的运行时权限检测
* 需要进行运行时权限检测的Activity可以继承这个类
*
* @author hongming.wang
* @创建时间:2016年5月27日 下午3:01:31
* @项目名称: AMapLocationDemo
* @文件名称:PermissionsChecker.java
* @类型名称:PermissionsChecker
* @since 2.5.0
*/
public class CheckPermissionsActivity extends Activity implements ActivityCompat.OnRequestPermissionsResultCallback {
/**
* 需要进行检测的权限数组
*/
protected String[] needPermissions = {
Manifest.permission.ACCESS_COARSE_LOCATION,
Manifest.permission.ACCESS_FINE_LOCATION,
Manifest.permission.WRITE_EXTERNAL_STORAGE,
Manifest.permission.READ_EXTERNAL_STORAGE,
Manifest.permission.READ_PHONE_STATE
};
private static final int PERMISSON_REQUESTCODE = 0;
/**
* 判断是否需要检测,防止不停的弹框
*/
private boolean isNeedCheck = true;
@Override
protected void onResume() {
super.onResume();
if (isNeedCheck) {
checkPermissions(needPermissions);
}
}
/**
* @since 2.5.0
*/
private void checkPermissions(String... permissions) {
List<String> needRequestPermissonList = findDeniedPermissions(permissions);
if (null != needRequestPermissonList
&& needRequestPermissonList.size() > 0) {
ActivityCompat.requestPermissions(this,
needRequestPermissonList.toArray(
new String[needRequestPermissonList.size()]),
PERMISSON_REQUESTCODE);
}
}
/**
* 获取权限集中需要申请权限的列表
*
* @param permissions
* @return
* @since 2.5.0
*/
private List<String> findDeniedPermissions(String[] permissions) {
List<String> needRequestPermissonList = new ArrayList<String>();
for (String perm : permissions) {
if (ContextCompat.checkSelfPermission(this,
perm) != PackageManager.PERMISSION_GRANTED
|| ActivityCompat.shouldShowRequestPermissionRationale(
this, perm)) {
needRequestPermissonList.add(perm);
}
}
return needRequestPermissonList;
}
/**
* 检测是否说有的权限都已经授权
*
* @param grantResults
* @return
* @since 2.5.0
*/
private boolean verifyPermissions(int[] grantResults) {
for (int result : grantResults) {
if (result != PackageManager.PERMISSION_GRANTED) {
return false;
}
}
return true;
}
@Override
public void onRequestPermissionsResult(int requestCode,
String[] permissions, int[] paramArrayOfInt) {
if (requestCode == PERMISSON_REQUESTCODE) {
if (!verifyPermissions(paramArrayOfInt)) {
showMissingPermissionDialog();
isNeedCheck = false;
}
}
}
/**
* 显示提示信息
*
* @since 2.5.0
*/
private void showMissingPermissionDialog() {
AlertDialog.Builder builder = new AlertDialog.Builder(this);
builder.setTitle("提示");
builder.setMessage("当前应用缺少必要权限。\\n\\n请点击\\\"设置\\\"-\\\"权限\\\"-打开所需权限");
// 拒绝, 退出应用
builder.setNegativeButton("取消",
new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
finish();
}
});
builder.setPositiveButton("设置",
new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
startAppSettings();
}
});
builder.setCancelable(false);
builder.show();
}
/**
* 启动应用的设置
*
* @since 2.5.0
*/
private void startAppSettings() {
Intent intent = new Intent(
Settings.ACTION_APPLICATION_DETAILS_SETTINGS);
intent.setData(Uri.parse("package:" + getPackageName()));
startActivity(intent);
}
@Override
public boolean onKeyDown(int keyCode, KeyEvent event) {
if (keyCode == KeyEvent.KEYCODE_BACK) {
this.finish();
return true;
}
return super.onKeyDown(keyCode, event);
}
}
---------------------------------------------------------------------------------------------------------------------------
DensityUtils
package com.example.gaodedemo.util;
import android.content.Context;
import android.os.Environment;
import android.util.TypedValue;
import android.view.WindowManager;
import java.text.DecimalFormat;
import static android.content.Context.WINDOW_SERVICE;
//常用单位转换的辅助类
public class DensityUtils {
private DensityUtils() {
/* cannot be instantiated */
throw new UnsupportedOperationException("cannot be instantiated");
}
public static int dp2px(Context context, float dpVal) {
return (int) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP,
dpVal, context.getResources().getDisplayMetrics());
}
public static int sp2px(Context context, float spVal) {
return (int) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_SP,
spVal, context.getResources().getDisplayMetrics());
}
public static float px2dp(Context context, float pxVal) {
final float scale = context.getResources().getDisplayMetrics().density;
return (pxVal / scale);
}
public static float px2sp(Context context, float pxVal) {
return (pxVal / context.getResources().getDisplayMetrics().scaledDensity);
}
/**
* @return
*/
public static int getScreenWidth(Context context) {
WindowManager windowManager= (WindowManager) context.getSystemService(WINDOW_SERVICE);
int width = windowManager.getDefaultDisplay().getWidth();
return width;
}
/**
* @return
*/
public static int getScreenHeight(Context context) {
WindowManager windowManager= (WindowManager) context.getSystemService(WINDOW_SERVICE);
int height = windowManager.getDefaultDisplay().getHeight();
return height;
}
public static String convertSec2MinSp(int sec) {
String result = "";
int min = sec / 60;
int hour = 0;
if (min < 60) {
result = min + "";
} else {
hour = min / 60;
min = min % 60;
result = hour + ":" + min;
}
return result;
}
public static String convertMeter2KM(float meter) {
if(meter >= 1000) {
double dis = 0;
dis = Math.round(meter / 100d) / 10d;
DecimalFormat decimalFormat = new DecimalFormat("#0.0");//构造方法的字符格式这里如果小数不足2位,会以0补足.
String distanceString = decimalFormat.format(dis);//format 返回的是字符串
return distanceString + "公里";
}
else {
long dis = 0;
dis = Math.round(meter);
return dis+"米";
}
}
public static CharSequence convertMeter2KM_3(StringBuilder sb, float meter) {
if(sb != null){
sb.delete(0,sb.length());
}
if(meter >= 1000) {
double dis = 0;
dis = Math.round(meter / 100d) / 10d;
DecimalFormat decimalFormat = new DecimalFormat("#0.0");//构造方法的字符格式这里如果小数不足2位,会以0补足.
sb.append(decimalFormat.format(dis)).append("公里");//format 返回的是字符串
}
else {
long dis = 0;
dis = Math.round(meter);
sb.append(dis).append("米");
}
return sb;
}
public static String convertMeter2KM_2(float meter) {
double dis = 0;
dis = Math.round(meter / 100d) / 10d;
DecimalFormat decimalFormat = new DecimalFormat("#0.0");//构造方法的字符格式这里如果小数不足2位,会以0补足.
String distanceString = decimalFormat.format(dis);//format 返回的是字符串
return distanceString;
}
public static String getMusicCachePath() {
return Environment.getExternalStorageDirectory()
.getAbsolutePath() + "/LeAuto/Music/";
}
public static String convertMeter2KMNoUnit(float meter) {
double dis = 0;
dis = Math.round(meter / 10d) / 100d;
DecimalFormat decimalFormat = new DecimalFormat("#0");//构造方法的字符格式这里如果小数不足2位,会以0补足.
String distanceString = decimalFormat.format(dis);//format 返回的是字符串
return distanceString;
}
}
------------------------------------------------------------------------------------------------------------------------------
ErrorInfo
package com.example.gaodedemo.util;
import java.util.HashMap;
import java.util.Map;
/**
* -1 路径计算失败。 在导航过程中调用calculateDriveRoute方法导致的失败,导航过程中只能用reCalculate方法进行路径计算。
* 1 路径计算成功。
* 2 网络超时或网络失败,请检查网络是否通畅,稍候再试。
* 3 路径规划起点经纬度不合法,请选择国内坐标点,确保经纬度格式正常。
* 4 协议解析错误,请稍后再试。
* 6 路径规划终点经纬度不合法,请选择国内坐标点,确保经纬度格式正常。
* 7 算路服务端编码失败.
* 10 起点附近没有找到可行道路,请对起点进行调整。
* 11 终点附近没有找到可行道路,请对终点进行调整。
* 12 途经点附近没有找到可行道路,请对途经点进行调整。
* 13 key鉴权失败。 请仔细检查key绑定的sha1值与apk签名sha1值是否对应,或通过;高频问题查找相关解决办法。
* 14 请求的服务不存在, 请稍后再试。
* 15 请求服务响应错误,请检查网络状况,稍后再试。
* 16 无权限访问此服务,请稍后再试。
* 17 请求超出配额。
* 18 请求参数非法,请检查传入参数是否符合要求。
* 19 未知错误。
**/
public class ErrorInfo {
private static Map<Integer, String> list = new HashMap();
static {
list.put(-1, "路径计算失败,在导航过程中调用calculateDriveRoute方法导致的失败,导航过程中只能用reCalculate方法进行路径计算。");
list.put(1, "路径计算成功。");
list.put(2, "网络超时或网络失败,请检查网络是否通畅,如网络没问题,查看Logcat输出是否出现鉴权错误信息,如有,说明SHA1与KEY不对应导致。");
list.put(3, "路径规划起点经纬度不合法,请选择国内坐标点,确保经纬度格式正常。");
list.put(4, "协议解析错误,请稍后再试。");
list.put(6, "路径规划终点经纬度不合法,请选择国内坐标点,确保经纬度格式正常。");
list.put(7, "算路服务端编码失败.");
list.put(10, "起点附近没有找到可行道路,请对起点进行调整。");
list.put(11, "终点附近没有找到可行道路,请对终点进行调整。");
list.put(12, "途经点附近没有找到可行道路,请对途经点进行调整。");
list.put(13, "key鉴权失败,请仔细检查key绑定的sha1值与apk签名sha1值是否对应,或通过;高频问题查找相关解决办法。");
list.put(14, "请求的服务不存在,请稍后再试。");
list.put(15, "请求服务响应错误,请检查网络状况,稍后再试。");
list.put(16, "无权限访问此服务,请稍后再试。");
list.put(17, "请求超出配额。");
list.put(18, "请求参数非法,请检查传入参数是否符合要求。");
list.put(19, "未知错误。");
}
public static String getError(int id) {
return list.get(id);
}
}
------------------------------------------------------------------------------------------------------------------------------
IcallBack
package com.example.gaodedemo.util;
/**
* 创建时间:2017-9-20 下午3:37:55
* 项目名称:IndexActivity
*
* @author liqi
* @version 1.0
* @since JDK 1.6.0_21
* 文件名称:TTS.java
* 类说明:
*/
/**
* 播报回调类
*/
public interface ICallBack {
void onCompleted(int code);
}
----------------------------------------------------------------------------------------------------------------------------
IFlyTTs
package com.example.gaodedemo.util;
import android.content.Context;
import android.media.AudioManager;
import android.media.AudioManager.OnAudioFocusChangeListener;
import android.os.Bundle;
import com.iflytek.cloud.ErrorCode;
import com.iflytek.cloud.InitListener;
import com.iflytek.cloud.SpeechConstant;
import com.iflytek.cloud.SpeechError;
import com.iflytek.cloud.SpeechSynthesizer;
import com.iflytek.cloud.SpeechUtility;
import com.iflytek.cloud.SynthesizerListener;
/**
* 创建时间:2017-9-20 下午3:35:23
* 项目名称:IndexActivity
*
* @author liqi
* @version 1.0
* @since JDK 1.6.0_21
* 文件名称:MscTTS.java
* 类说明: 科大讯飞播报类
*/
public class IFlyTTS implements TTS, SynthesizerListener, OnAudioFocusChangeListener {
private static IFlyTTS iflyTTS = null;
Context mContext = null;
private boolean isPlaying = false;
private AudioManager mAm = null;
/**
* 请替换您自己申请的ID。
*/
private final String appId = "57b3c4a9";
public static IFlyTTS getInstance(Context context) {
if (iflyTTS == null) {
iflyTTS = new IFlyTTS(context);
}
return iflyTTS;
}
private IFlyTTS(Context context) {
mContext = context;
SpeechUtility.createUtility(mContext, SpeechConstant.APPID + "="
+ appId);
createSynthesizer();
mAm = (AudioManager) mContext.getSystemService(Context.AUDIO_SERVICE);
}
private SpeechSynthesizer mTts;
public void init() {
//设置发音人
mTts.setParameter(SpeechConstant.VOICE_NAME, "xiaoyan");
//设置语速,值范围:[0, 100],默认值:50
mTts.setParameter(SpeechConstant.SPEED, "55");
//设置音量
mTts.setParameter(SpeechConstant.VOLUME, "tts_volume");
//设置语调
mTts.setParameter(SpeechConstant.PITCH, "tts_pitch");
//设置与其他音频软件冲突的时候是否暂停其他音频
mTts.setParameter(SpeechConstant.KEY_REQUEST_FOCUS, "false");
//女生仅vixy支持多音字播报
mTts.setParameter(SpeechConstant.VOICE_NAME, "vixy");
}
private void createSynthesizer() {
mTts = SpeechSynthesizer.createSynthesizer(mContext,
new InitListener() {
@Override
public void onInit(int errorcode) {
if (ErrorCode.SUCCESS == errorcode) {
//初始化成功
}
}
});
}
public void playText(String playText) {
//多音字处理举例
if (playText != null && playText.contains("京藏")) {
playText = playText.replace("京藏", "京藏[=zang4]");
}
if (playText != null && playText.length() > 0) {
int result = mAm.requestAudioFocus(this,
AudioManager.STREAM_MUSIC,
AudioManager.AUDIOFOCUS_GAIN_TRANSIENT_MAY_DUCK);
if (result == AudioManager.AUDIOFOCUS_REQUEST_GRANTED) {
mTts.startSpeaking(playText, this);
isPlaying = true;
}
}
}
public void stopSpeak() {
if (mTts != null) {
mTts.stopSpeaking();
}
isPlaying = false;
}
public void destroy() {
stopSpeak();
if (mTts != null) {
mTts.destroy();
}
iflyTTS = null;
}
@Override
public void onBufferProgress(int arg0, int arg1, int arg2, String arg3) {
}
//播报是否成功以及错误码
//在音频播放完成,或会话出现错误时,将回调此函数。若为null,则没有出现错误。
@Override
public void onCompleted(SpeechError arg0) {
isPlaying = false;
if (mAm != null) {
mAm.abandonAudioFocus(this);
}
if (callBack != null) {
if (arg0 == null) {
callBack.onCompleted(0);
}
}
}
@Override
public void onEvent(int arg0, int arg1, int arg2, Bundle arg3) {
}
@Override
public void onSpeakBegin() {
isPlaying = true;
}
@Override
public void onSpeakPaused() {
isPlaying = false;
}
@Override
public void onSpeakProgress(int arg0, int arg1, int arg2) {
}
@Override
public void onSpeakResumed() {
}
@Override
public boolean isPlaying() {
return isPlaying;
}
ICallBack callBack = null;
@Override
public void setCallback(ICallBack callback) {
callBack = callback;
}
@Override
public void onAudioFocusChange(int focusChange) {
// TODO Auto-generated method stub
}
}
------------------------------------------------------------------------------------------------------------------------------
SystemTTs
package com.example.gaodedemo.util;
import android.annotation.SuppressLint;
import android.content.Context;
import android.speech.tts.TextToSpeech;
import android.speech.tts.TextToSpeech.OnUtteranceCompletedListener;
import android.speech.tts.UtteranceProgressListener;
import java.util.Locale;
/**
* 系统播报类,部分手机不支持中文播报
*/
@SuppressLint("NewApi")
public class SystemTTS extends UtteranceProgressListener implements TTS, OnUtteranceCompletedListener {
private Context mContext;
private static SystemTTS singleton;
private TextToSpeech textToSpeech; // 系统语音播报类
private boolean isSuccess = true;
public static SystemTTS getInstance(Context context) {
if (singleton == null) {
synchronized (SystemTTS.class) {
if (singleton == null) {
singleton = new SystemTTS(context);
}
}
}
return singleton;
}
private SystemTTS(Context context) {
this.mContext = context.getApplicationContext();
textToSpeech = new TextToSpeech(mContext, new TextToSpeech.OnInitListener() {
@Override
public void onInit(int i) {
//系统语音初始化成功
if (i == TextToSpeech.SUCCESS) {
int result = textToSpeech.setLanguage(Locale.CHINA);
textToSpeech.setPitch(1.0f);// 设置音调,值越大声音越尖(女生),值越小则变成男声,1.0是常规
textToSpeech.setSpeechRate(1.0f);
textToSpeech.setOnUtteranceProgressListener(SystemTTS.this);
textToSpeech.setOnUtteranceCompletedListener(SystemTTS.this);
if (result == TextToSpeech.LANG_MISSING_DATA
|| result == TextToSpeech.LANG_NOT_SUPPORTED) {
//系统不支持中文播报
isSuccess = false;
}
}
}
});
}
public void destroy() {
stopSpeak();
if (textToSpeech != null) {
textToSpeech.shutdown();
}
singleton = null;
}
public void init() {
}
public void playText(String playText) {
if (!isSuccess) {
return;
}
if (textToSpeech != null) {
textToSpeech.speak(playText,
TextToSpeech.QUEUE_ADD, null, null);
}
}
public void stopSpeak() {
if (textToSpeech != null) {
textToSpeech.stop();
}
}
@Override
public boolean isPlaying() {
return textToSpeech.isSpeaking();
}
ICallBack callBack = null;
@Override
public void setCallback(ICallBack callback) {
callBack = callback;
}
//播报完成回调
@Override
public void onUtteranceCompleted(String utteranceId) {
}
@Override
public void onStart(String utteranceId) {
}
@Override
public void onDone(String utteranceId) {
}
@Override
public void onError(String utteranceId) {
}
}
---------------------------------------------------------------------------------------------------------------------------------
TTs
package com.example.gaodedemo.util;
/**
* 创建时间:2017-9-20 下午3:37:55
* 项目名称:IndexActivity
* @author liqi
* @version 1.0
* @since JDK 1.6.0_21
* 文件名称:TTS.java
* 类说明:
*/
public interface TTS {
public void init();
public void playText(String playText);
public void stopSpeak();
public void destroy();
public boolean isPlaying();
public void setCallback(ICallBack callback);
}
-----------------------------------------------------------------------------------------------------------------------------
TTSController
package com.example.gaodedemo.util;
import android.content.Context;
import android.os.Handler;
import android.os.Message;
import com.amap.api.navi.AMapNaviListener;
import com.amap.api.navi.model.AMapLaneInfo;
import com.amap.api.navi.model.AMapModelCross;
import com.amap.api.navi.model.AMapNaviCameraInfo;
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.AMapServiceAreaInfo;
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 java.util.LinkedList;
/**
* 当前DEMO的播报方式是队列模式。其原理就是依次将需要播报的语音放入链表中,播报过程是从头开始依次往后播报。
* <p>
* 导航SDK原则上是不提供语音播报模块的,如果您觉得此种播报方式不能满足你的需求,请自行优化或改进。
*/
public class TTSController implements AMapNaviListener, ICallBack {
@Override
public void onCompleted(int code) {
if (handler != null) {
handler.obtainMessage(1).sendToTarget();
}
}
public static enum TTSType {
/**
* 讯飞语音
*/
IFLYTTS,
/**
* 系统语音
*/
SYSTEMTTS;
}
public static TTSController ttsManager;
private Context mContext;
private TTS tts = null;
private SystemTTS systemTTS;
private IFlyTTS iflyTTS = null;
private LinkedList<String> wordList = new LinkedList<String>();
private final int TTS_PLAY = 1;
private final int CHECK_TTS_PLAY = 2;
private Handler handler = new Handler() {
@Override
public void handleMessage(Message msg) {
super.handleMessage(msg);
switch (msg.what) {
case TTS_PLAY:
if (tts != null && wordList.size() > 0) {
tts.playText(wordList.removeFirst());
}
break;
case CHECK_TTS_PLAY:
if (!tts.isPlaying()) {
handler.obtainMessage(1).sendToTarget();
}
break;
}
}
};
public void setTTSType(TTSType type) {
if (type == TTSType.SYSTEMTTS) {
tts = systemTTS;
} else {
tts = iflyTTS;
}
tts.setCallback(this);
}
private TTSController(Context context) {
mContext = context.getApplicationContext();
systemTTS = SystemTTS.getInstance(mContext);
iflyTTS = IFlyTTS.getInstance(mContext);
tts = iflyTTS;
}
public void init() {
if (systemTTS != null) {
systemTTS.init();
}
if (iflyTTS != null) {
iflyTTS.init();
}
tts.setCallback(this);
}
public static TTSController getInstance(Context context) {
if (ttsManager == null) {
ttsManager = new TTSController(context);
}
return ttsManager;
}
public void stopSpeaking() {
if (systemTTS != null) {
systemTTS.stopSpeak();
}
if (iflyTTS != null) {
iflyTTS.stopSpeak();
}
wordList.clear();
}
public void destroy() {
if (systemTTS != null) {
systemTTS.destroy();
}
if (iflyTTS != null) {
iflyTTS.destroy();
}
ttsManager = null;
}
/****************************************************************************
* 以下都是导航相关接口
****************************************************************************/
@Override
public void onArriveDestination() {
}
@Override
public void onArrivedWayPoint(int arg0) {
}
@Override
public void onCalculateRouteFailure(int arg0) {
if (wordList != null)
wordList.addLast("路线规划失败");
}
@Override
public void onEndEmulatorNavi() {
}
@Override
public void onGetNavigationText(int arg0, String arg1) {
}
@Override
public void onInitNaviFailure() {
}
@Override
public void onInitNaviSuccess() {
}
@Override
public void onLocationChange(AMapNaviLocation arg0) {
}
@Override
public void onReCalculateRouteForTrafficJam() {
if (wordList != null)
wordList.addLast("前方路线拥堵,路线重新规划");
}
@Override
public void onReCalculateRouteForYaw() {
if (wordList != null)
wordList.addLast("路线重新规划");
}
@Override
public void onStartNavi(int arg0) {
}
@Override
public void onTrafficStatusUpdate() {
}
@Override
public void onGpsOpenStatus(boolean enabled) {
}
@Override
public void onNaviInfoUpdate(NaviInfo naviinfo) {
}
@Override
public void onNaviInfoUpdated(AMapNaviInfo aMapNaviInfo) {
}
@Override
public void updateCameraInfo(AMapNaviCameraInfo[] infoArray) {
}
@Override
public void onServiceAreaUpdate(AMapServiceAreaInfo[] infoArray) {
}
@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 onCalculateRouteSuccess(int[] routeIds) {
}
@Override
public void notifyParallelRoad(int parallelRoadType) {
}
@Override
public void OnUpdateTrafficFacility(AMapNaviTrafficFacilityInfo aMapNaviTrafficFacilityInfo) {
}
@Override
public void OnUpdateTrafficFacility(AMapNaviTrafficFacilityInfo[] infos) {
}
@Override
public void updateAimlessModeStatistics(AimLessModeStat aimLessModeStat) {
}
@Override
public void updateAimlessModeCongestionInfo(AimLessModeCongestionInfo aimLessModeCongestionInfo) {
}
@Override
public void onPlayRing(int type) {
}
@Override
public void onGetNavigationText(String playText) {
if (wordList != null)
wordList.addLast(playText);
handler.obtainMessage(CHECK_TTS_PLAY).sendToTarget();
}
@Override
@Deprecated
public void OnUpdateTrafficFacility(TrafficFacilityInfo arg0) {
}
@Override
public void showModeCross(AMapModelCross aMapModelCross) {
}
@Override
public void hideModeCross() {
}
@Override
public void updateIntervalCameraInfo(AMapNaviCameraInfo aMapNaviCameraInfo, AMapNaviCameraInfo aMapNaviCameraInfo1, int i) {
}
@Override
public void showLaneInfo(AMapLaneInfo aMapLaneInfo) {
}
}