前言:
总觉得时间太少,还是得怪自己太懒.项目开发中不可避免会用到定位搜索功能、微信支付功能、微信QQ登录分享这些功能,近期的项目中又遇到类似的功能,所以不可避免得去集成这些相关的SDK,同一功能的不同SDK也是挺多家的,所以根据场景不同,也得做出相应的选择。 这篇文章就开始总结下关于定位功能的,由于最近项目使用到的是百度地图SDK,所以总结下吧!
I. 集成百度SDK
下面是百度SDK集成文档的官方地址
百度SDK集成的地址:http://lbsyun.baidu.com/index.php?title=androidsdk/guide/key
只要跟着官方开发文档的步骤,先申请app key,接着填写下面截图的资料信息,至于项目的发布版SHA1和开发版SHA1怎么获取,可以点击进去 "查看详细配置方法"进去查看如何获取sha1值;个人建议发布版sha1和开发版SHA1一致即可,一般填上发布版的正式包对应的SHA1值,那么这就需要在开发时使debug包的签名和正式包的签名一致.
下面针对项目的gradle文件进行相应的配置(基于Android Studio),使得项目的发布版和开发版使用同一签名,取得的SHA1值也一致.
android {
compileSdkVersion 23
buildToolsVersion "23.0.3"
sourceSets {
main {
//jniLibs.srcDir 'libs' //百度地图
jniLibs.srcDirs = ['libs'] //第三方so库
}
}
signingConfigs {
debug {
storeFile file("../yourapp.keystore") //签名文件路径
storePassword "your password"
keyAlias "your alias"
keyPassword "your password"
}
release {
storeFile file("../yourapp.keystore")
storePassword "your password"
keyAlias "your alias"
keyPassword "your password"
}
}
buildTypes {
debug {
// 显示Log
buildConfigField "boolean", "LOG_DEBUG", "true"
signingConfig signingConfigs.debug //debug模式下引用signingConfigs.debug的签名
//不相关的省略
}
release {
buildConfigField "boolean", "LOG_DEBUG", "false"
signingConfig signingConfigs.release
//不相关的省略
}
}
接着还是按照官方文档引入相应功能的so包和jar包,当然还有需要注意的:
- 1.比如在gradle文件添加jniLibs配置命令
- 2.项目配置依赖jar包,
关于Android Studio的配置具体的建议看官方demo.
Ⅱ. Hello BaiduMap
很熟悉的Hello World,对百度地图SDK并不了解怎么接入的话,可以先看下百度文档关于基础地图的介绍
Hello BaiduMap 文档:http://lbsyun.baidu.com/index.php?title=androidsdk/guide/hellobaidumap
注意点:
**1.下面是初始化SDK的操作,官方建议放在程序的入口处(Application类里),其实大多SDK的初始化都建议放在Application类,但在集成的同时就得考虑这么一问题,在程序在启动之时去初始化这些集成的SDK,如果集成的SDK较多,那势必会引起应用启动时间延长.所以个人觉得如果应用不是主功能的地方使用到SDK,一般情况下可以把SDK初始化操作放在activity的入口处(onCreate生命周期方法等),比如在开发的应用中个人信息中的地址选项需要用到定位功能,那么则可以在地址选项页所在的activity进行初始化定位SDK. **
public class MyDataActivity extends BaseActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
//在使用SDK各组件之前初始化context信息,传入ApplicationContext
//注意该方法要再setContentView方法之前实现
SDKInitializer.initialize(Global.getApplicationContext());
setContentView(R.layout.activity_main);
}
}
2.注意将activity与MapView的生命周期进行绑定
@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();
}
那么只需要参照Hello BaiduMap,简单的几个步骤,就可以对百度地图SDK有个大概的了解.
Ⅲ. 简单集成定位
效果图:
下面是具体的代码,详细介绍都在注释中说明
/**
*SDKInitializer.initialize()已经在JobAddressFragment
*所在的activity的onCreate方法进行调用
*/
public class JobAddressFragment extends BaseFragment{
public int radius = 20;
public LocationClient mLocationClient = null;
private MapView mBaiduMapView;
private BaiduMap mbaiduMap;
private Dialog loadingDialog;
public String mCity;
@Override
public int getLayoutRes() {
return R.layout.jobaddress;
}
@Override
public void initView() {
mBaiduMapView = findView(R.id.job_address_baidu);
mbaiduMap = mBaiduMapView.getMap();
loadingDialog = GlobalUtils.getLoadingDialog(mActivity,
GlobalUtils.getString(R.string.usercenter_edit_name_save),false);
}
@Override
public void initData() {
//检测GPS是否开启
if(!GlobalUtils.isOpenGps(Global.getContext())){
showToast(GlobalUtils.getString(R.string.usercenter_selete_address_gps_close));
return;
}
initLocation();
beginLocation();
}
//启动定位功能
private void beginLocation(){
LocationClientOption option = new LocationClientOption();//高精度
//LocationMode 可选,默认高精度,设置定位模式,高精度,低功耗,仅设备
option.setLocationMode(LocationClientOption.LocationMode.Hight_Accuracy);
option.setScanSpan(0);//可选,默认0,即仅定位一次,设置发起定位请求的间隔需要大于等于5000ms才是有效的
option.setIsNeedAddress(true);//可选,设置是否需要地址信息,默认不需要
option.setCoorType("bd09ll");
mLocationClient.setLocOption(option);
mLocationClient.start(); //开启定位
// 隐藏百度地图的logo
View child = mBaiduMapView.getChildAt(1);
if (child != null && (child instanceof ImageView || child instanceof ZoomControls)){
child.setVisibility(View.INVISIBLE);
}
mBaiduMapView.showScaleControl(false); //地图上比例尺
mBaiduMapView.showZoomControls(false); // 隐藏缩放控件
}
//定位功能进行初始化的操作
private void initLocation() {
//note 打开定位图层,显示当前位置
mbaiduMap.setMyLocationEnabled(true);
MyLocationConfiguration config = new MyLocationConfiguration(
MyLocationConfiguration.LocationMode.FOLLOWING, // 跟随态,保持定位图标在地图中心
false, // 是否显示定位指标的方向
null);// null表示使用默认图标
mbaiduMap.setMyLocationConfigeration(config);
// 创建定位对象
mLocationClient = new LocationClient(mActivity);
// 设置监听器接收搜索结果
mLocationClient.registerLocationListener(new BDLocationListener() {
@Override // 定位到数据回调此方法
public void onReceiveLocation(BDLocation location) {
if (location == null) {
return;
}
/**获取定位的信息*/
String addrStr = location.getAddrStr(); // 详细的地址信息
mCity = location.getCity(); // 城市
latitude = location.getLatitude(); // 纬度
longitude = location.getLongitude(); // 经度
/**初始化搜索配置,展开搜索*/
//initSearch();
//beginSearch();
MyLocationData datas = new MyLocationData
.Builder()
.latitude(latitude)
.longitude(longitude)
.accuracy(location.getRadius()) // accuracy: 定位的精度
.build();
mbaiduMap.setMyLocationData(datas);// 更新我的位置, 刷新界面显示
}
});
}
@Override
public void onResume() {
mBaiduMapView.setVisibility(View.VISIBLE);
mBaiduMapView.onResume();
super.onResume();
}
@Override
public void onPause() {
mBaiduMapView.setVisibility(View.INVISIBLE);
mBaiduMapView.onPause();
super.onPause();
}
@Override
public void onDestroy() {
super.onDestroy();
if(mLocationClient != null){
mLocationClient.stop(); //销毁时关闭定位
}
mBaiduMapView.onDestroy();
mBaiduMapView = null;
}
小插曲:产品的需求里,要求更换默认的定位图标,那么咋整?
更换定位图标的代码如下:
BitmapDescriptor mapIndicator = BitmapDescriptorFactory.fromResource(R.drawable.usercenter_map_indicator);
MyLocationConfiguration config = new MyLocationConfiguration(
MyLocationConfiguration.LocationMode.FOLLOWING,//NORMAL普通态//COMPASS //FOLLOWING跟随态,保持定位图标在地图中心
false, // 是否显示方向
mapIndicator);// 使用自定义图标
效果图:
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-hZWk1soV-1594979355456)(https://img-blog.csdn.net/20161212150344238?watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQveWszNzc2NTczMjE=/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/SouthEast)]
Ⅳ. 简单集成搜索(周边搜索+城市搜索)
完成定位功能的集成之后,根据需求也要完成下搜索的功能.
产品需求:要求进入该界面就开始定位,并搜索出附近的大厦,搜索框输入关键词则可以进行搜索
下面是具体的代码实现,详细介绍都在注释中说明
private PoiSearch mPoiSearch;
//初始化搜索配置
private void initSearch() {
mPoiSearch = PoiSearch.newInstance(); // 创建搜索对象
// 设置监听器
mPoiSearch.setOnGetPoiSearchResultListener(new OnGetPoiSearchResultListener() {
@Override
public void onGetPoiResult(PoiResult poiResult) {
if (poiResult == null || poiResult.error == SearchResult.ERRORNO.RESULT_NOT_FOUND){
showToast("没有搜索到结果");
return ;
}
// 搜索到的所有的结果
List<PoiInfo> allPoi = poiResult.getAllPoi();
jobAddress = new ArrayList<LocationGpsBean>();
if(allPoi!=null && allPoi.size()>0) {
for (PoiInfo info : allPoi) {
LocationGpsBean bean = new LocationGpsBean();
bean.blackName = info.name;
bean.address = info.address;
jobAddress.add(bean);
}
}else{
showToast("没有搜索到结果");
return;
}
//搜索到结果之后再移除原有的
PoiOverlay poioverlay = new PoiOverlay(mbaiduMap);
poioverlay.setData(poiResult); //设置搜索到的POI数据
mbaiduMap.clear();
poioverlay.addToMap(); //兴趣点标注在地图上
poioverlay.zoomToSpan(); //缩放地图
mAdapter = new JobAddressAdapter(mActivity, jobAddress);
if(jobAddress!=null && jobAddress.size()>0){
mAdapter.selectPosition(0);
selectGpsBean = jobAddress.get(0);
}
mLvAddressNews.setAdapter(mAdapter);
}
@Override // 详情数据
public void onGetPoiDetailResult(PoiDetailResult poiDetailResult) {
if (poiDetailResult == null || poiDetailResult.error == SearchResult.ERRORNO.RESULT_NOT_FOUND) {
showToast("没有搜索到结果");
return ;
}
String name = poiDetailResult.getName();// 名称
String address = poiDetailResult.getAddress();// 地址
LatLng location = poiDetailResult.getLocation();// 经纬度
double serviceRating = poiDetailResult.getServiceRating();// 服务星级
double environmentRating = poiDetailResult.getEnvironmentRating(); // 环境星级
String info = "name: " + name
+ " \nuid: " + poiDetailResult.getUid()
+ " \naddress: " + address
+ " \nlocation: " + location
+ " \nenvironmentRating: " + environmentRating
+ " \nserviceRating: " + serviceRating;
showToast(info);
}
});
}
private double latitude;
private double longitude;
/**一开始进行周边搜索*/
private void beginSearch() {
LatLng mCurrentPos = new LatLng(latitude,longitude);
// 设置搜索选项
PoiNearbySearchOption option = new PoiNearbySearchOption();
option.keyword("大厦"); // 搜索关键字
option.location(mCurrentPos); // 搜索的中心点
option.radius(100); // 搜索100米以内
// 发起搜索
mPoiSearch.searchNearby(option);
}
/**搜索框进行城市搜索*/
private void search() {
GlobalUtils.hideKeyboard(mEtInputSearch); //收起键盘
String searchInput = mEtInputSearch.getText().toString().trim();//输入的关键词
if(TextUtils.isEmpty(searchInput)){
showToast("搜索内容为空,请输入!");
return ;
}
//下面做搜寻的操作
if(mPoiSearch == null){
initSearch();
}
// 发起搜索,
if(!TextUtils.isEmpty(mCity)){
//mCity为定位到的城市,进行城市搜索
mPoiSearch.searchInCity((new PoiCitySearchOption())
.city(""+mCity)
.keyword(searchInput));
}else{
//如果定位不成功或定位不到城市信息的情况下,则默认搜索城市为"广州"
//虽然默认是广州,但可以对任意关键词进行搜索
mPoiSearch.searchInCity((new PoiCitySearchOption())
.city("广州")
.keyword(searchInput));
}
}
上面就是具体的搜索代码,可以看到通过在initSearch方法里对mPoiSearch设置OnGetPoiSearchResultListener监听器,发起周边搜索以及搜索框搜索都会触发OnGetPoiSearchResultListener监听器,在监听器得到所搜索到的对象信息,进行兴趣点标注及ListView的信息展示,上面代码都已注释说明.
Ⅴ.总结+发发牢骚
1.上面简单记录了百度地图的定位和搜索功能,其他功能的可以参考百度SDK官方文档;
2.上面的定位+搜索功能只是简单的展示,当然还是有问题的,比如默认城市为广州进行搜索,针对一部分关键词还是搜索不到结果的。身在开发,心得由着产品,产品需求如此,开发周期短,之后再补过;
3.最近对该文章的功能进行了修改和优化,另找时间总结总结;
4.回首呆望,个把月没写博客咯,2016年的最后一个月了,抓紧时间总结,别让项目的无厘头需求改动搅乱了自己,加油!