最近因爲課程需要,在學習安卓開發的相關課程,需要使用百度定位實現定位功能,因爲小白剛接觸安卓不久,也是爲了幫助一下跟我一樣小白的同學,把相關過程記錄下來,以免忘記。
1.進入百度地圖官網註冊並申請KEY http://lbsyun.baidu.com/
然後點擊創建應用,進行KEY申請,具體看截圖
說明一下,發佈版SHA1、開發版SHA1在安卓程序中都是唯一的識別碼,發佈版SHA1要填寫正確,不然無法獲取相關服務。
想要獲取發佈版SHA1,需要先對程序打包簽名,請自行百度,或參考此文檔 https://blog.csdn.net/l_215851356/article/details/69914213
簽名之後,可以從簽名文件中獲取發佈版SHA1,請自行百度,或參考此文檔 https://jingyan.baidu.com/article/25648fc19932849191fd0001.html
獲取SHA1之後,填入百度申請中,提交,獲取KEY
選擇需要的sdk,點擊開發包下載(注:本人用迅雷及數個瀏覽器下載,都顯示數據丟失,無法解壓,最後解決辦法是把相關鏈接發到手機,用手機下載後傳到電腦)
解壓後的文件夾
BaiduLBS_android.jar放在project目錄下的app–>libs目錄下,其他目錄放在app–>main–>新建文件夾比如:jniLibs下,請看截圖
在build.gradle中配置libs目錄
sourceSets { main { jniLibs.srcDirs = [‘libs’] } }
主要爲設置service、引用key以及添加權限
<?xml version="1.0" encoding="utf-8"?> <manifest xmlns:android="http://schemas.android.com/apk/res/android" package="com.example.shiyan14"> <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> <service android:name="com.baidu.location.f" android:enabled="true" android:process=":remote"> </service> <meta-data android:name="com.baidu.lbsapi.API_KEY" android:value="LWSBWe5xkeCPZyNKGrt9f0FMH2TeW91h" /> <activity android:name=".Activity1"/> <activity android:name=".Activity2"/> </application> <!-- 這個權限用於進行網絡定位--> <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.ACCESS_WIFI_STATE"></uses-permission> <!-- 獲取運營商信息,用於支持提供運營商信息相關的接口--> <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE"></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> <!-- 寫入擴展存儲,向擴展卡寫入數據,用於寫入離線定位數據--> <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"></uses-permission> <!-- 訪問網絡,網絡定位需要上網--> <uses-permission android:name="android.permission.INTERNET" /> <!-- SD卡讀取權限,用戶寫入離線定位數據--> <uses-permission android:name="android.permission.MOUNT_UNMOUNT_FILESYSTEMS"></uses-permission> </manifest>
我的MainActivity中只寫了兩個按鈕跳轉事件,跳到其他頁面,不要學我的按鈕和類命名方法,要命名得規範一點(因爲命名不規範,沒少挨老師罵)
activity_main.xml我只放了兩個按鈕,跳轉到不同頁面
後面直接放代碼
Activity1
package com.example.shiyan14; import android.os.Bundle; import android.support.v7.app.AppCompatActivity; import android.view.View; import android.widget.Button; import android.widget.Toast; import com.baidu.location.BDLocation; import com.baidu.location.BDLocationListener; import com.baidu.location.LocationClient; import com.baidu.location.LocationClientOption; import com.baidu.mapapi.SDKInitializer; import com.baidu.mapapi.map.BaiduMap; import com.baidu.mapapi.map.MapStatus; import com.baidu.mapapi.map.MapStatusUpdate; import com.baidu.mapapi.map.MapStatusUpdateFactory; import com.baidu.mapapi.map.MapView; import com.baidu.mapapi.map.MyLocationData; import com.baidu.mapapi.model.LatLng; public class Activity1 extends AppCompatActivity implements View.OnClickListener { private MapView mMapView; private BaiduMap mBaiduMap; public LocationClient mLocationClient; public BDLocationListener myListener = new MyLocationListener(); private Button bt; private Button button; private Button buttons; private LatLng latLng; private boolean isFirstLoc = true; // 是否首次定位 @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); //在使用SDK各組件之前初始化context信息,傳入ApplicationContext //注意該方法要再setContentView方法之前實現 SDKInitializer.initialize(getApplicationContext()); setContentView(R.layout.activity1); initView(); initMap(); } private void initMap() { //獲取地圖控件引用 mBaiduMap = mMapView.getMap(); //普通地圖 mBaiduMap.setMapType(BaiduMap.MAP_TYPE_NORMAL); mBaiduMap.setMyLocationEnabled(true); //默認顯示普通地圖 mBaiduMap.setMapType(BaiduMap.MAP_TYPE_NORMAL); //開啓交通圖 //mBaiduMap.setTrafficEnabled(true); //開啓熱力圖 //mBaiduMap.setBaiduHeatMapEnabled(true); // 開啓定位圖層 mBaiduMap.setMyLocationEnabled(true); mLocationClient = new LocationClient(getApplicationContext()); //聲明LocationClient類 //配置定位SDK參數 initLocation(); mLocationClient.registerLocationListener(myListener); //註冊監聽函數 //開啓定位 mLocationClient.start(); //圖片點擊事件,回到定位點 mLocationClient.requestLocation(); } //配置定位SDK參數 private void initLocation() { LocationClientOption option = new LocationClientOption(); option.setLocationMode(LocationClientOption.LocationMode.Hight_Accuracy );//可選,默認高精度,設置定位模式,高精度,低功耗,僅設備 option.setCoorType("bd09ll");//可選,默認gcj02,設置返回的定位結果座標系 int span = 1000; option.setScanSpan(span);//可選,默認0,即僅定位一次,設置發起定位請求的間隔需要大於等於1000ms纔是有效的 option.setIsNeedAddress(true);//可選,設置是否需要地址信息,默認不需要 option.setOpenGps(true);//可選,默認false,設置是否使用gps option.setLocationNotify(true);//可選,默認false,設置是否當GPS有效時按照1S/1次頻率輸出GPS結果 option.setIsNeedLocationDescribe(true);//可選,默認false,設置是否需要位置語義化結果,可以在BDLocation // .getLocationDescribe裏得到,結果類似於「在北京天安門附近」 option.setIsNeedLocationPoiList(true);//可選,默認false,設置是否需要POI結果,可以在BDLocation.getPoiList裏得到 option.setIgnoreKillProcess(false); option.setOpenGps(true); // 打開gps //可選,默認true,定位SDK內部是一個SERVICE,並放到了獨立進程,設置是否在stop的時候殺死這個進程,默認不殺死 option.SetIgnoreCacheException(false);//可選,默認false,設置是否收集CRASH信息,默認收集 option.setEnableSimulateGps(false);//可選,默認false,設置是否需要過濾GPS仿真結果,默認需要 mLocationClient.setLocOption(option); } //實現BDLocationListener接口,BDLocationListener爲結果監聽接口,異步獲取定位結果 public class MyLocationListener implements BDLocationListener { @Override public void onReceiveLocation(BDLocation location) { //mLocationClient.onReceiveLocation(location); latLng = new LatLng(location.getLatitude(), location.getLongitude()); // 構造定位數據 MyLocationData locData = new MyLocationData.Builder() .accuracy(location.getRadius()) // 此處設置開發者獲取到的方向信息,順時針0-360 .direction(100).latitude(location.getLatitude()) .longitude(location.getLongitude()).build(); // 設置定位數據 mBaiduMap.setMyLocationData(locData); // 當不需要定位圖層時關閉定位圖層 //mBaiduMap.setMyLocationEnabled(false); if (isFirstLoc) { isFirstLoc = false; LatLng ll = new LatLng(location.getLatitude(), location.getLongitude()); MapStatus.Builder builder = new MapStatus.Builder(); builder.target(ll).zoom(18.0f); mBaiduMap.animateMapStatus(MapStatusUpdateFactory.newMapStatus(builder.build())); if (location.getLocType() == BDLocation.TypeGpsLocation) { // GPS定位結果 Toast.makeText(Activity1.this, location.getAddrStr(), Toast.LENGTH_SHORT).show(); } else if (location.getLocType() == BDLocation.TypeNetWorkLocation) { // 網絡定位結果 Toast.makeText(Activity1.this, location.getAddrStr(), Toast.LENGTH_SHORT).show(); } else if (location.getLocType() == BDLocation.TypeOffLineLocation) { // 離線定位結果 Toast.makeText(Activity1.this, location.getAddrStr(), Toast.LENGTH_SHORT).show(); } else if (location.getLocType() == BDLocation.TypeServerError) { Toast.makeText(Activity1.this, "服務器錯誤,請檢查", Toast.LENGTH_SHORT).show(); } else if (location.getLocType() == BDLocation.TypeNetWorkException) { Toast.makeText(Activity1.this, "網絡錯誤,請檢查", Toast.LENGTH_SHORT).show(); } else if (location.getLocType() == BDLocation.TypeCriteriaException) { Toast.makeText(Activity1.this, "手機模式錯誤,請檢查是否飛行", Toast.LENGTH_SHORT).show(); } } } } private void initView() { mMapView = findViewById(R.id.bmapView); bt = findViewById(R.id.bt); bt.setOnClickListener(this); button =findViewById(R.id.button); button.setOnClickListener(this); buttons = findViewById(R.id.buttons); buttons.setOnClickListener(this); } @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 public void onClick(View v) { switch (v.getId()) { case R.id.bt: //把定位點再次顯現出來 MapStatusUpdate mapStatusUpdate = MapStatusUpdateFactory.newLatLng(latLng); mBaiduMap.animateMapStatus(mapStatusUpdate); break; case R.id.button: //衛星地圖 mBaiduMap.setMapType(BaiduMap.MAP_TYPE_SATELLITE); break; case R.id.buttons: //普通地圖 mBaiduMap.setMapType(BaiduMap.MAP_TYPE_NORMAL); break; } } }
Activity2主要爲獲取poi
參考了 https://blog.csdn.net/ygreatred/article/details/79872794
使用
location.getLatitude();//緯度
location.getLongitude();//經度
location.getDirection();//定位方向
location.getRadius();//定位精度
location.getCoorType();//定位座標類型
location.getLocType();//定位類型、定位錯誤返回碼
location.getLocTypeDescription();//對應的定位類型說明
location.getTime();//獲取經緯度服務器時間
//判斷用戶是在室內,還是在室外1:室內,0:室外,這個判斷不一定是100%準確的
location.getUserIndoorState();
location.getAddrStr(); //獲取詳細地址信息
location.getCountry(); //獲取國家
location.getProvince(); //獲取省份
location.getCity(); //獲取城市
location.getDistrict(); //獲取區縣
location.getStreet(); //獲取街道信息
public class MyLocationListener extends BDAbstractLocationListener { @Override public void onReceiveLocation(BDLocation location) { //此處的BDLocation爲定位結果信息類,通過它的各種get方法可獲取定位相關的全部結果 // 以下只列舉部分獲取經緯度相關(常用)的結果信息 // 更多結果信息獲取說明,請參照類參考中BDLocation類中的說明 double latitude = location.getLatitude(); //獲取緯度信息 double longitude = location.getLongitude(); //獲取經度信息 float radius = location.getRadius(); //獲取定位精度,默認值爲0.0f int errorCode = location.getLocType(); //獲取定位類型、定位錯誤返回碼,具體信息可參照類參考中BDLocation類中的說明 String coorType = location.getCoorType(); String s1="緯度:"+String.valueOf(latitude); String s2="經度:"+String.valueOf(longitude); String s3="定位精度:"+String.valueOf(radius); textView.setText("\n\n" + s1+"\n"+s2+"\n"+s3+"\n"+"詳細地址:"+location.getAddrStr()+"\n"+"國家:"+location.getCountry()+"\n"+"省份:"+location.getProvince()+"\n城市:"+location.getCity()+"\n區縣:"+location.getDistrict() +"\n街道信息:"+location.getStreet()+"\n返回碼:"+errorCode+"\n座標類型:"+coorType); } }
activity1.xml
<?xml version="1.0" encoding="utf-8"?> <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent" android:layout_height="match_parent" tools:context=".MainActivity"> <com.baidu.mapapi.map.MapView android:id="@+id/bmapView" android:layout_width="match_parent" android:layout_height="match_parent" android:layout_above="@+id/ll" android:clickable="true"></com.baidu.mapapi.map.MapView> <LinearLayout android:id="@+id/ll" android:layout_width="match_parent" android:layout_height="wrap_content" android:layout_alignParentBottom="true" android:orientation="horizontal"> <Button android:id="@+id/bt" android:layout_width="0dp" android:layout_height="wrap_content" android:layout_weight="1" android:text="復位" /> <Button android:id="@+id/button" android:layout_width="0dp" android:layout_height="wrap_content" android:layout_weight="1" android:text="衛星" /> <Button android:id="@+id/buttons" android:layout_width="0dp" android:layout_height="wrap_content" android:layout_weight="1" android:text="普通" /> </LinearLayout> </RelativeLayout>
activity2.xml
<?xml version="1.0" encoding="utf-8"?> <android.support.constraint.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:app="http://schemas.android.com/apk/res-auto" xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent" android:layout_height="match_parent" tools:layout_editor_absoluteY="81dp"> <TextView android:id="@+id/textView" android:layout_width="332dp" android:layout_height="0dp" app:layout_constraintBottom_toBottomOf="parent" app:layout_constraintEnd_toEndOf="parent" app:layout_constraintTop_toTopOf="parent" /> </android.support.constraint.ConstraintLayout>
注意:由於代碼中沒有相應的try catch語句或者if語句,如果程序無法獲取權限,可能會出現無法服務或者閃退情況,如果遇到這種情況,請嘗試進入手機設置-更多應用-權限管理,把權限由詢問改爲允許。
或者由手機自帶的安全管家,進入權限管理,把權限由詢問改爲允許。
本人是一枚小白,雖然功能實現了,但代碼中有許多邏輯錯誤,不進行一一優化了。