Android 高德地图定位和导航

1. 在高德开放平台注册帐号

2.在高德地图开发平台中下载Android平台下载地图SDK和定位SDK和导航SDK文件

3. 添加jar包,将jar包放入工程的libs目录下。 (下载的三合一的SDK,只需下载自己需要的SDK)


4. 申请API KEY  高德地图开发平台进入控制台 生成自己得key

一:基础地图显示

1.添加用户key 在工程的“ AndroidManifest.xml ”文件如下代码中添加您的用户 Key。

<application
    android:allowBackup="true"
    android:icon="@mipmap/ic_launcher"
    android:label="@string/app_name"
    android:roundIcon="@mipmap/ic_launcher_round"
    android:supportsRtl="true"
    android:theme="@style/AppTheme">
    <activity android:name=".MainActivity">
        <intent-filter>
            <action android:name="android.intent.action.MAIN" />

            <category android:name="android.intent.category.LAUNCHER" />
        </intent-filter>
    </activity>
    <!-- 基础地图 -->
    <meta-data
        android:name="com.amap.api.v2.apikey"
        android:value="key" />
    <!-- 定位 -->
    <service android:name="com.amap.api.location.APSService" />
    <!-- 导航 -->
    <activity android:name="com.amap.api.navi.AmapRouteActivity"
        android:theme="@android:style/Theme.NoTitleBar"
        android:configChanges="orientation|keyboardHidden|screenSize" />

2.添加所需权限

<!--地图SDK(包含其搜索功能)需要的基础权限-->
<!--允许程序打开网络套接字-->
<uses-permission android:name="android.permission.INTERNET" />
<!--允许程序设置内置sd卡的写权限-->
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
<!--允许程序获取网络状态-->
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
<!--允许程序访问WiFi网络信息-->
<uses-permission android:name="android.permission.ACCESS_WIFI_STATE" />
<!--允许程序读写手机状态和身份-->
<uses-permission android:name="android.permission.READ_PHONE_STATE" />
<!--允许程序访问CellIDWiFi热点来获取粗略的位置-->
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />

3.在布局xml文件中添加地图控件。

<com.amap.api.maps.MapView
    android:id="@+id/map_view"
    android:layout_width="match_parent"
    android:layout_height="match_parent" />

4.创建地图Activity,管理地图生命周期。

public class Basicmap extends AppCompatActivity {
    private MapView mMapView = null;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_basicmap);
        //获取地图控件引用
        mMapView = (MapView) findViewById(R.id.map_view);
        //activity执行onCreate时执行mMapView.onCreate(savedInstanceState),实现地图生命周期管理
        mMapView.onCreate(savedInstanceState);

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

二:定位地图

1.配置AndroidManifest.xml中application标签中声明service组件,每个app拥有自己单独的定位service。(在基础地图的配置文件中已给出)

2.接下来声明使用权限(和基础地图有重复的可以自行删除)

<!--用于进行网络定位-->
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION"/>
<!--用于访问GPS定位-->
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION"/>
<!--用于获取运营商信息,用于支持提供运营商信息相关的接口-->
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE"/>
<!--用于访问wifi网络信息,wifi信息会用于进行网络定位-->
<uses-permission android:name="android.permission.ACCESS_WIFI_STATE"/>
<!--用于获取wifi的获取权限,wifi信息会用来进行网络定位-->
<uses-permission android:name="android.permission.CHANGE_WIFI_STATE"/>
<!--用于访问网络,网络定位需要上网-->
<uses-permission android:name="android.permission.INTERNET"/>
<!--用于读取手机当前的状态-->
<uses-permission android:name="android.permission.READ_PHONE_STATE"/>
<!--用于写入缓存数据到扩展存储卡-->
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
<!--用于申请调用A-GPS模块-->
<uses-permission android:name="android.permission.ACCESS_LOCATION_EXTRA_COMMANDS"/>
<!--用于申请获取蓝牙信息进行室内定位-->
<uses-permission android:name="android.permission.BLUETOOTH"/>
<uses-permission android:name="android.permission.BLUETOOTH_ADMIN"/>
3.启动定位功能
public class Locationmap extends AppCompatActivity implements LocationSource,AMapLocationListener {

    private MapView mMapView = null;
    private AMap aMap = null;
    private OnLocationChangedListener mListener = null;
    private AMapLocationClient mLocationClient = null;
    private boolean isFirstLoc = true;
    private int ACCESS_COARSE_LOCATION_CODE = 1;
    private int ACCESS_FINE_LOCATION_CODE = 2;
    private int WRITE_EXTERNAL_STORAGE_CODE = 3;
    private int READ_EXTERNAL_STORAGE_CODE = 4;
    private int READ_PHONE_STATE_CODE = 5;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_locationmap);

        //获取地图控件引用
        mMapView = (MapView) findViewById(R.id.map_view);
        //activity执行onCreate时执行mMapView.onCreate(savedInstanceState),实现地图生命周期管理
        mMapView.onCreate(savedInstanceState);

        //SDKAndroid 6.0下需要进行运行检测的权限如下:
        if (ContextCompat.checkSelfPermission(this, Manifest.permission.ACCESS_COARSE_LOCATION) != PackageManager.PERMISSION_GRANTED) {
            //申请WRITE_EXTERNAL_STORAGE权限
            ActivityCompat.requestPermissions(this, new String[]{Manifest.permission.ACCESS_COARSE_LOCATION}, ACCESS_COARSE_LOCATION_CODE);
        } else if (ContextCompat.checkSelfPermission(this, Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED) {
            ActivityCompat.requestPermissions(this, new String[]{Manifest.permission.ACCESS_FINE_LOCATION}, ACCESS_FINE_LOCATION_CODE);
        } else if (ContextCompat.checkSelfPermission(this, Manifest.permission.WRITE_EXTERNAL_STORAGE) != PackageManager.PERMISSION_GRANTED) {
            ActivityCompat.requestPermissions(this, new String[]{Manifest.permission.WRITE_EXTERNAL_STORAGE}, WRITE_EXTERNAL_STORAGE_CODE);
        } else if (ContextCompat.checkSelfPermission(this, Manifest.permission.READ_EXTERNAL_STORAGE) != PackageManager.PERMISSION_GRANTED) {
            ActivityCompat.requestPermissions(this, new String[]{Manifest.permission.READ_EXTERNAL_STORAGE}, READ_EXTERNAL_STORAGE_CODE);
        } else if (ContextCompat.checkSelfPermission(this, Manifest.permission.READ_PHONE_STATE) != PackageManager.PERMISSION_GRANTED) {
            ActivityCompat.requestPermissions(this, new String[]{Manifest.permission.READ_PHONE_STATE}, READ_PHONE_STATE_CODE);
        }

        if (aMap == null) {
            aMap = mMapView.getMap();
            //设置显示定位按钮 并且可以点击
            UiSettings settings = aMap.getUiSettings();
            aMap.setLocationSource(this);//设置了定位的监听,这里要实现LocationSource接口
            // 是否显示定位按钮
            settings.setMyLocationButtonEnabled(true);
            aMap.setMyLocationEnabled(true);//显示定位层并且可以触发定位,默认是flase
        }

        //初始化定位
        mLocationClient = new AMapLocationClient(getApplicationContext());
        //设置定位回调监听,这里要实现AMapLocationListener接口,AMapLocationListener接口只有onLocationChanged方法可以实现,用于接收异步返回的定位结果,参数是AMapLocation类型。
        mLocationClient.setLocationListener(this);
        //初始化定位参数
        AMapLocationClientOption mLocationOption = new AMapLocationClientOption();
        //设置定位模式为Hight_Accuracy高精度模式,Battery_Saving为低功耗模式,Device_Sensors是仅设备模式
        mLocationOption.setLocationMode(AMapLocationClientOption.AMapLocationMode.Hight_Accuracy);
        //设置是否返回地址信息(默认返回地址信息)
        mLocationOption.setNeedAddress(true);
        //设置是否只定位一次,默认为false
        mLocationOption.setOnceLocation(false);
        //设置是否强制刷新WIFI,默认为强制刷新
        mLocationOption.setWifiActiveScan(true);
        //设置是否允许模拟位置,默认为false,不允许模拟位置
        mLocationOption.setMockEnable(false);
        //设置定位间隔,单位毫秒,默认为2000ms
        mLocationOption.setInterval(2000);
        //给定位客户端对象设置定位参数
        mLocationClient.setLocationOption(mLocationOption);
        //启动定位
        mLocationClient.startLocation();

    }
    @Override
    protected void onDestroy() {
        super.onDestroy();
        //activity执行onDestroy时执行mMapView.onDestroy(),实现地图生命周期管理
        mMapView.onDestroy();
        mLocationClient.stopLocation();//停止定位
        mLocationClient.onDestroy();//销毁定位客户端。
        //销毁定位客户端之后,若要重新开启定位请重新New一个AMapLocationClient对象。
    }
    @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 activate(OnLocationChangedListener onLocationChangedListener) {
        mListener = onLocationChangedListener;
    }

    @Override
    public void deactivate() {
        mListener = null;
    }

    @Override
    public void onLocationChanged(AMapLocation aMapLocation) {
        if (aMapLocation != null) {
            if (aMapLocation.getErrorCode() == 0) {
                //定位成功回调信息,设置相关消息
                aMapLocation.getLocationType();//获取当前定位结果来源,如网络定位结果,详见官方定位类型表
                aMapLocation.getLatitude();//获取纬度
                aMapLocation.getLongitude();//获取经度
                aMapLocation.getAccuracy();//获取精度信息
                SimpleDateFormat df = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
                Date date = new Date(aMapLocation.getTime());
                df.format(date);//定位时间
                aMapLocation.getAddress();//地址,如果option中设置isNeedAddressfalse,则没有此结果,网络定位结果中会有地址信息,GPS定位不返回地址信息。
                aMapLocation.getCountry();//国家信息
                aMapLocation.getProvince();//省信息
                aMapLocation.getCity();//城市信息
                aMapLocation.getDistrict();//城区信息
                aMapLocation.getStreet();//街道信息
                aMapLocation.getStreetNum();//街道门牌号信息
                aMapLocation.getCityCode();//城市编码
                aMapLocation.getAdCode();//地区编码

                // 如果不设置标志位,此时再拖动地图时,它会不断将地图移动到当前的位置
                if (isFirstLoc) {
                    //设置缩放级别
                    aMap.moveCamera(CameraUpdateFactory.zoomTo(17));
                    //将地图移动到定位点
                    aMap.moveCamera(CameraUpdateFactory.changeLatLng(new LatLng(aMapLocation.getLatitude(), aMapLocation.getLongitude())));
                    //点击定位按钮 能够将地图的中心移动到定位点
                    mListener.onLocationChanged(aMapLocation);
                    //获取定位信息
                    StringBuffer buffer = new StringBuffer();
                    buffer.append(aMapLocation.getCountry() + ""
                            + aMapLocation.getProvince() + ""
                            + aMapLocation.getCity() + ""
                            + aMapLocation.getProvince() + ""
                            + aMapLocation.getDistrict() + ""
                            + aMapLocation.getStreet() + ""
                            + aMapLocation.getStreetNum());
                    Toast.makeText(getApplicationContext(), buffer.toString(), Toast.LENGTH_LONG).show();
                    isFirstLoc = false;
                }
            } else {
                //显示错误信息ErrCode是错误码,errInfo是错误信息,详见错误码表。
                Log.e("AmapError", "location Error, ErrCode:"
                        + aMapLocation.getErrorCode() + ", errInfo:"
                        + aMapLocation.getErrorInfo());
                Toast.makeText(getApplicationContext(), "定位失败", Toast.LENGTH_LONG).show();
            }
        }
    }

    @Override
    public void onRequestPermissionsResult(int requestCode, String[] permissions, int[] grantResults) {
        super.onRequestPermissionsResult(requestCode, permissions, grantResults);
        //可在此继续其他操作。
        if (requestCode == ACCESS_COARSE_LOCATION_CODE){
            Toast.makeText(getApplicationContext(), "ACCESS_COARSE_LOCATION_CODE", Toast.LENGTH_LONG).show();
        } else if (requestCode == ACCESS_FINE_LOCATION_CODE){
            Toast.makeText(getApplicationContext(), "ACCESS_FINE_LOCATION_CODE", Toast.LENGTH_LONG).show();
        } else if (requestCode == WRITE_EXTERNAL_STORAGE_CODE){
            Toast.makeText(getApplicationContext(), "WRITE_EXTERNAL_STORAGE_CODE", Toast.LENGTH_LONG).show();
        } else if (requestCode == READ_EXTERNAL_STORAGE_CODE){
            Toast.makeText(getApplicationContext(), "READ_EXTERNAL_STORAGE_CODE", Toast.LENGTH_LONG).show();
        } else if (requestCode == READ_PHONE_STATE_CODE){
            Toast.makeText(getApplicationContext(), "READ_PHONE_STATE_CODE", Toast.LENGTH_LONG).show();
        }

    }
}

三:导航地图

1.配置AndroidManifest.xml中application标签中声明service组件,每个app拥有自己单独的定位service。(在基础地图的配置文件中已给出)

2.接下来声明使用权限(和基础地图有重复的可以自行删除)

<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
<uses-permission android:name="android.permission.READ_PHONE_STATE" />
<uses-permission android:name="android.permission.CHANGE_WIFI_STATE" />
<uses-permission android:name="android.permission.ACCESS_WIFI_STATE" />
<uses-permission android:name="android.permission.WAKE_LOCK" />

3.启动导航功能(含语音功能)

public class Navigationalmap extends AppCompatActivity implements AMapNaviViewListener,AMapNaviListener,AMapLocationListener {

    private static final String TAG = "AAA";

    /** 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 String naviWay;

    /** 导航参数 */
    private JSONArray naviData;

    /** 线程句柄 */
    private Handler handler = new Handler();

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_navigationalmap);

        mAMapNaviView = new AMapNaviView(this);
        FrameLayout.LayoutParams layoutParams = new FrameLayout.LayoutParams(LayoutParams.MATCH_PARENT, LayoutParams.MATCH_PARENT);
        mAMapNaviView.setLayoutParams(layoutParams);
        setContentView(mAMapNaviView);

        naviWay = (String) getIntent().getSerializableExtra(MainActivity.NAVI_WAY);
        try {
            naviData = new JSONArray(getIntent().getStringExtra(MainActivity.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.e(TAG, "起点坐标为空,获取设备定位坐标作为起点.");
            initLocation();
        }

        mAMapNaviView.onCreate(savedInstanceState);
        setAmapNaviViewOptions();
        mAMapNaviView.setAMapNaviViewListener(this);
    }

    @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实例化的,
                 * ActivityonDestroy中一定要执行AMapLocationClientonDestroy
                 */
                mlocationClient.onDestroy();
                mlocationClient = null;
                mLocationOption = null;
            }
        } catch (Exception e) {
        }
    }

    /**
     * 初始化导航起始点、途经点参数
     */
    public void initNaviData() {
        JSONObject endPos = null;
        if (naviWay.equals(MainActivity.NAVI_DRIVE)) {
            // 驾车导航方式
            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 = wayPosArray.optJSONObject(i);
                mWayPointList.add(new NaviLatLng(wayPos.optDouble("latitude"), wayPos.optDouble("longitude")));
            }
        } else {
            // 步行和骑车导航方式
            endPos = naviData.optJSONObject(1);
            endList.add(new NaviLatLng(endPos.optDouble("latitude"), endPos.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.setSettingMenuEnabled(false);//设置菜单按钮是否在导航界面显示
        viewOptions.setNaviNight(false);//设置导航界面是否显示黑夜模式
        viewOptions.setReCalculateRouteForYaw(true);//设置偏航时是否重新计算路径
        viewOptions.setReCalculateRouteForTrafficJam(true);//前方拥堵时是否重新计算路径
        viewOptions.setTrafficInfoUpdateEnabled(true);//设置交通播报是否打开
        viewOptions.setCameraInfoUpdateEnabled(true);//设置摄像头播报是否打开
        viewOptions.setScreenAlwaysBright(true);//设置导航状态下屏幕是否一直开启。
        viewOptions.setTrafficBarEnabled(false);  //设置 返回路况光柱条是否显示(只适用于驾车导航,需要联网)
        viewOptions.setMonitorCameraEnabled(true); //设置摄像头图标是否显示 是
        // viewOptions.setLayoutVisible(false);  //设置导航界面UI是否显示
        //viewOptions.setNaviViewTopic(mThemeStle);//设置导航界面的主题
        //viewOptions.setZoom(16);
        viewOptions.setTilt(0);  //2D显示
        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内精度最高的一次定位结果。
        //如果设置其为truesetOnceLocation(boolean b)接口也会被设置为true,反之不会。
        mLocationOption.setOnceLocationLatest(true);
        //设置定位间隔,单位毫秒,默认为2000ms
        mLocationOption.setInterval(2000);
        //设置定位参数
        mlocationClient.setLocationOption(mLocationOption);
        // 此方法为每隔固定时间会发起一次定位请求,为了减少电量消耗或网络流量消耗,
        // 注意设置合适的定位时间的间隔(最小间隔支持为2000ms),并且在合适时间调用stopLocation()方法来取消定位请求
        // 在定位结束后,在合适的生命周期调用onDestroy()方法
        // 在单次定位情况下,定位无论成功与否,都无需调用stopLocation()方法移除请求,定位sdk内部会移除
        //启动定位
        mlocationClient.startLocation();
    }

    /**
     * 界面右下角功能设置按钮的回调接口
     */
    @Override
    public void onNaviSetting() {

    }
    /**
     * 导航页面左下角返回按钮点击后弹出的『退出导航对话框』中选择『确定』后的回调接口
     */
    @Override
    public void onNaviCancel() {
        Log.e(TAG, "导航结束.");
        finish();
    }
    /**
     * 导航页面左下角返回按钮的回调接口 false-SDK主动弹出『退出导航』对话框,true-SDK不主动弹出『退出导航对话框』,由用户自定义
     * @return
     */
    @Override
    public boolean onNaviBackClick() {
        return false;
    }

    /**
     * 导航界面地图状态的回调
     * i - 地图状态,0:车头朝上状态;1:非锁车状态,即车标可以任意显示在地图区域内。
     * @param i
     */
    @Override
    public void onNaviMapMode(int i) {

    }

    /**
     * 转弯view的点击回调
     */
    @Override
    public void onNaviTurnClick() {

    }

    /**
     * 下一个道路View点击回调
     */
    @Override
    public void onNextRoadClick() {

    }

    /**
     * 全览按钮点击回调
     */
    @Override
    public void onScanViewButtonClick() {

    }

    /**
     * 锁地图状态发生变化时回调
     * @param b
     */
    @Override
    public void onLockMap(boolean b) {

    }

    @Override
    public void onNaviViewLoaded() {
        Log.e(TAG, "导航页面加载成功");
        Log.e(TAG, "请不要使用AMapNaviView.getMap().setOnMapLoadedListener();overwrite导航SDK内部画线逻辑");
    }

    /**
     * 导航创建失败时的回调函数
     */
    @Override
    public void onInitNaviFailure() {
        Log.e(TAG, "导航创建失败" );
    }

    /**
     * 初始化成功
     */
    @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, true, true);
        } catch (Exception e) {
            e.printStackTrace();
        }
        if(naviWay.contains(MainActivity.NAVI_WALK)) {
            mAMapNavi.calculateWalkRoute(startList.get(0), endList.get(0)); // 步行导航
        } else if(naviWay.contains(MainActivity.NAVI_RIDE)) {
            mAMapNavi.calculateRideRoute(startList.get(0), endList.get(0));// 骑车导航
        } else if(naviWay.contains(MainActivity.NAVI_DRIVE)) {
            mAMapNavi.calculateDriveRoute(startList, endList, mWayPointList, strategy);// 驾车导航
        }
    }

    /**
     * 开始导航回调
     * i - 导航类型,1 : 实时导航,2 :模拟导航
     * @param i
     */
    @Override
    public void onStartNavi(int i) {
        Log.e(TAG, "启动导航后回调函数=" + i );
    }
    /**
     * 当前方路况光柱信息有更新时回调函数。
     */
    @Override
    public void onTrafficStatusUpdate() {

    }

    /**
     * 当前位置回调
     * @param aMapNaviLocation
     */
    @Override
    public void onLocationChange(AMapNaviLocation aMapNaviLocation) {

    }

    /**
     * 导航播报信息回调函数
     * i - 播报类型,包含导航播报、前方路况播报和整体路况播报,类型请见NaviTTSType
     * s - 播报文字
     * @param i
     * @param s
     */
    @Override
    public void onGetNavigationText(int i, String s) {

    }

    @Override
    public void onGetNavigationText(String s) {

    }

    /**
     * 结束模拟导航
     */
    @Override
    public void onEndEmulatorNavi() {

    }

    /**
     * 到达目的地后回调函数
     */
    @Override
    public void onArriveDestination() {
        Log.e(TAG, "到达目的地");
    }

    /**
     * 步行或者驾车路径规划失败后的回调函数
     * @param i
     */
    @Override
    public void onCalculateRouteFailure(int i) {
        Toast.makeText(Navigationalmap.this,"路径规划失败=" + i + ",失败原因查看官方错误码对照表",Toast.LENGTH_LONG).show();
        Log.e(TAG, "路径规划失败=" + i );
    }

    /**
     * 步行或驾车导航时,出现偏航后需要重新计算路径的回调函数
     */
    @Override
    public void onReCalculateRouteForYaw() {

    }

    /**
     * 驾车导航时,如果前方遇到拥堵时需要重新计算路径的回调
     */
    @Override
    public void onReCalculateRouteForTrafficJam() {

    }

    /**
     * 驾车路径导航到达某个途经点的回调函数
     * i - 到达途径点的编号,标号从1开始,依次累加。 模拟导航下不工作
     * @param i
     */
    @Override
    public void onArrivedWayPoint(int i) {

    }

    /**
     * 用户手机GPS设置是否开启的回调函数
     * b - true,开启;false,未开启
     * @param b
     */
    @Override
    public void onGpsOpenStatus(boolean b) {

    }

    /**
     * 导航数据回调  ********重点
     * 导航引导信息回调 naviInfo 是导航信息类
     * naviInfo - 导航信息对象。
     * @param naviInfo
     */
    @Override
    public void onNaviInfoUpdate(NaviInfo naviInfo) {

    }

    /**
     * 过时
     * @param aMapNaviInfo
     */
    @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) {

    }

    /**
     * 显示路口放大图回调
     * aMapNaviCross - 路口放大图类,可以获得此路口放大图bitmap
     * @param aMapNaviCross
     */
    @Override
    public void showCross(AMapNaviCross aMapNaviCross) {

    }

    /**
     * 关闭路口放大图回调
     */
    @Override
    public void hideCross() {

    }

    @Override
    public void showModeCross(AMapModelCross aMapModelCross) {

    }

    @Override
    public void hideModeCross() {

    }
    /**
     * 显示道路信息回调
     * aMapLaneInfos - 道路信息数组,可获得各条道路分别是什么类型,可用于用户使用自己的素材完全自定义显示。
     * bytes - 道路背景数据数组,可用于装载官方的DriveWayView,并显示。
     * bytes1 - 道路推荐数据数组,可用于装载官方的DriveWayView,并显示。
     * @param aMapLaneInfos
     * @param bytes
     * @param bytes1
     */
    @Override
    public void showLaneInfo(AMapLaneInfo[] aMapLaneInfos, byte[] bytes, byte[] bytes1) {

    }

    @Override
    public void showLaneInfo(AMapLaneInfo aMapLaneInfo) {

    }

    /**
     * 隐藏车道信息
     */
    @Override
    public void hideLaneInfo() {

    }

    /**
     * 路线计算成功
     * @param ints
     */
    @Override
    public void onCalculateRouteSuccess(int[] ints) {
        Log.e(TAG, "路径规划完毕,开始导航.");
        handler.postDelayed(new Runnable() {

            @Override
            public void run() {
                // true表示模拟导航,false表示真实GPS导航(默认true                if(MainActivity.NAVI_TYPE) {
                    mAMapNavi.startNavi(NaviType.EMULATOR);
                } else {
                    mAMapNavi.startNavi(NaviType.GPS);
                }
            }
        }, 3000);
    }
    /**
     * 通知当前是否显示平行路切换
     * parallelRoadType - 0表示隐藏 1 表示显示主路 2 表示显示辅路
     * @param i
     */
    @Override
    public void notifyParallelRoad(int i) {

    }

    /**
     * 巡航模式(无路线规划)下,道路设施信息更新回调
     *  aMapNaviTrafficFacilityInfo - 道路设施信息
     * @param aMapNaviTrafficFacilityInfo
     */
    @Override
    public void OnUpdateTrafficFacility(AMapNaviTrafficFacilityInfo aMapNaviTrafficFacilityInfo) {

    }

    /**
     * 更新交通设施信息
     * @param aMapNaviTrafficFacilityInfos
     */
    @Override
    public void OnUpdateTrafficFacility(AMapNaviTrafficFacilityInfo[] aMapNaviTrafficFacilityInfos) {

    }

    /**
     * 已过时
     * @param trafficFacilityInfo
     */
    @Override
    public void OnUpdateTrafficFacility(TrafficFacilityInfo trafficFacilityInfo) {

    }

    /**
     * 巡航模式(无路线规划)下,统计信息更新回调 连续5个点大于15km/h后开始回调
     * aimLessModeStat - 巡航模式(无路线规划)下统计信息
     * @param aimLessModeStat
     */
    @Override
    public void updateAimlessModeStatistics(AimLessModeStat aimLessModeStat) {

    }

    /**
     * 巡航模式(无路线规划)下,统计信息更新回调 当拥堵长度大于500米且拥堵时间大于5分钟时回调
     * @param aimLessModeCongestionInfo
     */
    @Override
    public void updateAimlessModeCongestionInfo(AimLessModeCongestionInfo aimLessModeCongestionInfo) {

    }

    @Override
    public void onPlayRing(int i) {

    }

    /**
     * 定位回调接口实现
     */
    @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(Navigationalmap.this, "location Error, ErrCode:" + amapLocation.getErrorCode() +
                        ", errInfo:" + amapLocation.getErrorInfo(), Toast.LENGTH_LONG).show();
            }
        }
    }
}

4.语音功能(到讯飞官网注册APPID,下载SDK)

/**
 * 导航语音播报(讯飞)
 *
 */
@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 onCompleted(SpeechError error) {
            if (error != null) {
            }
        }

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

        @Override
        public void onBufferReceived(byte[] bytes) {

        }
    };

    TTSController(Context context) {
        mContext = context;
    }

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

    public void init() {
        AMapNavi mAMapNavi = null;
        mAMapNavi = AMapNavi.getInstance(mContext);
        mAMapNavi.setUseInnerVoice(true);
        SpeechUtility.createUtility(mContext, SpeechConstant.APPID + "=" + "输入您讯飞的appid");
        // 初始化合成对象.
        mSpeechSynthesizer = SpeechSynthesizer.createSynthesizer(mContext, new InitListener() {
            @Override
            public void onInit(int i) {
                Log.e("AAA","2A");
            }
        });
        initSpeechSynthesizer();
    }

    /**
     * 使用SpeechSynthesizer合成语音,不弹出合成Dialog.
     *
     * @param
     */
    public void playText(String playText) {
        if (!isfinish) {
            return;
        }
        if (null == mSpeechSynthesizer) {
            // 创建合成对象.
            mSpeechSynthesizer = SpeechSynthesizer.createSynthesizer(mContext, new InitListener() {
                @Override
                public void onInit(int i) {
                    Log.e("AAA","2A");
                }
            });
            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 onEvent(int i, int i1, int i2, Bundle bundle) {

    }

    @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 onEndEmulatorNavi() {
        this.playText("导航结束");
    }

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

    @Override
    public void onGetNavigationText(String s) {

    }

    @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 updateCameraInfo(AMapNaviCameraInfo[] aMapNaviCameraInfos) {

    }

    @Override
    public void updateIntervalCameraInfo(AMapNaviCameraInfo aMapNaviCameraInfo, AMapNaviCameraInfo aMapNaviCameraInfo1, int i) {

    }

    @Override
    public void onServiceAreaUpdate(AMapServiceAreaInfo[] aMapServiceAreaInfos) {

    }

    @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 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) {
        String calculateResult = "路径计算就绪";
        this.playText(calculateResult);
    }

    @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 onPlayRing(int i) {

    }
}

Demo下载地址:https://download.csdn.net/download/qq_39735504/10284355

  • 4
    点赞
  • 45
    收藏
    觉得还不错? 一键收藏
  • 4
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值