前言:百度的定位sdk可以获取设备当前的详细信息,如经纬度,具体地址(省->街道)等,
本文主要使用的是定位sdk和地图sdk中的poi搜索功能(以当前位置半径多少米内的关键词搜索)
目录
插入下百度的官方文档:
一、准备工作
1.注册百度的开发者账号
2.在控制台中创建应用,选择Android平台
需要传入包名和sha1值,sha1值可以通过运行AndroidStruido的右侧Gradle中的这个Task获取,
3.获取到访问应用(AK)
二、项目
1.添加百度 Key
项目的 “AndroidManifest.xml” 文件中,添加如下代码:
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION"/>
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION"/>
<uses-permission android:name="android.permission.INTERNET" />
<application
...... >
<meta-data
android:name="com.baidu.lbsapi.API_KEY"
android:value="你的应用AK" />
……
</application>
2.代码混淆
在app模块中的proguard-rules.pro文件中添加一下代码
-keep class com.baidu.** {*;}
-keep class vi.com.** {*;}
-keep class com.baidu.vi.** {*;}
-dontwarn com.baidu.**
3.导入具体的sdk
在app模块下的build.gradle中的中添加以下语句
android {
...
buildTypes {
release {
...
proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro'
}
}
}
dependencies {
implementation 'com.baidu.lbsyun:BaiduMapSDK_Search:7.6.4'
implementation 'com.baidu.lbsyun:BaiduMapSDK_Util:7.6.4'
implementation 'com.baidu.lbsyun:BaiduMapSDK_Location:9.6.0'
}
4.新建地图相关类
public class MyLocation {
private double latitude;
private double longitude;
private String country;
private String province;
private String city;
private String district;
private String street;
private String address;
public double getLatitude() {
return latitude;
}
public void setLatitude(double latitude) {
this.latitude = latitude;
}
public double getLongitude() {
return longitude;
}
public void setLongitude(double longitude) {
this.longitude = longitude;
}
public String getCountry() {
return country;
}
public void setCountry(String country) {
this.country = country;
}
public String getProvince() {
return province;
}
public void setProvince(String province) {
this.province = province;
}
public String getCity() {
return city;
}
public void setCity(String city) {
this.city = city;
}
public String getDistrict() {
return district;
}
public void setDistrict(String district) {
this.district = district;
}
public String getStreet() {
return street;
}
public void setStreet(String street) {
this.street = street;
}
public String getAddress() {
return address;
}
public void setAddress(String address) {
this.address = address;
}
@Override
public String toString() {
return "MyLocation{" +
"latitude=" + latitude +
", longitude=" + longitude +
", country='" + country + '\'' +
", province='" + province + '\'' +
", city='" + city + '\'' +
", district='" + district + '\'' +
", street='" + street + '\'' +
", address='" + address + '\'' +
'}';
}
}
public interface LocationFuc {
void startLocation(LocationCallback locationCallback);
interface LocationCallback {
void locationResult(MyLocation myLocation);
void failure();
}
}
具体定位类:
import android.content.Context;
import com.baidu.location.BDAbstractLocationListener;
import com.baidu.location.BDLocation;
import com.baidu.location.LocationClient;
import com.baidu.location.LocationClientOption;
import com.baidu.mapapi.SDKInitializer;
import com.baidu.mapapi.common.BaiduMapSDKException;
public class BaiduLocationFuc implements LocationFuc {
LocationClient mLocationClient;
public BaiduLocationFuc(Context context) {
// java
// 是否同意隐私政策,默认为false
SDKInitializer.setAgreePrivacy(context.getApplicationContext(), true);
try {
// 在使用 SDK 各组间之前初始化 context 信息,传入 ApplicationContext
SDKInitializer.initialize(context.getApplicationContext());
} catch (BaiduMapSDKException e) {
e.printStackTrace();
}
LocationClient.setAgreePrivacy(true);
try {
mLocationClient = new LocationClient(context.getApplicationContext());
LocationClientOption option = new LocationClientOption();
option.setLocationMode(LocationClientOption.LocationMode.Battery_Saving);
//可选,设置定位模式,默认高精度
//LocationMode.Hight_Accuracy:高精度;
//LocationMode. Battery_Saving:低功耗;
//LocationMode. Device_Sensors:仅使用设备;
//LocationMode.Fuzzy_Locating, 模糊定位模式;v9.2.8版本开始支持,可以降低API的调用频率,但同时也会降低定位精度;
option.setCoorType("bd09ll");
//可选,设置返回经纬度坐标类型,默认gcj02
//gcj02:国测局坐标;
//bd09ll:百度经纬度坐标;
//bd09:百度墨卡托坐标;
//海外地区定位,无需设置坐标类型,统一返回wgs84类型坐标
option.setFirstLocType(LocationClientOption.FirstLocType.SPEED_IN_FIRST_LOC);
option.setOnceLocation(true);
option.setIsNeedAddress(true);
//可选,首次定位时可以选择定位的返回是准确性优先还是速度优先,默认为速度优先
//可以搭配setOnceLocation(Boolean isOnceLocation)单次定位接口使用,当设置为单次定位时,setFirstLocType接口中设置的类型即为单次定位使用的类型
//FirstLocType.SPEED_IN_FIRST_LOC:速度优先,首次定位时会降低定位准确性,提升定位速度;
//FirstLocType.ACCUARACY_IN_FIRST_LOC:准确性优先,首次定位时会降低速度,提升定位准确性;
option.setScanSpan(30000);
//可选,设置发起定位请求的间隔,int类型,单位ms
//如果设置为0,则代表单次定位,即仅定位一次,默认为0
//如果设置非0,需设置1000ms以上才有效
// option.setOpenGnss(true);
//可选,设置是否使用卫星定位,默认false
//使用高精度和仅用设备两种定位模式的,参数必须设置为true
// option.setLocationNotify(true);
//可选,设置是否当卫星定位有效时按照1S/1次频率输出卫星定位结果,默认false
// option.setIgnoreKillProcess(false);
//可选,定位SDK内部是一个service,并放到了独立进程。
//设置是否在stop的时候杀死这个进程,默认(建议)不杀死,即setIgnoreKillProcess(true)
option.SetIgnoreCacheException(false);
//可选,设置是否收集Crash信息,默认收集,即参数为false
// option.setWifiCacheTimeOut(5*60*1000);
//可选,V7.2版本新增能力
//如果设置了该接口,首次启动定位时,会先判断当前Wi-Fi是否超出有效期,若超出有效期,会先重新扫描Wi-Fi,然后定位
// option.setEnableSimulateGnss(false);
//可选,设置是否需要过滤卫星定位仿真结果,默认需要,即参数为false
// option.setNeedNewVersionRgc(true);
//可选,设置是否需要最新版本的地址信息。默认需要,即参数为true
mLocationClient.setLocOption(option);
mLocationClient.registerLocationListener(bdAbstractLocationListener);
//mLocationClient为第二步初始化过的LocationClient对象
//需将配置好的LocationClientOption对象,通过setLocOption方法传递给LocationClient对象使用
//更多LocationClientOption的配置,请参照类参考中LocationClientOption类的详细说明
} catch (Exception e) {
e.printStackTrace();
}
}
private BDAbstractLocationListener bdAbstractLocationListener = new BDAbstractLocationListener() {
@Override
public void onReceiveLocation(BDLocation location) {
mLocationClient.stop();
double latitude = location.getLatitude(); //获取纬度信息
double longitude = location.getLongitude(); //获取经度信息
float radius = location.getRadius(); //获取定位精度,默认值为0.0f
String coorType = location.getCoorType();
//获取经纬度坐标类型,以LocationClientOption中设置过的坐标类型为准
int errorCode = location.getLocType();
MyLocation myLocation = new MyLocation();
myLocation.setLatitude(latitude);
myLocation.setLongitude(longitude);
myLocation.setCountry(location.getCountry());
myLocation.setProvince(location.getProvince());
myLocation.setCity(location.getCity());
myLocation.setDistrict(location.getDistrict());
myLocation.setStreet(location.getStreet());
myLocation.setAddress(location.getAddrStr());
if (locationCallback != null) {
locationCallback.locationResult(myLocation);
}
}
};
LocationCallback locationCallback;
@Override
public void startLocation(LocationCallback locationCallback) {
this.locationCallback = locationCallback;
mLocationClient.start();
}
}
通过定位进行poi搜索的方法
Executor executorService = Executors.newFixedThreadPool(4); //线程池 可直接创建子线程代替
public void searchBaiduPoi(Context context, MyLocation locationResult, String key) {
executorService.execute(new Runnable() {
@Override
public void run() {
com.baidu.mapapi.search.poi.PoiSearch poiSearch = com.baidu.mapapi.search.poi.PoiSearch.newInstance();
poiSearch.setOnGetPoiSearchResultListener(new OnGetPoiSearchResultListener() {
@Override
public void onGetPoiResult(com.baidu.mapapi.search.poi.PoiResult poiResult) {
if (poiResult.error != SearchResult.ERRORNO.NO_ERROR) {
if (poiResult != null) {
List<PoiInfo> allPoi = poiResult.getAllPoi();
//这里就拿到poi列表了
}
}
}
@Override
public void onGetPoiDetailResult(PoiDetailResult poiDetailResult) {
}
@Override
public void onGetPoiDetailResult(PoiDetailSearchResult poiDetailSearchResult) {
}
@Override
public void onGetPoiIndoorResult(PoiIndoorResult poiIndoorResult) {
}
});
poiSearch.searchNearby(new PoiNearbySearchOption()
.location(new LatLng(locationResult.getLatitude(), locationResult.getLongitude()))
.radius(20000).keyword(key) // 输入搜索的半径(m) 和关键词 如:小区
.pageNum(0));
}
});
}
6.在activity/fragment中使用
/* 在运行下面代码时,应该先动态申请
Manifest.permission.ACCESS_COARSE_LOCATION,
Manifest.permission.ACCESS_FINE_LOCATION
这两个权限*/
locationFuc.startLocation(new LocationFuc.LocationCallback() {
@Override
public void locationResult(MyLocation myLocation) {
//这里就已经获取到了位置信息,进行别的操作
如:调用searchBaiduPoi方法进行poi搜索
}
@Override
public void failure() {
}
});