写在前面
本来想使用百度定位的SDK把定位功能实现了,可无奈遇上个坑到写这篇blog为止都还没有解决。故所以把使用百度地图SDK实现简单的POI检索功能和遇到的坑先做一个总结。
下载.os和jar包
坑
1. 如果需要使用自定义的功能,最好不要分别下载。
例如之前我只是想先简单的实现POI检索功能,所以只下载了跟百度地图相关的SDK,实现了之后觉得单调,决定加入定位功能的时候再单独去下载了定位相关的SDK,坑就出现了,引入.os和jar之后,
出现 java.lang.NoSuchMethodError: No direct method <init>
这样的错误。只要我们下载的时候勾选要下载的SDK统一下载,就不会出现这样的bug了。
2.jar和.os引入之后,仍然无法使用(初始化SDK)。
解决方案是在app的build.gradle加入
android{
...
sourceSets {
main() {
jniLibs.srcDirs = ['libs']
}
}
}
这在地图的文档没有说到,但在定位的文档才可以找到。小小的吐槽一下百度文档…
地图初始化
- 添加密匙 (申请百度账号,密匙在这里就不写了。很简单)
<application>
<meta-data
android:name="com.baidu.lbsapi.API_KEY"
android:value="开发者 key" />
</application>
- 添加所需权限
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE"/>
<uses-permission android:name="android.permission.INTERNET"/>
<uses-permission android:name="com.android.launcher.permission.READ_SETTINGS" />
<uses-permission android:name="android.permission.WAKE_LOCK"/>
<uses-permission android:name="android.permission.CHANGE_WIFI_STATE" />
<uses-permission android:name="android.permission.ACCESS_WIFI_STATE" />
<uses-permission android:name="android.permission.GET_TASKS" />
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
<uses-permission android:name="android.permission.WRITE_SETTINGS" />
- 在布局xml文件中添加地图控件
<com.baidu.mapapi.map.MapView
android:id="@+id/bmapView"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:clickable="true" />
- 在应用程序创建时初始化 SDK
public class MyApplication extends Application {
@Override
public void onCreate() {
super.onCreate();
/***
* 初始化定位sdk,建议在Application中创建
*/
SDKInitializer.initialize(getApplicationContext());
}
}
- 管理地图生命周期
@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();
}
}
当然,还要在你的AndroidManifest中把你的Application设置成我们自定义的MyApplication
完成以上步骤运行,就能把地图显示出来,在没实现定位功能之前,初始化位置是在北京。
POI检索
- 初始化POI检索对象
/**
*实例化
*/
PoiSearch mPoiSearch = PoiSearch.newInstance();
/**
*回调
*/
OnGetPoiSearchResultListener poiListener = new OnGetPoiSearchResultListener(){
@Override
public void onGetPoiResult(PoiResult result){
//获取POI检索结果
}
@Override
public void onGetPoiDetailResult(PoiDetailResult result){
//获取Place详情页检索结果
}
@Override
public void onGetPoiIndoorResult(PoiIndoorResult poiIndoorResult) {
//获取门址类列表
}
};
/**
*设置监听
*/
mPoiSearch.setOnGetPoiSearchResultListener(poiListener);
- 检索
城市检索
mPoiSearch.searchInCity((new PoiCitySearchOption())
.city("深圳")//城市
.keyword("美食")//检索关键字
.pageNum(0)//分页编码
.pageCapacity(5));//每页容量,默认10条
周边检索
mPoiSearch.searchNearby(new PoiNearbySearchOption()
//搜索结果排序规则,PoiSortType.comprehensive->距离排序
.sortType(PoiSortType.comprehensive) ->综合排序;
.radius(1000)//检索半径范围,单位:米
.location(LatLng location)) //检索位置
区域检索
mPoiSearch.searchInBound(new PoiBoundSearchOption()
.bound(LatLngBounds bound)//检索范围
);
构建LatLngBounds对象
LatLng southwest = new LatLng(latitude - 0.01, longitude - 0.012);// 西南
LatLng northeast = new LatLng(latitude + 0.01, longitude + 0.012);// 东北
LatLngBounds bounds = new LatLngBounds.Builder().include(southwest)
.include(northeast).build();// 得到一个地理范围对象
所有检索的结果都在poiListener中回调
在每一个POI中都包含一个”Uid”的字段,如果我们需要知道某个POI的详情,我们可以
mPoiSearch.searchPoiDetail((new PoiDetailSearchOption()).poiUid(uid));
检索的结果同样是在poiListener中回调
详细的文档内容在这里
在回调中得到的是一条条的信息,纯文本看着多没意思,展示的地图还没用上。那我们就可以给每个检索出来的POI在地图上标注起来,瞬间好玩多了!
- 覆盖物
自定义 PoiOverlay 类
private class MyPoiOverlay extends PoiOverlay {
public MyPoiOverlay(BaiduMap baiduMap) {
super(baiduMap);
}
@Override
public boolean onPoiClick(int index) {
super.onPoiClick(index);
return true;
}
}
在POI检索回调接口中添加自定义的PoiOverlay
public void onGetPoiResult(PoiResult result) {
if (result == null || result.error == SearchResult.ERRORNO.RESULT_NOT_FOUND) {
return;
}
if (result.error == SearchResult.ERRORNO.NO_ERROR) {
mBaiduMap.clear();
//创建PoiOverlay
PoiOverlay overlay = new MyPoiOverlay(mBaiduMap);
//设置overlay可以处理标注点击事件
mBaiduMap.setOnMarkerClickListener(overlay);
//设置PoiOverlay数据
overlay.setData(result);
//添加PoiOverlay到地图中
overlay.addToMap();
overlay.zoomToSpan();
return;
}
}
这样,检索出来的POI在地图上就完成标注了
写到这里,简单的地图的POI功能就完成了。
写在最后
简简单单的POI检索当然不能满足我们日益膨胀的心呀!所以现在努力实现定位的功能,到时候再更新blog,分享给那些还没了解定位但即将使用的筒靴一个开篇指引和遇到的坑。加油!
note:
在覆盖物中设计到两个类:PoiOverlay 和OverlayManager在SDK中是没有的,但在官方的Demo中有给出。这里是给没有下载Demo的筒靴的一个帮助,希望可以共同进步!