1. 程式人生 > >高德地圖整合

高德地圖整合

        高德地圖的整合和實現

高德地圖目前的定位型別有 3 種:

LOCATION_TYPE_LOCATE :只在第一次定位移動到地圖中心點;

LOCATION_TYPE_MAP_FOLLOW :定位,移動到地圖中心點並跟隨;

LOCATION_TYPE_MAP_ROTATE :定位,移動到地圖中心點,跟蹤並根據面向方向旋轉地圖。

注意它在自己的模擬器上不能定位,要在手機上才能使用定位和旋轉,不要忘記開手機上的GPS定位哦

    

1.如果沒有註冊過,就先去高德開放平臺先去註冊,首先在 http://id.amap.com/ 站點註冊使用者名稱,密碼(如果沒有):


然後建立應用,再生成獲取ApiKey

獲取Key 

如何申請 Key

1、建立新應用

進入控制檯,建立一個新應用。如果您之前已經建立過應用,可直接跳過這個步驟。

 應用名稱可以自己定義

獲取key

 獲取key的連結可參考:http://lbs.amap.com/api/android-sdk/guide/create-project/get-key#key。

 


2、新增新Key

在建立的應用上點選"新增新Key"按鈕,在彈出的對話方塊中,依次輸入應用名名稱,選擇繫結的服務為“Android平臺SDK”,輸入釋出版安全碼  SHA1、除錯版安全碼 SHA1、以及 Package,如下圖所示:

需要注意的是: 1個KEY只能用於一個應用(多渠道安裝包屬於多個應用),1個Key在多個應用上使用會出現服務呼叫失敗。

在閱讀完高德地圖API服務條款後,勾選此選項,點選“提交”,完成 Key 的申請,此時您可以在所建立的應用下面看到剛申請的 Key 了。

如何獲取 SHA1

除錯版本(debug)和釋出版本(release)下的 SHA1 值是不同的,釋出 apk 時需要根據釋出 apk 對應的 keystore 重新配置 Key。

  • 獲取除錯版本 SHA1 需要根據不同的開發工具,分別參考 通過Eclipse獲取SHA1 通過Android Studio獲取SHA1
  • 獲取釋出版本下 SHA1 的方法請參考 使用 keytool(jdk自帶工具)獲取SHA1

通過 eclipse 獲取 SHA1

使用 adt 22 以上版本,可以在 eclipse 中直接檢視。

Windows:依次在 eclipse 中開啟 Window -> Preferances -> Android -> Build。

Mac:依次在 eclipse 中開啟 Eclipse/ADT->Preferances -> Android -> Build。

在彈出的 Build 對話方塊中 “SHA1 fingerprint” 中的值即為 Android 簽名證書的 SHA1 值,如下圖所示:

通過Android Studio獲取SHA1

第一步、開啟 Android Studio 的 Terminal 工具。

第二步、輸入命令:keytool -v -list -keystore  keystore檔案路徑。

第三步、輸入 Keystore 密碼

使用 keytool(jdk自帶工具)獲取 SHA1

1、執行進入控制檯。

2、在彈出的控制檯視窗中輸入 cd .android 定位到 .android 資料夾。

3.繼續在控制檯輸入命令。

除錯版本使用 debug.keystore,命令為:keytool -list -v -keystore debug.keystore。 釋出版本使用 apk 對應的 keystore,命令為:keytool -list -v -keystore apk 的  keystore。

如下所示:

提示輸入金鑰庫密碼,開發模式預設密碼是 android,釋出模式的密碼是為 apk 的 keystore 設定的密碼。輸入金鑰後回車(如果沒設定密碼,可直接回車),

此時可在控制檯顯示的資訊中獲取 Sha1 值,如下圖所示:

說明:keystore 檔案為 Android 簽名證書檔案。

如何獲取 PackageName

開啟 Android 專案的 AndroidManifest.xml 配置檔案,package 屬性所對應的內容為應用包名,如下圖所示:

也請檢查 build.gradle 檔案的 applicationid 屬性是否與上文提到的 package 屬性一致,如果不一致會導致 INVALID_USER_SCODE,請調整一致。

  • 如何申請 Key
  • 如何獲取 SHA1
  • 如何獲取 PackageName
   獲取到key以後就在開始在清單檔案裡配置

   先在清單檔案里加入一些網路許可權和Apikey

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="com..gaodeditu">

    <!--允許程式開啟網路套接字-->
    <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" />
    <!--用於進行網路定位-->
    <uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION"></uses-permission>
    <!--用於訪問GPS定位-->
    <uses-permission android:name="android.permission.ACCESS_FINE_LOCATION"></uses-permission>
    <!--用於獲取wifi的獲取許可權,wifi資訊會用來進行網路定位-->
    <uses-permission android:name="android.permission.CHANGE_WIFI_STATE"></uses-permission>
    <!--用於讀取手機當前的狀態-->
    <uses-permission android:name="android.permission.READ_PHONE_STATE"></uses-permission>
    <!--用於申請呼叫A-GPS模組-->
    <uses-permission android:name="android.permission.ACCESS_LOCATION_EXTRA_COMMANDS"/>
    <!--獲取運營商資訊,用於支援提供運營商資訊相關的介面-->
    <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" />
	

    <meta-data 
	android:name="com.amap.api.v2.apikey" 
	android:value="6b273938762bde148d424b5d4bf014fd">//換成您的key
    </meta-data>
    <service android:name="com.amap.api.location.APSService"></service>

    <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>
    </application>


</manifest>

然後在專案的build.gradle裡新增依賴

 
defaultConfig {  
         ........  
  
        ndk {  
            //設定支援的SO庫架構(開發者可以根據需要,選擇一個或多個平臺的so)  
            abiFilters "armeabi", "armeabi-v7a", "arm64-v8a", "x86","arm64-v8a","x86_64"  
        }  
    }  
  
dependencies {  
       ........  
  
     
    compile 'com.amap.api:3dmap:5.0.0'  
    compile 'com.amap.api:location:3.3.0'  
    compile 'com.amap.api:search:5.0.0'  
  
}

然後就開始寫activity—main的佈局

<?xml version="1.0" encoding="utf-8"?>
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical" >

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

    <TextView
        android:id="@+id/location_errInfo_text"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_gravity="bottom|left"
        android:layout_marginBottom="10dp"
        android:layout_marginLeft="10dp"
        android:background="@android:color/holo_red_light"
        android:textColor="@android:color/darker_gray"
        android:text="TextView"
        android:visibility="gone"/>

    <RadioGroup
        android:id="@+id/gps_radio_group"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_gravity="top|left"
        android:layout_marginLeft="10dp"
        android:layout_marginTop="10dp"
        android:background="@android:color/holo_orange_light"
        android:orientation="horizontal" >

        <RadioButton
            android:id="@+id/gps_locate_button"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:checked="true"
            android:text="定位"
            android:textColor="@android:color/black" />

        <RadioButton
            android:id="@+id/gps_follow_button"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="追蹤"
            android:textColor="@android:color/black" />

        <RadioButton
            android:id="@+id/gps_rotate_button"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="旋轉"
            android:textColor="@android:color/black" />
    </RadioGroup>

</FrameLayout>

MainActivity

import android.os.Bundle;
import android.support.annotation.IdRes;
import android.support.v7.app.ActionBar;
import android.support.v7.app.AppCompatActivity;
import android.util.Log;
import android.view.View;
import android.view.Window;
import android.widget.RadioGroup;
import android.widget.RadioGroup.OnCheckedChangeListener;
import android.widget.TextView;
import android.widget.Toast;

import com.amap.api.location.AMapLocation;
import com.amap.api.location.AMapLocationClient;
import com.amap.api.location.AMapLocationClientOption;
import com.amap.api.location.AMapLocationListener;
import com.amap.api.maps.AMap;
import com.amap.api.maps.CameraUpdateFactory;
import com.amap.api.maps.LocationSource;
import com.amap.api.maps.MapView;
import com.amap.api.maps.UiSettings;
import com.amap.api.maps.model.LatLng;

import java.text.SimpleDateFormat;
import java.util.Date;


public class MainActivity extends AppCompatActivity implements LocationSource, AMapLocationListener,OnCheckedChangeListener{
    private MapView mapView;
    //AMap是地圖物件
    private AMap aMap;
    //宣告AMapLocationClient類物件,定位發起端
    private AMapLocationClient mLocationClient = null;
    //宣告mLocationOption物件,定位引數
    public AMapLocationClientOption mLocationOption = null;
    //宣告mListener物件,定位監聽器
    private LocationSource.OnLocationChangedListener mListener = null;
    //標識,用於判斷是否只顯示一次定位資訊和使用者重新定位
    private boolean isFirstLoc = true;
    private Bundle savedInstanceState;

    private RadioGroup mGPSModeGroup;
    private TextView mLocationErrText;
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);

        requestWindowFeature(Window.FEATURE_NO_TITLE);// 不顯示程式的標題欄
        setContentView(R.layout.activity_main);

        //隱藏標題欄
        ActionBar actionBar=getSupportActionBar();
        actionBar.hide();
        //初始化控制元件
        initView();
    }
    /**
     * 獲取控制元件
     */
    private void initView() {
        mapView= (MapView) findViewById(R.id.map);
        //在activity執行onCreate時執行mMapView.onCreate(savedInstanceState),實現地圖生命週期管理
        mapView.onCreate(savedInstanceState);
        if (aMap == null) {
            aMap = mapView.getMap();
            //設定顯示定位按鈕 並且可以點選
            UiSettings settings = aMap.getUiSettings();
            aMap.setLocationSource(this);//設定了定位的監聽
            // 是否顯示定位按鈕
            settings.setMyLocationButtonEnabled(true);
            aMap.setMyLocationEnabled(true);//顯示定位層並且可以觸發定位,預設是flase
        }

        //找控制元件
        mGPSModeGroup = (RadioGroup) findViewById(R.id.gps_radio_group);
        mGPSModeGroup.setOnCheckedChangeListener(this);
        mLocationErrText = (TextView)findViewById(R.id.location_errInfo_text);
        mLocationErrText.setVisibility(View.GONE);

        //開始定位
        location();
    }


    private void location() {
        //初始化定位
        mLocationClient = new AMapLocationClient(getApplicationContext());
        //設定定位回撥監聽
        mLocationClient.setLocationListener(this);
        //初始化定位引數
        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,不允許模擬位置  true方法開啟允許位置模擬
        mLocationOption.setMockEnable(true);
        //設定定位間隔,單位毫秒,預設為2000ms
        mLocationOption.setInterval(2000);
        //給定位客戶端物件設定定位引數
        mLocationClient.setLocationOption(mLocationOption);
        //啟動定位
        mLocationClient.startLocation();
    }

    @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中設定isNeedAddress為false,則沒有此結果,網路定位結果中會有地址資訊,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);
                    //新增圖釘
                    //  aMap.addMarker(getMarkerOptions(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
    protected void onDestroy() {
        super.onDestroy();
        //在activity執行onDestroy時執行mMapView.onDestroy(),實現地圖生命週期管理
        mapView.onDestroy();
        mLocationClient.stopLocation();//停止定位
        mLocationClient.onDestroy();//銷燬定位客戶端。
    }

    @Override
    protected void onResume() {
        super.onResume();
        //在activity執行onResume時執行mMapView.onResume (),實現地圖生命週期管理
        mapView.onResume();
    }

    @Override
    protected void onPause() {
        super.onPause();
        //在activity執行onPause時執行mMapView.onPause (),實現地圖生命週期管理
        mapView.onPause();
    }

    @Override
    protected void onSaveInstanceState(Bundle outState) {
        super.onSaveInstanceState(outState);
        //在activity執行onSaveInstanceState時執行mMapView.onSaveInstanceState (outState),實現地圖生命週期管理
        mapView.onSaveInstanceState(outState);
    }


    //監聽事件,實現3D旋轉
    @Override
    public void onCheckedChanged(RadioGroup radioGroup, @IdRes int i) {
        switch (i) {
            case R.id.gps_locate_button:
                // 設定定位的型別為定位模式
                aMap.setMyLocationType(AMap.LOCATION_TYPE_LOCATE);
                break;
            case R.id.gps_follow_button:
                // 設定定位的型別為 跟隨模式
                aMap.setMyLocationType(AMap.LOCATION_TYPE_MAP_FOLLOW);
                break;
            case R.id.gps_rotate_button:
                // 設定定位的型別為根據地圖面向方向旋轉
                aMap.setMyLocationType(AMap.LOCATION_TYPE_MAP_ROTATE);
                break;
        }

    }
}