一、SDK版本v2.0.0初探 一、开发前的准备工作: 1、注册百度账号,并登录。(有百度账号的话直接登录) 2、申请Key,地址:http://developer.baidu.com/map/android-mobile-apply-key.htm 注:经研究发现在申请KEY时,应用名称一定要写成my_app_应用名(也就是说"my_app_"是必须要有的)这样,生成的API密钥后面才可用。其他格式的也可以生成API密钥,但是在使用过程中会出问题。(比如:一开始就报授权Key错误,或者使用一段时间后就不行了) 3、下载SDK(v2.0.0),地址:http://developer.baidu.com/map/sdkandev-download.htm 注:下载Android SDKv2.0.0 (矢量地图版),里面有BaiduMap_AndroidSDK_v2.0.0_Lib.zip、BaiduMap_AndroidSDK_v2.0.0_Docs.zip和BaiduMap_AndroidSDK_v2.0.0_Sample.zip三个压缩包。 二、搭建开发环境,开始The world, hello(世界,你好)之旅: 1、创建android项目,在选SDK时(Choose an SDK to target),选的不是Google APIs,是不带地图服务的SDK 。 2、在项目创建完毕,在工程里新建libs文件夹,将开发包(BaiduMap_AndroidSDK_v2.0.0_Lib.zip)里的baidumapapi_v2_0_0.jar拷贝到libs根目录下,将libBMapApiEngine_v2_0_0.so和libvi_voslib.so 拷贝到libs\armeabi目录下,拷贝完成后的工程目录如下图所示:
3、在AndroidManifest.xml文件中添加使用权限: 4、添加对多种屏幕的支持: 5、配置Activity: 6、在布局xml文件中添加地图控件:7、 创建地图Activity,并import相关类: a. 创建地图引擎管理类对象,并初始化。 b.通过ID获取代表地图显示组件的MapView对象,并设置启用内置的缩放控件。 c.获取地图控制器对象,并设置地图的中心点及缩放级别。 d.重写Activity的生命周期回调方法onResume()、onPause()和onDestroy(),管理地图引擎管理类对象和显示对象生命周期。经过以上这些步骤,加载的是上海市浦东新区地图(基础图),运行工程效果图如下: 注:基本的地图图层,包括若干个缩放级别,显示基本的地图信息,包括道路、街道、学校、公园等内容。
e.在地图中显示实时交通信息示图(当前,全国范围内已支持多个城市实时路况查询,且会陆续开通其他城市。) 运行效果图如下:
f.显示卫星图(卫星地图是卫星拍摄的真实的地理面貌,所以卫星地图可用来检测地面的信息,你可以了解到地理位置,地形等。) 运行效果图如下:
完整代码如下:
|
阐述一个概念,地图覆盖物:所有叠加或覆盖到地图的内容,我们统称为地图覆盖物。如标注、矢量图形元素(包括:折线和多边形和圆)、定位图标等。覆盖物拥有自己的地理坐标,当您拖动或缩放地图时,它们会相应的移动。
要实现的需求:假如我们知道北京天安门(建筑物)的GPS纬度经度值:39.915,116.404,想要把它在百度地图上标注出来。
实现上述需求的步骤:
一、准备工作:
1、创建android工程,并导入百度地图需要用到的jar包和so文件。
2、在AndroidManifest文件中添加使用百度地图SDK所需的权限及屏幕配置。
3、在布局文件layout中添加显示百度地图的MapView。
4、在继承了Activity类的子类中:
a. 创建并初始化地图引擎管理对象;
b. 通过组件ID获取代表地图显示View的MapView对象,并设置相应属性。
(比如:启用内置的缩放控件、设置允许的地图缩放级别等)
c. 重写Activity的生命周期回调方法onResume()、onPause()和onDestroy(),管理地图引擎管理类对象和显示对象生命周期。
5、详细的请阅读上一篇:Android 百度地图SDK (v2.0.0)初探
二、在地图上标注出北京天安门:
1、想要在地图上标注一个建筑物,总得有一个标识吧?
获取在地图上标识建筑物的图标对象:
[mw_shl_code=java,true] // 获取用于在地图上标注一个地理坐标点的图标
Drawable drawable = this.getResources().getDrawable(R.drawable.icon_marka);[/mw_shl_code]
2、在基础图上添加覆盖物(添加图层)
a. 编写覆盖物类,自己定义一个类,继承自ItemizedOverlay<OverlayItem>类,需要重写父类的构造函数、createItem(int index)和size()方法。
注:从2.0.0开始,SDK不支持直接继承Overlay , 用户可通过继承ItemizedOverlay来添加覆盖物。
b. 在自定义的覆盖物类(继承自ItemizedOverlay<OverlayItem>)中, 声明一个用于存放覆盖物的集合:
[mw_shl_code=java,true]/**覆盖物列表集合*/private ArrayList<OverlayItem> mOverlayList = new ArrayList<OverlayItem>();[/mw_shl_code]
声明double类型的变量存储北京天安门的纬度、经度值:
[mw_shl_code=java,true] // 声明double类型的变量存储北京天安门的纬度、经度值
private double mLat1 = 39.915; // point1纬度
private double mLon1 = 116.404; // point1经度[/mw_shl_code]
c. 在构造函数中,将GPS纬度经度值转换成以微度的整数形式存储的地理坐标点
[mw_shl_code=java,true] /* 注:GeoPoint对象构造方法的参数列表:第一个是参数表示纬度,第二个是经度
(我们平时都是经纬度这么叫的,想着应该是经度在前的,呵呵。)
在网上查了下,GPS的值官方给的就是纬度经度,也就是说纬度是在前的,以前一直没太注意。*/
GeoPoint geoPoint1 = new GeoPoint((int) (mLat1 * 1E6), (int) (mLon1 * 1E6));[/mw_shl_code]
构造OverlayItem对象并添加到mOverlayList集合里
[mw_shl_code=java,true]mOverlayList.add(new OverlayItem(geoPoint1, "point1", "point1"));[/mw_shl_code]
必须调用的方法:
[mw_shl_code=java,true] /*
* 官方的解释:在一个新ItemizedOverlay上执行所有操作的工具方法。
* 没搞明白啥意思,但是必须的调用这个方法,否则程序运行报错*/
populate();[/mw_shl_code]
d. 返回的是从指定List集合中,取出的一个OverlayItem对象。
[mw_shl_code=java,true] /*
* 返回的是从指定List集合中,取出的一个OverlayItem对象。
* mOverlayList集合里一旦有了数据,在调用其之前,
* 一定的在MyOverlayItem的构造函数里调用这个方法populate();
*/
@Override
protected OverlayItem createItem(int index) {
return mOverlayList.get(index);
}[/mw_shl_code]
e. 获取当前覆盖物列表的大小
[mw_shl_code=java,true] @Override
public int size() {
return mOverlayList.size();
}[/mw_shl_code]
自定义的覆盖物类的完整代码:
[mw_shl_code=java,true] /**
* 包含了一个覆盖物列表的覆盖物类
* @author android_ls
*/
final class MyOverlayItem extends ItemizedOverlay<OverlayItem> {
/**覆盖物列表集合*/
private ArrayList<OverlayItem> mOverlayList = new ArrayList<OverlayItem>();
// 声明double类型的变量存储北京天安门的纬度、经度值
private double mLat1 = 39.915; // point1纬度
private double mLon1 = 116.404; // point1经度
// 传进来的Drawable对象用于在地图上标注一个地理坐标点
public MyOverlayItem(Drawable drawable) {
super(drawable);
// 将GPS纬度经度值转换成以微度的整数形式存储的地理坐标点
/* 注:GeoPoint对象构造方法的参数列表:第一个是参数表示纬度,第二个是经度
(我们平时都是经纬度这么叫的,想着应该是经度在前的,呵呵。)
在网上查了下,GPS的值官方给的就是纬度经度,也就是说纬度是在前的,以前一直没太注意。*/
GeoPoint geoPoint1 = new GeoPoint((int) (mLat1 * 1E6), (int) (mLon1 * 1E6));
// 构造OverlayItem对象并添加到mOverlayList集合里
mOverlayList.add(new OverlayItem(geoPoint1, "point1", "point1"));
/*
* 官方的解释:在一个新ItemizedOverlay上执行所有操作的工具方法。
* 没搞明白啥意思,但是必须的调用这个方法,否则程序运行报错*/
populate();
}
/*
* 返回的是从指定List集合中,取出的一个OverlayItem对象。
* mOverlayList集合里一旦有了数据,在调用其之前,
* 一定的在MyOverlayItem的构造函数里调用这个方法populate();
*/
@Override
protected OverlayItem createItem(int index) {
return mOverlayList.get(index);
}
@Override
public int size() {
return mOverlayList.size();
}
}[/mw_shl_code]
创建覆盖物(MyOverlayItem)对象并添加到覆盖物列表中:
[mw_shl_code=java,true] mMapView.getOverlays().add(new MyOverlayItem(drawable));[/mw_shl_code]
3、刷新地图
[mw_shl_code=java,true]mMapView.refresh();[/mw_shl_code]
运行效果图如下:
完整代码:
[mw_shl_code=java,true]package com.android.baidu.map;
import java.util.ArrayList;
import android.app.Activity;
import android.graphics.drawable.Drawable;
import android.os.Bundle;
import android.widget.Toast;
import com.baidu.mapapi.BMapManager;
import com.baidu.mapapi.MKGeneralListener;
import com.baidu.mapapi.map.ItemizedOverlay;
import com.baidu.mapapi.map.MKEvent;
import com.baidu.mapapi.map.MapController;
import com.baidu.mapapi.map.MapView;
import com.baidu.mapapi.map.OverlayItem;
import com.baidu.platform.comapi.basestruct.GeoPoint;
/**
* 在地图上标注已知GPS纬度经度值的建筑物
* 场景:假如我们知道北京天安门(建筑物)的GPS纬度经度值:39.915,116.404,想要把它在地图上标注出来。
* @author android_ls
*
*/
public class BaiduMapOverlayActivity extends Activity {
/**地图引擎管理类*/
private BMapManager mBMapManager = null;
/**显示地图的View*/
private MapView mMapView = null;
/**
* 经研究发现在申请KEY时:应用名称一定要写成my_app_应用名(也就是说"my_app_"是必须要有的)。
* 百度地图SDK提供的服务是免费的,接口无使用次数限制。您需先申请密钥(key),才可使用该套SDK。
* */
public static final String BAIDU_MAP_KEY = "07418AEC69BAAB7104C6230A6120C580DFFAEEBB";
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
// 注意:请在调用setContentView前初始化BMapManager对象,否则会报错
mBMapManager = new BMapManager(this.getApplicationContext());
mBMapManager.init(BAIDU_MAP_KEY, new MKGeneralListener() {
@Override
public void onGetNetworkState(int iError) {
if (iError == MKEvent.ERROR_NETWORK_CONNECT) {
Toast.makeText(BaiduMapOverlayActivity.this.getApplicationContext(),
"您的网络出错啦!",
Toast.LENGTH_LONG).show();
}
}
@Override
public void onGetPermissionState(int iError) {
if (iError == MKEvent.ERROR_PERMISSION_DENIED) {
// 授权Key错误:
Toast.makeText(BaiduMapOverlayActivity.this.getApplicationContext(),
"请在 DemoApplication.java文件输入正确的授权Key!",
Toast.LENGTH_LONG).show();
}
}
});
setContentView(R.layout.main);
mMapView = (MapView) this.findViewById(R.id.bmapsView);
// 设置启用内置的缩放控件
mMapView.setBuiltInZoomControls(true);
// 获取地图控制器,可以用它控制平移和缩放
MapController mMapController = mMapView.getController();
// 设置地图的缩放级别。 这个值的取值范围是[3,18]。
mMapController.setZoom(13);
// 获取用于在地图上标注一个地理坐标点的图标
Drawable drawable = this.getResources().getDrawable(R.drawable.icon_marka);
// 创建覆盖物(MyOverlayItem)对象并添加到覆盖物列表中
mMapView.getOverlays().add(new MyOverlayItem(drawable));
// 刷新地图
mMapView.refresh();
}
/**
* 包含了一个覆盖物列表的覆盖物类
* @author android_ls
*/
final class MyOverlayItem extends ItemizedOverlay<OverlayItem> {
/**覆盖物列表集合*/
private ArrayList<OverlayItem> mOverlayList = new ArrayList<OverlayItem>();
// 声明double类型的变量存储北京天安门的纬度、经度值
private double mLat1 = 39.915; // point1纬度
private double mLon1 = 116.404; // point1经度
// 传进来的Drawable对象用于在地图上标注一个地理坐标点
public MyOverlayItem(Drawable drawable) {
super(drawable);
// 将GPS纬度经度值转换成以微度的整数形式存储的地理坐标点
/* 注:GeoPoint对象构造方法的参数列表:第一个是参数表示纬度,
* 第二个是经度(我们平时都是经纬度这么叫的,想着应该是经度在前的,呵呵。)
* 在网上查了下,GPS的值官方给的就是纬度经度,也就是说纬度是在前的,以前一直没太注意。*/
GeoPoint geoPoint1 = new GeoPoint(
(int) (mLat1 * 1E6),
(int) (mLon1 * 1E6));
// 构造OverlayItem对象并添加到mOverlayList集合里
mOverlayList.add(new OverlayItem(geoPoint1, "point1", "point1"));
/*
* 官方的解释:在一个新ItemizedOverlay上执行所有操作的工具方法。
* 没搞明白啥意思,但是必须的调用这个方法,否则程序运行报错*/
populate();
}
/*
* 返回的是从指定List集合中,取出的一个OverlayItem对象。
* mOverlayList集合里一旦有了数据,在调用其之前,
* 一定的在MyOverlayItem的构造函数里调用这个方法populate();
*/
@Override
protected OverlayItem createItem(int index) {
return mOverlayList.get(index);
}
@Override
public int size() {
return mOverlayList.size();
}
}
// 重写以下方法,管理API
@Override
protected void onResume() {
mMapView.onResume();
if (mBMapManager != null) {
mBMapManager.start();
}
super.onResume();
}
@Override
protected void onPause() {
mMapView.onPause();
if (mBMapManager != null) {
mBMapManager.stop();
}
super.onPause();
}
@Override
protected void onDestroy() {
mMapView.destroy();
if (mBMapManager != null) {
mBMapManager.destroy();
mBMapManager = null;
}
super.onDestroy();
}
}[/mw_shl_code]
三、在地图上标注出北京天安门附近的几个点:
从2.0.0开始,SDK不支持直接继承Overlay 。 在地图上显示一个或一组覆盖物,都可以通过继承ItemizedOverlay来添加覆盖物。
在上面讲解的基础上,修改覆盖物类的部分代码就可以了。直接上代码:
[mw_shl_code=java,true] class MyOverlayItem extends ItemizedOverlay<OverlayItem> {
/**覆盖物列表集合*/
private ArrayList<OverlayItem> mOverlayList = new ArrayList<OverlayItem>();
// 场景:假如我们有一组建筑物的GPS经纬度值,想要把这些建筑物在地图上标注出来。
private double mLat1 = 39.90923; // point1纬度
private double mLon1 = 116.397428; // point1经度
private double mLat2 = 39.9022;// point2纬度
private double mLon2 = 116.3922; // point2经度
private double mLat3 = 39.917723; // point3纬度
private double mLon3 = 116.3722; // point3纬度
private double mLat4 = 39.915; // point4纬度
private double mLon4 = 116.404; // point4经度
// 传进来的Drawable对象用于在地图上标注一个地理坐标点
public MyOverlayItem(Drawable drawable) {
super(drawable);
// 将GPS纬度经度值转换成以微度的整数形式存储的地理坐标点
/* 注:GeoPoint对象构造方法的参数列表:第一个是参数表示纬度,第二个是经度
(我们平时都是经纬度这么叫的,想着应该是经度在前的,呵呵。)
在网上查了下,GPS的值官方给的就是纬度经度,也就是说纬度是在前的,以前一直没太注意。*/
GeoPoint geoPoint1 = new GeoPoint((int) (mLat1 * 1E6), (int) (mLon1 * 1E6));
GeoPoint geoPoint2 = new GeoPoint((int) (mLat2 * 1E6), (int) (mLon2 * 1E6));
GeoPoint geoPoint3 = new GeoPoint((int) (mLat3 * 1E6), (int) (mLon3 * 1E6));
GeoPoint geoPoint4 = new GeoPoint((int) (mLat4 * 1E6), (int) (mLon4 * 1E6));
// 构造OverlayItem对象并添加到mOverlayList集合里
mOverlayList.add(new OverlayItem(geoPoint1, "point1", "point1"));
mOverlayList.add(new OverlayItem(geoPoint2, "point2", "point2"));
mOverlayList.add(new OverlayItem(geoPoint3, "point3", "point3"));
mOverlayList.add(new OverlayItem(geoPoint4, "point4", "point4"));
// 必须的调用这个方法,否则程序运行报错
populate();
}
/*
* 返回的是从指定List集合中,取出的一个OverlayItem对象。
* mOverlayList集合里一旦有了数据,在调用其之前,
* 一定的在MyOverlayItem的构造函数里调用这个方法populate();
*/
@Override
protected OverlayItem createItem(int index) {
return mOverlayList.get(index);
}
@Override
public int size() {
return mOverlayList.size();
}
}[/mw_shl_code]
对代码进行优化:
GPSPonit 实体类:
[mw_shl_code=java,true]package com.android.baidu.map.entity;
/**
* 类名: Ponit.java
* 功能描述:存放GPS纬度、经度值
* @author android_ls
* 创建日期: 2013-2-10 下午07:43:47
* @version V1.0
*/
public class GPSPonit {
private double mLat; // 纬度
private double mLon; // 经度
public double getmLat() {
return mLat;
}
public void setmLat(double mLat) {
this.mLat = mLat;
}
public double getmLon() {
return mLon;
}
public void setmLon(double mLon) {
this.mLon = mLon;
}
public GPSPonit(double mLat, double mLon) {
this.mLat = mLat;
this.mLon = mLon;
}
public GPSPonit() {
}
@Override
public String toString() {
return "Ponit [mLat=" + mLat + ", mLon=" + mLon + "]";
}
}[/mw_shl_code]
优化后的Activity类:
[mw_shl_code=java,true]package com.android.baidu.map;
import java.util.ArrayList;
import android.app.Activity;
import android.graphics.drawable.Drawable;
import android.os.Bundle;
import android.widget.Toast;
import com.android.baidu.map.entity.GPSPonit;
import com.baidu.mapapi.BMapManager;
import com.baidu.mapapi.MKGeneralListener;
import com.baidu.mapapi.map.ItemizedOverlay;
import com.baidu.mapapi.map.MKEvent;
import com.baidu.mapapi.map.MapController;
import com.baidu.mapapi.map.MapView;
import com.baidu.mapapi.map.OverlayItem;
import com.baidu.platform.comapi.basestruct.GeoPoint;
/**
* 在地图上标注已知GPS纬度经度值的一组建筑物
* @author android_ls
*
*/
public class BaiduMapOverlayItemsActivity extends Activity {
/**地图引擎管理类*/
private BMapManager mBMapManager = null;
/**显示地图的View*/
private MapView mMapView = null;
/**
* 经研究发现在申请KEY时:应用名称一定要写成my_app_应用名(也就是说"my_app_"是必须要有的)。
* 百度地图SDK提供的服务是免费的,接口无使用次数限制。您需先申请密钥(key),才可使用该套SDK。
* */
public static final String BAIDU_MAP_KEY = "07418AEC69BAAB7104C6230A6120C580DFFAEEBB";
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
// 注意:请在调用setContentView前初始化BMapManager对象,否则会报错
mBMapManager = new BMapManager(this.getApplicationContext());
mBMapManager.init(BAIDU_MAP_KEY, new MKGeneralListener() {
@Override
public void onGetNetworkState(int iError) {
if (iError == MKEvent.ERROR_NETWORK_CONNECT) {
Toast.makeText(BaiduMapOverlayItemsActivity.this.getApplicationContext(),
"您的网络出错啦!",
Toast.LENGTH_LONG).show();
}
}
@Override
public void onGetPermissionState(int iError) {
if (iError == MKEvent.ERROR_PERMISSION_DENIED) {
// 授权Key错误:
Toast.makeText(BaiduMapOverlayItemsActivity.this.getApplicationContext(),
"请在 DemoApplication.java文件输入正确的授权Key!",
Toast.LENGTH_LONG).show();
}
}
});
setContentView(R.layout.main);
mMapView = (MapView) this.findViewById(R.id.bmapsView);
// 设置启用内置的缩放控件
mMapView.setBuiltInZoomControls(true);
// 获取地图控制器,可以用它控制平移和缩放
MapController mMapController = mMapView.getController();
// 设置地图的缩放级别。 这个值的取值范围是[3,18]。
mMapController.setZoom(13);
//TODO 构建一组数据
GPSPonit gp1 = new GPSPonit(39.90923, 116.397428);
GPSPonit gp2 = new GPSPonit(39.9022, 116.3922);
GPSPonit gp3 = new GPSPonit(39.917723, 116.3722);
GPSPonit gp4 = new GPSPonit(39.915, 116.404);
/**存放GPS纬度、经度值的数组*/
GPSPonit[] mGPSPonit = new GPSPonit[4];
mGPSPonit[0] = gp1;
mGPSPonit[1] = gp2;
mGPSPonit[2] = gp3;
mGPSPonit[3] = gp4;
Drawable drawable = this.getResources().getDrawable(R.drawable.icon_marka);
// 创建覆盖物(MyOverlayItem)对象并添加到覆盖物列表中
mMapView.getOverlays().add(new MyOverlayItem(drawable, mGPSPonit));
// 刷新地图
mMapView.refresh();
}
final class MyOverlayItem extends ItemizedOverlay<OverlayItem> {
/**覆盖物列表集合*/
private ArrayList<OverlayItem> mOverlayList = new ArrayList<OverlayItem>();
// 场景:假如我们有一组建筑物的GPS经纬度值,想要把这些建筑物在地图上标注出来。
// 传进来的Drawable对象用于在地图上标注一个地理坐标点
public MyOverlayItem(Drawable drawable, GPSPonit[] gPSPonit) {
super(drawable);
for(int i = 0; i < gPSPonit.length; i++){
GPSPonit gpp = gPSPonit ;
GeoPoint geoPoint = new GeoPoint(
(int) (gpp.getmLat() * 1E6),
(int) (gpp.getmLon() * 1E6));
mOverlayList.add(new OverlayItem(geoPoint, "point"+i, "point1"+i));
}
// 必须的调用这个方法,否则程序运行报错
populate();
}
/*
* 返回的是从指定List集合中,取出的一个OverlayItem对象。
* mOverlayList集合里一旦有了数据,在调用其之前,
* 一定的在MyOverlayItem的构造函数里调用这个方法populate();
*/
@Override
protected OverlayItem createItem(int index) {
return mOverlayList.get(index);
}
@Override
public int size() {
return mOverlayList.size();
}
}
// 重写以下方法,管理API
@Override
protected void onResume() {
mMapView.onResume();
if (mBMapManager != null) {
mBMapManager.start();
}
super.onResume();
}
@Override
protected void onPause() {
mMapView.onPause();
if (mBMapManager != null) {
mBMapManager.stop();
}
super.onPause();
}
@Override
protected void onDestroy() {
mMapView.destroy();
if (mBMapManager != null) {
mBMapManager.destroy();
mBMapManager = null;
}
super.onDestroy();
}
}[/mw_shl_code]
运行效果图如下:
Android百度地图SDK版本v2.0.0试用(3) 周边检索:根据检索词、中心点地理坐标和半径与发起周边检索。 实现场景:查找以上海市浦东新区为中心,半径为1000米内所有的“浦东发展银行”(搜周边)。 实现步骤: 一、前提条件: 搭建百度地图开发环境; 地图引擎管理对象和显示地图的View对象,都已创建并初始化; MapView对象的相关属性已设置,生命周期函数也已处理。 详见:Android 百度地图SDK (v2.0.0)初探(一楼) 二、检索以上海市浦东新区为中心,半径为1000米内所有的“浦东发展银行”(搜周边)的具体实现步骤: 1、创建搜索服务类对象,并初始化。代码如下: [mw_shl_code=java,true] mMKSearch = new MKSearch(); mMKSearch.init(mBMapManager, new MKSearchListener() { @Override public void onGetAddrResult(MKAddrInfo arg0, int arg1) { // TODO Auto-generated method stub } @Override public void onGetBusDetailResult(MKBusLineResult arg0, int arg1) { // TODO Auto-generated method stub } @Override public void onGetDrivingRouteResult(MKDrivingRouteResult arg0, int arg1) { // TODO Auto-generated method stub } @Override public void onGetPoiResult(MKPoiResult result, int type, int error) { } @Override public void onGetPoiDetailSearchResult(int type, int error) { } @Override public void onGetSuggestionResult(MKSuggestionResult arg0, int arg1) { // TODO Auto-generated method stub } @Override public void onGetTransitRouteResult(MKTransitRouteResult arg0, int arg1) { // TODO Auto-generated method stub } @Override public void onGetWalkingRouteResult(MKWalkingRouteResult arg0, int arg1) { // TODO Auto-generated method stub } });[/mw_shl_code] 2、 调用mMKSearch对象的mMKSearch.poiSearchNearBy(arg0, arg1, arg2)方法,参数列表:关键词、中心点地理坐标、半径,单位:米。 [mw_shl_code=java,true] // 根据中心点、半径与检索词发起周边检索. // 参数列表:关键词、中心点地理坐标、半径,单位:米 mMKSearch.poiSearchNearBy("浦东发展银行", mGeoPoint, 1000);[/mw_shl_code] 3、在onGetPoiResult()回调方法内处理检索到的结果。 [mw_shl_code=java,true]@Override public void onGetPoiResult(MKPoiResult result, int type, int error) { if (error != 0) { Toast.makeText(BaiduMapPoiOverlayActivity.this, "抱歉,未查找到结果", Toast.LENGTH_SHORT).show(); } else { if (result == null) { Toast.makeText(BaiduMapPoiOverlayActivity.this, "抱歉,您填写的搜索条件,未查找到结果,换个条件试试!", Toast.LENGTH_SHORT).show(); return; } // 创建POI内置的Overlay对象 PoiOverlay poiOverlay = new PoiOverlay(BaiduMapPoiOverlayActivity.this, mMapView); // 符合搜索条件的所有点 poiOverlay.setData(result.getAllPoi()); // 向覆盖物列表中添加覆盖物对象PoiOverlay mMapView.getOverlays().add(poiOverlay); // 刷新地图 mMapView.refresh(); } }[/mw_shl_code] 4、运行效果图如下:
三、查看检索到的POI详情:
1、在前面我们以上海市浦东新区为中心,半径为1000米内所有的“浦东发展银行”,检索得到的是一个POI的列表。代码如下: [mw_shl_code=java,true]ArrayList<MKPoiInfo> mkPois = result.getAllPoi();[/mw_shl_code] 注:a. result是MKPoiResult类对象的一个引用。 b. POI是中国POI(Point of Interest)数据库的缩写,可以翻译成“兴趣点”, 每个POI包含四方面信息,名称、类别、经度、纬度。这个计划的远景目标是建立全国的POI数据库,并且全部开放。 [mw_shl_code=java,true]MKPoiInfo mkPoi = mkPois.get(1);[/mw_shl_code] 3、发起查看详细信息的请求: [mw_shl_code=java,true] mMKSearch.poiDetailSearch(mkPoi.uid); [/mw_shl_code] 4、需要在AndroidManifest.xml中设置如下信息: 注:调用百度API里的POI详细信息展示Activity,官方给的有错误。 [mw_shl_code=java,true] <activity android:configChanges="orientation|keyboardHidden" android:name="com.baidu.mapapi.search.PlaceCaterActivity" android:theme="@android:style/Theme.NoTitleBar" > </activity>[/mw_shl_code] 5、处理onGetPoiDetailSearchResult()回调方法: [mw_shl_code=java,true]@Override public void onGetPoiDetailSearchResult(int type, int error) { // type - 值为GeoSearchManager.GEO_SEARCH_DETAILS if (error != 0) { Toast.makeText(BaiduMapPoiOverlayActivity.this, "抱歉,未找到结果", Toast.LENGTH_SHORT).show(); } else { Toast.makeText(BaiduMapPoiOverlayActivity.this, "成功,查看详情页面", Toast.LENGTH_SHORT).show(); } }[/mw_shl_code] 6、运行效果图如下:
三、完整代码:
1、在AndroidManifest.xml中的配置: [mw_shl_code=java,true]<?xml version="1.0" encoding="utf-8"?> <manifest xmlns:android="http://schemas.android.com/apk/res/android" package="com.android.baidu.map" android:versionCode="1" android:versionName="1.0" > <uses-sdk android:minSdkVersion="8" /> <application android:icon="@drawable/ic_launcher" android:label="@string/app_name" > <activity android:configChanges="orientation|keyboardHidden" android:label="@string/app_name" android:name=".BaiduMapPoiOverlayActivity" android:screenOrientation="sensor" > <intent-filter > <action android:name="android.intent.action.MAIN" /> <category android:name="android.intent.category.LAUNCHER" /> </intent-filter> </activity> <activity android:configChanges="orientation|keyboardHidden" android:name="com.baidu.mapapi.search.PlaceCaterActivity" android:theme="@android:style/Theme.NoTitleBar" > </activity> </application> <!-- 使用网络功能所需权限 --> <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" > </uses-permission> <uses-permission android:name="android.permission.INTERNET" > </uses-permission> <uses-permission android:name="android.permission.ACCESS_WIFI_STATE" > </uses-permission> <uses-permission android:name="android.permission.CHANGE_WIFI_STATE" > </uses-permission> <!-- 读取手机的当前状态权限,没有的话会报错,这个是使用百度地图API必须的 --> <uses-permission android:name="android.permission.READ_PHONE_STATE" > </uses-permission> <!-- Cache功能需要读写外部存储器 ,若没这个权限,地图加载不出来 --> <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" > </uses-permission> <supports-screens android:anyDensity="true" android:largeScreens="true" android:normalScreens="true" android:resizeable="true" android:smallScreens="true" /> </manifest>[/mw_shl_code] 2、继承自Activity类的子类的完整代码: [mw_shl_code=java,true]package com.android.baidu.map; import java.util.ArrayList; import android.app.Activity; import android.os.Bundle; import android.widget.Toast; import com.baidu.mapapi.BMapManager; import com.baidu.mapapi.MKGeneralListener; import com.baidu.mapapi.map.MKEvent; import com.baidu.mapapi.map.MapController; import com.baidu.mapapi.map.MapView; import com.baidu.mapapi.map.PoiOverlay; import com.baidu.mapapi.search.MKAddrInfo; import com.baidu.mapapi.search.MKBusLineResult; import com.baidu.mapapi.search.MKDrivingRouteResult; import com.baidu.mapapi.search.MKPoiInfo; import com.baidu.mapapi.search.MKPoiResult; import com.baidu.mapapi.search.MKSearch; import com.baidu.mapapi.search.MKSearchListener; import com.baidu.mapapi.search.MKSuggestionResult; import com.baidu.mapapi.search.MKTransitRouteResult; import com.baidu.mapapi.search.MKWalkingRouteResult; import com.baidu.platform.comapi.basestruct.GeoPoint; /** * 根据检索词、中心点地理坐标和半径与发起周边检索. * @author android_ls * */ public class BaiduMapPoiOverlayActivity extends Activity { /**地图引擎管理类*/ private BMapManager mBMapManager = null; /**显示地图的View*/ private MapView mMapView = null; /**搜索服务,用于位置检索、周边检索、范围检索、公交检索、驾乘检索、步行检索*/ private MKSearch mMKSearch = null; /** * 经研究发现在申请KEY时:应用名称一定要写成my_app_应用名(也就是说"my_app_"是必须要有的)。 * 百度地图SDK提供的服务是免费的,接口无使用次数限制。您需先申请密钥(key),才可使用该套SDK。 * */ public static final String BAIDU_MAP_KEY = "07418AEC69BAAB7104C6230A6120C580DFFAEEBB"; @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); // 注意:请在调用setContentView前初始化BMapManager对象,否则会报错 mBMapManager = new BMapManager(this.getApplicationContext()); mBMapManager.init(BAIDU_MAP_KEY, new MKGeneralListener() { @Override public void onGetNetworkState(int iError) { if (iError == MKEvent.ERROR_NETWORK_CONNECT) { Toast.makeText(BaiduMapPoiOverlayActivity.this.getApplicationContext(), "您的网络出错啦!", Toast.LENGTH_LONG).show(); } } @Override public void onGetPermissionState(int iError) { if (iError == MKEvent.ERROR_PERMISSION_DENIED) { // 授权Key错误: Toast.makeText(BaiduMapPoiOverlayActivity.this.getApplicationContext(), "请在 DemoApplication.java文件输入正确的授权Key!", Toast.LENGTH_LONG).show(); } } }); setContentView(R.layout.main); mMapView = (MapView) this.findViewById(R.id.bmapsView); // 设置启用内置的缩放控件 mMapView.setBuiltInZoomControls(true); MapController mapController = mMapView.getController(); // 上海市浦东新区的GPS纬度经度值:31.224078,121.540419 GeoPoint mGeoPoint = new GeoPoint( (int) (31.224078 * 1E6), (int) (121.540419 * 1E6)); // 设置地图的中心点 mapController.setCenter(mGeoPoint); mapController.setZoom(15); mMKSearch = new MKSearch(); mMKSearch.init(mBMapManager, new MKSearchListener() { @Override public void onGetAddrResult(MKAddrInfo arg0, int arg1) { // TODO Auto-generated method stub } @Override public void onGetBusDetailResult(MKBusLineResult arg0, int arg1) { // TODO Auto-generated method stub } @Override public void onGetDrivingRouteResult(MKDrivingRouteResult arg0, int arg1) { // TODO Auto-generated method stub } @Override public void onGetPoiResult(MKPoiResult result, int type, int error) { if (error != 0) { Toast.makeText(BaiduMapPoiOverlayActivity.this, "抱歉,未查找到结果", Toast.LENGTH_SHORT).show(); } else { if (result == null) { Toast.makeText(BaiduMapPoiOverlayActivity.this, "抱歉,您填写的搜索条件,未查找到结果,换个条件试试!", Toast.LENGTH_SHORT).show(); return; } // 创建POI内置的Overlay对象 PoiOverlay poiOverlay = new PoiOverlay(BaiduMapPoiOverlayActivity.this, mMapView); // 符合搜索条件的所有点 poiOverlay.setData(result.getAllPoi()); // 向覆盖物列表中添加覆盖物对象PoiOverlay mMapView.getOverlays().add(poiOverlay); // 刷新地图 mMapView.refresh(); /* 注: POI是中国POI(Point of Interest)数据库的缩写,可以翻译成“兴趣点”, * 每个POI包含四方面信息,名称、类别、经度、纬度。 * 这个计划的远景目标是建立全国的POI数据库,并且全部开放。*/ // 当执行完POI检索后,我们会得到一个POI的列表。 ArrayList<MKPoiInfo> mkPois = result.getAllPoi(); // 取POI列表中的第二个元素 MKPoiInfo mkPoi = mkPois.get(1); /* 每个POI节点都有个uid属性,我们可以根据这个uid获取关于这个poi的一些更详细的信息。 * 比如:评论、图片、商户描述等。*/ // 发起查看详细信息的请求 mMKSearch.poiDetailSearch(mkPoi.uid); } } @Override public void onGetPoiDetailSearchResult(int type, int error) { // type - 值为GeoSearchManager.GEO_SEARCH_DETAILS if (error != 0) { Toast.makeText(BaiduMapPoiOverlayActivity.this, "抱歉,未找到结果", Toast.LENGTH_SHORT).show(); } else { Toast.makeText(BaiduMapPoiOverlayActivity.this, "成功,查看详情页面", Toast.LENGTH_SHORT).show(); } } @Override public void onGetSuggestionResult(MKSuggestionResult arg0, int arg1) { // TODO Auto-generated method stub } @Override public void onGetTransitRouteResult(MKTransitRouteResult arg0, int arg1) { // TODO Auto-generated method stub } @Override public void onGetWalkingRouteResult(MKWalkingRouteResult arg0, int arg1) { // TODO Auto-generated method stub } }); // 根据中心点、半径与检索词发起周边检索. // 参数列表:关键词、中心点地理坐标、半径,单位:米 mMKSearch.poiSearchNearBy("浦东发展银行", mGeoPoint, 1000); } // 重写以下方法,管理API @Override protected void onResume() { mMapView.onResume(); if (mBMapManager != null) { mBMapManager.start(); } super.onResume(); } @Override protected void onPause() { mMapView.onPause(); if (mBMapManager != null) { mBMapManager.stop(); } super.onPause(); } @Override protected void onDestroy() { mMapView.destroy(); if (mBMapManager != null) { mBMapManager.destroy(); mBMapManager = null; } super.onDestroy(); } } 本文转自:http://www.apkbus.com/forum.php?mod=viewthread&tid=109187 |