Android整合百度地圖-----顯示地圖、定位、長按顯示地址資訊
阿新 • • 發佈:2018-11-16
一、基礎部分
轉載請註明出處:https://blog.csdn.net/Hunter2916/article/details/82867205
1、下載百度地圖的SDK
下載地址:http://lbsyun.baidu.com/index.php?title=android-locsdk/geosdk-android-download
2、申請key值
註冊百度賬號——>登入百度地圖官網——>控制檯—–>建立應用
具體方法地址:http://lbsyun.baidu.com/apiconsole/key
3、解壓後的jar包放到app下的libs中,並右鍵add到build.gradle中
build.gradle中新增ndk
ndk {
//選擇要新增的對應 cpu 型別的.so 庫。
abiFilters 'armeabi', 'armeabi-v7a', 'armeabi64-v8a', 'x86', 'x86_64'
// 還可以新增 'x86', 'x86_64', 'mips', 'mips64'
}
dependencies{
//百度定位架包
compile files('libs/BaiduLBS_Android.jar')
}
4、在manifest.xml中新增key和service
<meta-data
android:name="com.baidu.lbsapi.API_KEY"
android:value="你自己申請的key" />
<!-- 宣告service元件 -->
<service
android:name="com.baidu.location.f"
android:enabled="true"
android:process=":remote" />
5、新增許可權
<!-- 這個許可權用於進行網路定位-->
<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>
//切記有些許可權在Android5.0以後還需要在程式碼中動態獲取
//例如:
private void requestRunPermissions() {
List<PermissionItem> permisson = new ArrayList<>();
permisson.add(new PermissionItem(Manifest.permission.READ_PHONE_STATE, "電話狀態", R.drawable.permission_ic_phone));
permisson.add(new PermissionItem(Manifest.permission.ACCESS_COARSE_LOCATION, "地理位置", R.drawable.permission_ic_location));
permisson.add(new PermissionItem(Manifest.permission.ACCESS_FINE_LOCATION, "地理位置", R.drawable.permission_ic_location));
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN) {
permisson.add(new PermissionItem(Manifest.permission.READ_EXTERNAL_STORAGE, "讀取許可權", R.drawable.permission_ic_storage));
permisson.add(new PermissionItem(Manifest.permission.WRITE_EXTERNAL_STORAGE, "寫入許可權", R.drawable.permission_ic_storage));
}
HiPermission.create(this)
.title("開啟地圖許可權")
.permissions(permisson)
.filterColor(ResourcesCompat.getColor(getResources(), R.color.colorAccent, getTheme()))
.style(R.style.PermissionBlueStyle)
.msg("我們需要獲得以下許可權才能為您提供服務")
.checkMutiPermission(new PermissionCallback() {
@Override
public void onClose() {
}
@Override
public void onFinish() {
// showToastShort("所有許可權申請完成");
}
@Override
public void onDeny(String permission, int position) {
}
@Override
public void onGuarantee(String permission, int position) {
}
});
}
//新增許可權第三方框架
compile 'me.weyye.hipermission:library:1.0.7'
6、主介面佈局
<com.baidu.mapapi.map.MapView
android:id="@+id/bmapView"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:clickable="true" />
7、Activity中的程式碼
private BaiduMap mBaiduMap;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
binding = DataBindingUtil.setContentView(this, R.layout.activity_main);
mBaiduMap = binding.bmapView.getMap();
//initView();
//在定位之前進行一次動態的獲取許可權
requestRunPermissions();
}
在不設定任何屬性的情況下,定位在北京比例為5公里
7.1、設定縮放比例並使用靜態定位
private void initView() {
//更新地圖
//設定初始化比例 500米左右 zoom越大則地圖越詳細
LatLng latLng = new LatLng(30.272858,120.15941);
MapStatus mMapStatus = new MapStatus.Builder()
.target(latLng)
.zoom(16)
.build();
MapStatusUpdate mMapStatusUpdate = MapStatusUpdateFactory.newMapStatus(mMapStatus); //改變地圖狀態
mBaiduMap.setMapStatus(mMapStatusUpdate);
}
二、定位以及長按地圖獲取地理資訊
1、Activity中程式碼
public class MainActivity extends BaseActivity {
ActivityMainBinding binding;
private Context context;
private BaiduMap mBaiduMap;
//定位相關
private LocationClient mLocationClient;
private MyLocationListener mLocationListener = new MyLocationListener();
private Boolean isFirstIn = true;
private double latitude;
private double longtitude;
//定點陣圖標
private BitmapDescriptor mIconLocation;
private MyOrientationListener myOrientationListener;
private float mCurrentX;
private LatLng mDestLocationData;
private LatLng mLastLocationData;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
// mLocationListener = new MyLocationListener();
context = this;
binding = DataBindingUtil.setContentView(this, R.layout.activity_main);
geoCoder = GeoCoder.newInstance();
mBaiduMap = binding.bmapView.getMap();
initView();
//在定位之前進行一次動態的獲取許可權
// if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
// if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) {
requestRunPermissions();
// }
initLocation();
}
private void initListener() {
binding.typeNone.setOnClickListener(this);
binding.typeNoraml.setOnClickListener(this);
// binding.typeSatellite.setOnClickListener(this);
binding.typeTraffic.setOnClickListener(this);
binding.location.setOnClickListener(this);
binding.overlay.setOnClickListener(this);
}
private void requestRunPermissions() {
List<PermissionItem> permisson = new ArrayList<>();
permisson.add(new PermissionItem(Manifest.permission.READ_PHONE_STATE, "電話狀態", R.drawable.permission_ic_phone));
permisson.add(new PermissionItem(Manifest.permission.ACCESS_COARSE_LOCATION, "地理位置", R.drawable.permission_ic_location));
permisson.add(new PermissionItem(Manifest.permission.ACCESS_FINE_LOCATION, "地理位置", R.drawable.permission_ic_location));
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN) {
permisson.add(new PermissionItem(Manifest.permission.READ_EXTERNAL_STORAGE, "讀取許可權", R.drawable.permission_ic_storage));
permisson.add(new PermissionItem(Manifest.permission.WRITE_EXTERNAL_STORAGE, "寫入許可權", R.drawable.permission_ic_storage));
}
HiPermission.create(this)
.title("開啟地圖許可權")
.permissions(permisson)
.filterColor(ResourcesCompat.getColor(getResources(), R.color.colorAccent, getTheme()))
.style(R.style.PermissionBlueStyle)
.msg("我們需要獲得以下許可權才能為您提供服務")
.checkMutiPermission(new PermissionCallback() {
@Override
public void onClose() {
}
@Override
public void onFinish() {
// showToastShort("所有許可權申請完成");
}
@Override
public void onDeny(String permission, int position) {
}
@Override
public void onGuarantee(String permission, int position) {
}
});
}
/**
* 定位的方法
*/
private void initLocation() {
// binding.LocationResult.setMovementMethod(ScrollingMovementMethod.getInstance());
myOrientationListener = new MyOrientationListener(this);
mLocationClient = new LocationClient(this);
mLocationClient.registerLocationListener(mLocationListener);
LocationClientOption option = new LocationClientOption();
option.setLocationMode(LocationClientOption.LocationMode.Hight_Accuracy);//精確定位
option.setCoorType("bd09ll");//可選,設定返回的定位結果座標系
option.setIsNeedAddress(true);//獲取詳細地址
option.setOpenGps(true);//設定是否使用GPS
// option.setScanSpan(1000);//可選,預設0,即僅定位一次,設定發起定位請求的間隔需要大於等於1000ms才是有效的
option.setIsNeedLocationDescribe(true);//可選,預設false,設定是否需要位置語義化結果,可以在BDLocation
option.setIsNeedLocationPoiList(true);//可選,預設false,設定是否需要POI結果,可以在BDLocation.getPoiList裡得到
option.SetIgnoreCacheException(false);//可選,預設false,設定是否收集CRASH資訊,預設收集
option.setEnableSimulateGps(false);//可選,預設false,設定是否需要過濾GPS模擬結果,預設需要
mLocationClient.setLocOption(option);
//定位後的圖示 初始化圖示
mIconLocation = BitmapDescriptorFactory.fromResource(R.mipmap.navi_map_gps_locked);
//設定自定以圖示
MyLocationConfiguration configuration = new
MyLocationConfiguration(MyLocationConfiguration.LocationMode.NORMAL, true, mIconLocation);
mBaiduMap.setMyLocationConfiguration(configuration);
}
private void initView() {
//更新地圖
//設定初始化比例 500米左右 zoom越大則地圖越詳細
MapStatusUpdate msu = MapStatusUpdateFactory.zoomTo(15.0f);
mBaiduMap.setMapStatus(msu);
}
@Override
public void onClick(View v) {
switch (v.getId()) {
case R.id.type_noraml://普通地圖
mBaiduMap.setMapType(BaiduMap.MAP_TYPE_NORMAL);
break;
// case R.id.type_satellite://衛星模式
// mBaiduMap.setMapType(BaiduMap.MAP_TYPE_SATELLITE);
// break;
case R.id.type_none:
mBaiduMap.setMapType(BaiduMap.MAP_TYPE_NONE);
break;
case R.id.type_traffic:
if (mBaiduMap.isTrafficEnabled()) {
mBaiduMap.setTrafficEnabled(false);
binding.typeTraffic.setText("實時路況(開)");
} else {
mBaiduMap.setTrafficEnabled(true);
binding.typeTraffic.setText("實時路況(關)");
}
break;
}
}
/***
* Stop location service
*/
@Override
protected void onStop() {
super.onStop();
//停止定位
mBaiduMap.setMyLocationEnabled(false);
mLocationClient.stop();
}
@Override
protected void onStart() {
super.onStart();
//開啟定位
mBaiduMap.setMyLocationEnabled(true);
//判斷的時候注意
if (!mLocationClient.isStarted()) {
mLocationClient.start();
}
}
@Override
protected void onResume() {
super.onResume();
binding.bmapView.onResume();
}
@Override
protected void onPause() {
super.onPause();
binding.bmapView.onPause();
}
@Override
protected void onDestroy() {
super.onDestroy();
binding.bmapView.onDestroy();
}
/**
* 定位結果回撥,重寫onReceiveLocation方法,定位的回撥 latitude 緯度
*/
private class MyLocationListener extends BDAbstractLocationListener {
if (location == null || binding.bmapView == null) {
return;
}
MyLocationData data = new MyLocationData.Builder()
.accuracy(location.getRadius())
.latitude(location.getLatitude())
.longitude(location.getLongitude())
.build();
mBaiduMap.setMyLocationData(data);
@Override
public void onReceiveLocation(BDLocation location) {
if (isFirstIn) {
LatLng latLng = new LatLng(location.getLatitude(), location.getLongitude());
MapStatusUpdate msu = MapStatusUpdateFactory.newLatLng(latLng);
mBaiduMap.animateMapStatus(msu);
isFirstIn = false;
Toast.makeText(context, "我的位置資訊為::" + location.getDistrict(),
Toast.LENGTH_SHORT).show();
}
}
}
}
2、點選按鈕回到定位的地方
private double latitude;//緯度
private double longtitude;//經度
/**
* 獲取當前的定位方法
*/
private void getMyLocation() {
LatLng latLng = new LatLng(latitude, longtitude);
MapStatusUpdate msu = MapStatusUpdateFactory.newLatLng(latLng);
mBaiduMap.animateMapStatus(msu);
}
/**
* 定位結果回撥,重寫onReceiveLocation方法,定位的回撥 latitude 緯度
*/
private class MyLocationListener extends BDAbstractLocationListener {
@Override
public void onReceiveLocation(BDLocation location) {
if (location == null || binding.bmapView == null) {
return;
}
MyLocationData data = new MyLocationData.Builder()
.accuracy(location.getRadius())
.direction(mCurrentX)//方向感測器
.latitude(location.getLatitude())
.longitude(location.getLongitude())
.build();
mBaiduMap.setMyLocationData(data);
latitude = location.getLatitude();
longtitude = location.getLongitude();
if (isFirstIn) {
LatLng latLng = new LatLng(location.getLatitude(), location.getLongitude());
MapStatusUpdate msu = MapStatusUpdateFactory.newLatLng(latLng);
mBaiduMap.animateMapStatus(msu);
isFirstIn = false;
// Toast.makeText(context, "我的位置資訊為::" + poiList.get(0).getName(),
// Toast.LENGTH_SHORT).show();
Toast.makeText(context, "我的位置資訊為::" + location.getDistrict(),
Toast.LENGTH_SHORT).show();
}
}
}
3、長按定位顯示資訊
/**
* 長按定點陣圖標
*/
mBaiduMap.setOnMapLongClickListener(new BaiduMap.OnMapLongClickListener() {
@Override
public void onMapLongClick(LatLng latLng) {
// MapStatus maps = new MapStatus.Builder().target(latLng).zoom(15).build();
// MapStatusUpdate m = MapStatusUpdateFactory.newMapStatus(maps);
//改變地圖狀態
// mBaiduMap.setMapStatus(m);
// showToastShort("設定目的地成功");
// showToastShort("設定目的地成功"+latLng.toString());
// mDestLocationData = latLng;
latlngToAddress(latLng);
addDestInfoOverLay(latLng);
}
});
/**
* 經緯度或地址相互轉換
*
* @param latlng
*/
private void latlngToAddress(LatLng latlng) {
// 設定反地理經緯度座標,請求位置時,需要一個經緯度
// geoCoder.reverseGeoCode(new ReverseGeoCodeOption().location(latlng));
//設定地址或經緯度反編譯後的監聽,這裡有兩個回撥方法,
geoCoder.setOnGetGeoCodeResultListener(new OnGetGeoCoderResultListener() {
//經緯度轉換成地址
@Override
public void onGetReverseGeoCodeResult(ReverseGeoCodeResult result) {
if (result == null || result.error != SearchResult.ERRORNO.NO_ERROR) {
Toast.makeText(MainActivity.this, "找不到該地址!", Toast.LENGTH_SHORT).show();
}
// tv_address.setText("地址:" + result.getAddress());
assert result != null;
showToastShort("地址:" + result.getAddress());
}
//把地址轉換成經緯度
@Override
public void onGetGeoCodeResult(GeoCodeResult result) {
// 詳細地址轉換在經緯度
String address = result.getAddress();
}
});
// 設定反地理經緯度座標,請求位置時,需要一個經緯度
//切記一定要放在下面不然第一次長按定位不走該方法
geoCoder.reverseGeoCode(new ReverseGeoCodeOption().location(latlng));
}
/**
* 長按新增覆蓋物
*
* @param latLng
*/
private void addDestInfoOverLay(LatLng latLng) {
//清除所有的覆蓋物
mBaiduMap.clear();
OverlayOptions options = new MarkerOptions().position(latLng)
.icon(BitmapDescriptorFactory.fromResource(R.mipmap.ic_myloc))
.zIndex(5);//層數
mBaiduMap.addOverlay(options);
}