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

發佈了45 篇原創文章 · 獲贊 17 · 訪問量 3萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章