高德地圖整合
高德地圖的整合和實現
高德地圖目前的定位型別有 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以後就在開始在清單檔案裡配置 先在清單檔案里加入一些網路許可權和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;
}
}
}