本章為百度地圖定位,内容為使用百度地圖的sdk,實作對自己目前位置的定位。
- 申請AK
- 下載下傳SDK開發包
- 在android項目中引用百度SDK
- 實作定位
先擺上運作後的圖:
![](https://img.laitimes.com/img/9ZDMuAjOiMmIsIjOiQnIsICM38FdsYkRGZkRG9lcvx2bjxiNx8VZ6l2csQTVE5kMRpWT4FleYhnRzwEMW1mY1RzRapnTtxkb5ckYplTeMZTTINGMShUYfRHelRHLwEzX39GZhh2css2RkBnVHFmb1clWvB3MaVnRtp1XlBXe0xyayFWbyVGdhd3LcV2Zh1Wa9M3clN2byBXLzN3btg3Pn5GcuQzMwQjN1EjM0IDNwAjMwIzLc52YucWbp5GZzNmLn9Gbi1yZtl2Lc9CX6MHc0RHaiojIsJye.png)
沒錯,這肯定不是我運作後的圖,是我随便找的一張網圖嘿嘿。隻是說會是這種形式定位自己。據說許多小夥伴運作後會定位到非洲,遇到這種情況的趕緊到下方評論區留名,讓我嘴角忍不住上揚。建議大家用真機測試,就是自己手機。
大家先使用Android Studio建立一個empty activity;
一、申請AK
要想使用百度地圖sdk,就必須申請一個百度地圖的api key。
① 打開網址http://lbsyun.baidu.com/apiconsole/key,裡面需要你注冊的就注冊注冊成為百度的開發者。
②建立應用
點選建立應用:
關于SHA1的擷取:
- 打開Android Studio;
- 點選底部的Terminal;
- 找到你的.Android目錄:(一般在C:\Users\Administrator.android);
- 在Terminal輸入下面指令:
keytool -list -v -keystore debug.keystore -alias androiddebugkey
出現下面情況直接回車;
找到SHA1填入;(提示格式不對是因為你複制内容的最前面或最後面有空格)
包名:就是你建構項目的包名,可以在項目的AndroidMainfest.xml檢視package。
完成上面步驟後,ak就自動生成了:
二、下載下傳SDK開發包
選擇下面網址進行自定義下載下傳:
http://lbsyun.baidu.com/index.php?title=androidsdk/sdkandev-download
暫時我們隻需要基礎定位,其他的大家也可以根據需求勾選下載下傳。
三、在android項目中引用百度SDK
1、将開發包中的jar包和so檔案添加到libs檔案下。
我們将解壓後的檔案libs直接托到下圖的app下,替換原來空的libs;隻有一個BaiduLBS_Android.jar包。
在app目錄下的build.gradle檔案中android塊中配置sourceSets标簽,如果沒有使用該标簽則新增,詳細配置代碼如下:
sourceSets {
main {
jniLibs.srcDir 'libs'
}
}
然後我們需要将jar包導入項目:
點選File->project structure到下圖界面:選擇Dependence和app
點選紅色箭頭的 ‘+’,下方有個import Jar導入jar包,路徑選擇自己剛才替換libs的目錄下面。
導jar包完成後,我們可以在app目錄下的build.gradle中檢視是否導入成功:
現在我們的應用中已經內建了百度地圖SDK,當我們在打包混淆的時候需要注意于BaiduMap SDK 相關的内容不應該被混淆,是以我們需要配置混淆檔案。
1.打開app目錄下的build.gradle檔案,在release代碼塊中添加如下内容(也可能Android Studio已自動生成)
2.編寫混淆檔案,打開app目錄下的proguard-rules.pro檔案,添加如下代碼。
-keep class com.baidu.** {*;}
-keep class mapsdkvi.com.** {*;}
-dontwarn com.baidu.**
2、配置AndroidManifest.xml
内容在代碼處有注釋:關于授權,可能沒用到的,我也一并聲明了
<!-- 這個權限用于進行網絡定位-->
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION"/>
<!-- 這個權限用于通路GPS定位-->
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION"/>
<!-- 用于通路wifi網絡資訊,wifi資訊會用于進行網絡定位-->
<uses-permission android:name="android.permission.ACCESS_WIFI_STATE"/>
<!-- 擷取營運商資訊,用于支援提供營運商資訊相關的接口-->
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE"/>
<!-- 這個權限用于擷取wifi的擷取權限,wifi資訊會用來進行網絡定位-->
<uses-permission android:name="android.permission.CHANGE_WIFI_STATE"/>
<!-- 寫入擴充存儲,向擴充卡寫入資料,用于寫入離線定位資料-->
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
<!-- 通路網絡,網絡定位需要上網 -->
<uses-permission android:name="android.permission.INTERNET"/>
<!-- 允許挂載和反挂載檔案系統可移動存儲 -->
<uses-permission android:name="android.permission.MOUNT_UNMOUNT_FILESYSTEMS"
tools:ignore="ProtectedPermissions" />
<!-- 允許程式讀取底層系統日志檔案 -->
<uses-permission android:name="android.permission.READ_LOGS"
tools:ignore="ProtectedPermissions" />
<!-- 允許通路振動裝置 -->
<uses-permission android:name="android.permission.VIBRATE"/>
<!-- 允許使用PowerManager的 WakeLocks保持程序在休眠時從螢幕消失 -->
<uses-permission android:name="android.permission.WAKE_LOCK"/>
<!-- 允許程式讀取或寫入系統設定 -->
<uses-permission android:name="android.permission.WRITE_SETTINGS"
tools:ignore="ProtectedPermissions" />
<!-- android 9.0上使用前台服務,需要添權重限 -->
<uses-permission android:name="android.permission.FOREGROUND_SERVICE" />
<!-- 用于讀取手機目前的狀态 -->
<uses-permission android:name="android.permission.READ_PHONE_STATE" />
<!-- 讀取緩存資料 -->
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
<!-- 擷取模拟定位資訊 -->
<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">
<!-- 聲明service元件 -->
<service
android:name="com.baidu.location.f"
android:enabled="true"
android:process=":remote"/>
<!-- AK鑒權 -->
<meta-data
android:name="com.baidu.lbsapi.API_KEY"
android:value="YB5k1UuPfS41uikoflUqfG7jYleNgLdU" />
<activity android:name=".MainActivity">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
</application>
3、在layout中添加百度地圖控件
<com.baidu.mapapi.map.MapView
android:id="@+id/bmapview"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:clickable="true"
android:focusable="true" />
四、實作定位
進入我們的MainActivity.java檔案;
- 在應用程式建立時初始化SDK引用的Context全局變量。
- 然後重寫activity的生命周期的幾個方法來管理地圖的生命周期。在activity的onResume、onPause、onDestory方法中分别執行mapview的onReusme、onPause、onDestory方法。
-
定位功能主要會用到LocationClient、BDLocationListener、BDNotifyListener、LocationClientOption等類。
(1)初始化LocationClient類:
LocationClient類是定位SDK的核心類,必須在主線程中聲明。需要傳入一個Context類型的參數,推薦使用getApplicationContext()來擷取全局程序有效的context。
(2)設定定位參數:
主要的參數有:定位模式、傳回坐标類型、是否打開GPS等。
定位模式分為三種:
① 高精度定位模式:同時使用網絡定位和GPS定位,優先傳回最高精度的定位結果。
② 低功耗定位模式:不使用GPS,隻使用網絡定位(WiFi和基站)。
③ 僅用裝置定位模式: 不适用網絡定位,隻使用GPS進行定位。但是此模式下不支援室内環境的定位。
(3)設定定位監聽函數
public BDLocationListener myListener = new BDLocationListener() {
@Override
public void onReceiveLocation(BDLocation location) {
}
}
(4)設定定位函數
最後給上MainActivity.java完整代碼(按alt+enter導入相關類,對于gradle檔案同步,我們要按下下圖鍵:)
public class MainActivity extends Activity {
// 百度地圖控件
private MapView mapView = null;
// 定位相關聲明
public LocationClient locationClient = null;
//自定義圖示
BitmapDescriptor mCurrentMarker = null;
boolean isFirstLoc = true;// 是否首次定位
BaiduMap baiduMap;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
requestWindowFeature(Window.FEATURE_NO_TITLE);
//
SDKInitializer.initialize(getApplicationContext());
setContentView(R.layout.activity_main);
mapView = findViewById(R.id.bmapview);
// 百度地圖對象
baiduMap = mapView.getMap();
baiduMap.setMyLocationEnabled(true);
locationClient = new LocationClient(getApplicationContext()); // 執行個體化LocationClient類
locationClient.registerLocationListener(myListener); // 注冊監聽函數
this.setLocationOption(); //設定定位參數
locationClient.start(); // 開始定位
}
//設定定位函數
private void setLocationOption() {
LocationClientOption option = new LocationClientOption();
option.setOpenGps(true); // 打開GPS
option.setLocationMode(LocationClientOption.LocationMode.Hight_Accuracy);// 設定定位模式
option.setCoorType("bd09ll"); // 傳回的定位結果是百度經緯度,預設值gcj02
option.setScanSpan(5000); // 設定發起定位請求的間隔時間為5000ms
option.setIsNeedAddress(true); // 傳回的定位結果包含位址資訊
option.setNeedDeviceDirect(true); // 傳回的定位結果包含手機機頭的方向
locationClient.setLocOption(option);
}
//定義響應函數
public BDLocationListener myListener = new BDLocationListener() {
@Override
public void onReceiveLocation(BDLocation location) {
// map view 銷毀後不在處理新接收的位置
if (location == null || mapView == null)
return;
MyLocationData locData = new MyLocationData.Builder()
.accuracy(location.getRadius())
// 此處設定開發者擷取到的方向資訊,順時針0-360
.direction(100).latitude(location.getLatitude())
.longitude(location.getLongitude()).build();
baiduMap.setMyLocationData(locData); //設定定位資料
if (isFirstLoc) {
isFirstLoc = false;
LatLng ll = new LatLng(location.getLatitude(),
location.getLongitude());
MapStatusUpdate u = MapStatusUpdateFactory.newLatLngZoom(ll, 16); //設定地圖中心點以及縮放級别
baiduMap.animateMapStatus(u);
}
}
};
@Override
protected void onResume() {
super.onResume();
mapView.onResume();
}
@Override
protected void onPause() {
super.onPause();
mapView.onPause();
}
@Override
protected void onDestroy() {
mapView.onDestroy();
mapView = null;
super.onDestroy();
}
}
好了,這次的安卓百度地圖定位就到這了,有任何疑問或出錯的地方大家積極在下方評論,那些定位到非洲的小夥伴也記得留言哦。