现在的位置: 首页 > 综合 > 正文

android 百度地图SDK 获取手机附近POI兴趣点列表 (过时)

2018年05月21日 ⁄ 综合 ⁄ 共 12430字 ⁄ 字号 评论关闭

文章内容已经过时~大家去百度官方api学习。

http://developer.baidu.com/map/


http://lbsyun.baidu.com/sdk/download




功能描述:获取手机自身附近的兴趣点(Poi, 之后使用Poi表示兴趣点)列表,显示在listview中先上效果图

结果图

显而易见的是,图中只有一个简单的listview,然后每个item分别包含Poi的名字,地址和手机到poi所在的距离。由于我在学校里,附近只有5个ATM。尴尬

好了如果你看到的这个效果是你所需要的功能,内心是不是有点小激动呢?

现在我们来分析这个实现的思路:

零,做好之前的准备工作

一,首先是要得到手机自身的位置

二,然后根据这个位置和你要找的POI的名字来得到附近的POI列表

实现的步骤:

向项目中加入百度地图SDK。

 登录后来访问 下载地址http://developer.baidu.com/map/sdkandev-download.htm全部商情下载

下载后解压成

解压图

在BaiduMap_AndroidSDK_v2.4.1_Sample - > BaiduMapsApiDemo - >库以及库 - > armeabi中

 baidumapapi_v2_4_1.jar locSDK_3.1.jar libBaiduMapSDK_v2_4_1.so liblocSDK3.so以相同模式拷到我们当前新建的项目中

 然后添加到构建路径

然后记得申请的关键:http://developer.baidu.com/map/android-mobile-apply-key.htm跟着提示走,这里就不叙述了。

东西准备好了,开始编写代码

首先当然是MainActivity.java

public class MainActivity extends Activity {

	final static String TAG = "MainActivity";

	private static final int MSG_SELFPOINT = 1;
	private static final int MSG_MPOIINFOLIST = 2;

	private static final String POI_NAME = "ATM"; // 搜索指定兴趣点名称
	private static final int SCAN_SPAN = 60 * 1000; // 刷新时间
	private static final int POI_DISTANCE = 1000; // 搜索半径

	private LocationClient locationClient = null;
	private MKSearch mMKSearch = null;
	private GeoPoint selfPoint = null; // 自身经纬度

	private ListView poiInfoList;
	private List<poiinfo> mPoiInfoList = null;

	@SuppressLint("HandlerLeak")
	private Handler handler = new Handler() {
		public void handleMessage(Message msg) {
			switch (msg.what) {
			case MSG_SELFPOINT: // 获得自身经纬度
			default:
				Double[] locNum = (Double[]) msg.obj;
				// 用给定的经纬度构造一个GeoPoint(纬度,经度)
				selfPoint = new GeoPoint((int) (locNum[0] * 1E6), (int) (locNum[1] * 1E6));
				// 执行搜索周边兴趣点列表
				mMKSearch.poiSearchNearBy(POI_NAME, selfPoint, POI_DISTANCE);
				break;
			case MSG_MPOIINFOLIST: // 获得周边兴趣点列表
				PoiAdapter adapter = new PoiAdapter(getApplicationContext(), mPoiInfoList);
				adapter.notifyDataSetChanged();
				poiInfoList.setAdapter(adapter);
				break;
			}
		}
	};

	@Override
	public void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);

		initMapManagerAndMKSearch();

		setContentView(R.layout.activity_main);
		initViews();

		startLocationClient();
	}

	@Override
	protected void onDestroy() {
		super.onDestroy();
		if (locationClient != null && locationClient.isStarted()) {
			locationClient.stop();
			locationClient = null;
		}
	}

	/**
	 * 使用地图sdk前需先初始化BMapManager. BMapManager是全局的,可为多个MapView共用,它需要地图模块创建前创建,
	 * 并在地图地图模块销毁后销毁,只要还有地图模块在使用,BMapManager就不应该销毁
	 */
	private void initMapManagerAndMKSearch() {
		MyApplication app = (MyApplication) this.getApplication();
		if (app.mBMapManager == null) {
			app.mBMapManager = new BMapManager(getApplicationContext());
			/**
			 * 如果BMapManager没有初始化则初始化BMapManager
			 */
			app.mBMapManager.init(new MyApplication.MyGeneralListener());
		}
		mMKSearch = new MKSearch();
		mMKSearch.init(app.mBMapManager, new MKSearchListener() {

			@Override
			public void onGetWalkingRouteResult(MKWalkingRouteResult result, int iError) {
				// 步行路线搜索结果
			}

			@Override
			public void onGetTransitRouteResult(MKTransitRouteResult result, int iError) {
				// 公交换乘路线搜索结果
			}

			@Override
			public void onGetSuggestionResult(MKSuggestionResult arg0, int arg1) {
				// TODO Auto-generated method stub
			}

			@Override
			public void onGetShareUrlResult(MKShareUrlResult arg0, int arg1, int arg2) {
				// TODO Auto-generated method stub
			}

			@Override
			public void onGetPoiResult(MKPoiResult result, int type, int iError) {
				// POI搜索结果(范围检索、城市POI检索、周边检索)
				if (result == null) {
					Log.i(TAG, "周围一定范围内没有检索出POI目标");
					Toast.makeText(getApplicationContext(), "周围一定范围内没有检索出POI目标", Toast.LENGTH_SHORT).show();
					return;
				}
				mPoiInfoList = new ArrayList<poiinfo>();
				PoiInfo mPoiInfo = null;

				for (MKPoiInfo mMKPoiInfo : result.getAllPoi()) {
					// 计算自身与目的地之间的距离
					int distanceM = (int) DistanceUtil.getDistance(selfPoint, mMKPoiInfo.pt);
					mPoiInfo = new PoiInfo(mMKPoiInfo.name, mMKPoiInfo.address, distanceM);
					mPoiInfoList.add(mPoiInfo);
				}
				Message.obtain(handler, MSG_MPOIINFOLIST).sendToTarget();
			}

			@Override
			public void onGetPoiDetailSearchResult(int arg0, int arg1) {
				// TODO Auto-generated method stub
			}

			@Override
			public void onGetDrivingRouteResult(MKDrivingRouteResult result, int iError) {
				// 驾车路线搜索结果
			}

			@Override
			public void onGetBusDetailResult(MKBusLineResult arg0, int arg1) {
				// TODO Auto-generated method stub
			}

			@Override
			public void onGetAddrResult(MKAddrInfo result, int iError) {
				// 根据经纬度搜索地址信息结果
			}
		});

	}

	private void startLocationClient() {
		locationClient = new LocationClient(getApplicationContext());
		locationClient.setLocOption(setLocationOption());
		// 注册位置监听器
		locationClient.registerLocationListener(new BDLocationListener() {
			@Override
			public void onReceiveLocation(BDLocation location) {
				if (location == null) {
					return;
				}
				double latitude = location.getLatitude(); // 纬度
				double longitude = location.getLongitude(); // 经度
				Double[] locNum = { latitude, longitude };
				Message.obtain(handler, MSG_SELFPOINT, locNum).sendToTarget();
				locationClient.stop(); // 停止查询自身经纬度
			}

			@Override
			public void onReceivePoi(BDLocation location) {
			}
		});

		locationClient.start(); // 开始查询自身经纬度
		locationClient.requestLocation();
	}

	private LocationClientOption setLocationOption() {
		// 设置定位条件
		LocationClientOption option = new LocationClientOption();
		option.setServiceName("com.baidu.location.service_v2.9");
		// 需要地址信息,设置为其他任何值(string类型,且不能为null)时,都表示无地址信息。
		option.setAddrType("all");
		// 设置是否返回POI的电话和地址等详细信息。默认值为false,即不返回POI的电话和地址信息。
		option.setPoiExtraInfo(false);
		// 设置产品线名称。强烈建议您使用自定义的产品线名称,方便我们以后为您提供更高效准确的定位服务。
		option.setProdName("定位我当前的位置");
		// 设置GPS,使用gps前提是用户硬件打开gps。默认是不打开gps的。
		option.setOpenGps(true);
		// 定位的时间间隔,单位:ms
		// 当所设的整数值大于等于1000(ms)时,定位SDK内部使用定时定位模式。
		option.setScanSpan(SCAN_SPAN);
		// 查询范围,默认值为500,即以当前定位位置为中心的半径大小。
		option.setPoiDistance(POI_DISTANCE);
		// 禁用启用缓存定位数据
		option.disableCache(true);
		// 坐标系类型,百度手机地图对外接口中的坐标系默认是bd09ll
		option.setCoorType("bd09ll");
		// 设置最多可返回的POI个数,默认值为3。由于POI查询比较耗费流量,设置最多返回的POI个数,以便节省流量。
		option.setPoiNumber(0);
		// 设置定位方式的优先级。
		// 当gps可用,而且获取了定位结果时,不再发起网络请求,直接返回给用户坐标。这个选项适合希望得到准确坐标位置的用户。如果gps不可用,再发起网络请求,进行定位。
		option.setPriority(LocationClientOption.NetWorkFirst);
		return option;
	}

	private void initViews() {
		poiInfoList = (ListView) findViewById(R.id.lv_poiInfoList);
	}

}
</poiinfo></poiinfo>

从onCreate走起,先初始化BMapManager,然后加载布局,最后初始化LocationClient配置参数start()以及requestLocation()后

通过registerLocationListener中onReceiveLocation()可获得自身经纬度,经纬度手柄一下调用MKSearch.poiSearchNearBy()搜索周边兴趣点列表

通过MKSearchListener中onGetPoiResult()列表配置。再处理一下加载UI。

然后是MyApplication.java

public class MyApplication extends Application {

	private static MyApplication mInstance = null;
	public boolean m_bKeyRight = true;
	BMapManager mBMapManager = null;

	@Override
	public void onCreate() {
		super.onCreate();
		mInstance = this;
		initEngineManager(this);
	}

	public void initEngineManager(Context context) {
		if (mBMapManager == null) {
			mBMapManager = new BMapManager(context);
		}

		if (!mBMapManager.init(new MyGeneralListener())) {
			Toast.makeText(MyApplication.getInstance().getApplicationContext(),
					"BMapManager  初始化错误!", Toast.LENGTH_LONG).show();
		}
	}

	public static MyApplication getInstance() {
		return mInstance;
	}

	// 常用事件监听,用来处理通常的网络错误,授权验证错误等
	static class MyGeneralListener implements MKGeneralListener {

		@Override
		public void onGetNetworkState(int iError) {
			if (iError == MKEvent.ERROR_NETWORK_CONNECT) {
				Toast.makeText(
						MyApplication.getInstance().getApplicationContext(),
						"您的网络出错啦!", Toast.LENGTH_LONG).show();
			} else if (iError == MKEvent.ERROR_NETWORK_DATA) {
				Toast.makeText(
						MyApplication.getInstance().getApplicationContext(),
						"输入正确的检索条件!", Toast.LENGTH_LONG).show();
			}
			// ...
		}

		@Override
		public void onGetPermissionState(int iError) {
			// 非零值表示key验证未通过
			if (iError != 0) {
				// 授权Key错误:
				Toast.makeText(
						MyApplication.getInstance().getApplicationContext(),
						"请在 DemoApplication.java文件输入正确的授权Key,并检查您的网络连接是否正常!error: "
								+ iError, Toast.LENGTH_LONG).show();
				MyApplication.getInstance().m_bKeyRight = false;
			} else {
				MyApplication.getInstance().m_bKeyRight = true;
				Toast.makeText(
						MyApplication.getInstance().getApplicationContext(),
						"key认证成功", Toast.LENGTH_LONG).show();
			}
		}
	}
}

然后清单文件:

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="com.example.android"
    android:versionCode="1"
    android:versionName="1.0" >

    <uses-sdk
        android:minSdkVersion="7"
        android:targetSdkVersion="10" />

    <permission android:name="android.permission.BAIDU_LOCATION_SERVICE" />

    <uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />
    <uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
    <uses-permission android:name="android.permission.ACCESS_WIFI_STATE" />
    <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
    <uses-permission android:name="android.permission.BAIDU_LOCATION_SERVICE" />
    <uses-permission android:name="android.permission.CHANGE_WIFI_STATE" />
    <uses-permission android:name="android.permission.INTERNET" />
    <uses-permission android:name="android.permission.MOUNT_UNMOUNT_FILESYSTEMS" />
    <uses-permission android:name="android.permission.READ_PHONE_STATE" />
    <uses-permission android:name="android.permission.READ_LOGS" />
    <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
    <uses-permission android:name="android.permission.WRITE_SETTINGS" />

    <application
        android:name="MyApplication"
        android:allowBackup="true"
        android:icon="@drawable/ic_launcher"
        android:label="@string/app_name" >
        <meta-data
            android:name="com.baidu.lbsapi.API_KEY"
            android:value="SebBBgHgrqTVjr8WXAYP9TCl" />

        <activity android:name="com.example.android.MainActivity" >
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />

                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
        </activity>

        <service
            android:name="com.baidu.location.f"
            android:enabled="true"
            android:permission="android.permission.BAIDU_LOCATION_SERVICE"
            android:process=":remote" >
            <intent-filter>
                <action android:name="com.baidu.location.service_v2.4" />
            </intent-filter>
        </service>
    </application>

</manifest>

这里注意需要在中的android:值填写关键值还有一个百度自己的位置服务的注册。

最后布局文件:activity_main.xml和item.xml

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="fill_parent"
    android:layout_height="fill_parent"
    android:orientation="vertical" >

    <com.baidu.mapapi.map.MapView
        android:id="@+id/map_View"
        android:layout_width="fill_parent"
        android:layout_height="fill_parent"
        android:clickable="true"
        android:visibility="gone" />

    <ListView
        android:id="@+id/lv_poiInfoList"
        android:layout_width="fill_parent"
        android:layout_height="wrap_content"
        android:background="#fff" />

</LinearLayout>

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:orientation="vertical" >

    <TextView
        android:id="@+id/tv_poiName"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content" />

    <TextView
        android:id="@+id/tv_poiAddress"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content" />

    <TextView
        android:id="@+id/tv_poiDistance"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content" />

</LinearLayout>

列表适配器:

public class PoiAdapter extends BaseAdapter {

	List<poiinfo> poiInfoList;
	@SuppressWarnings("unused")
	private Context context;
	private LayoutInflater inflater;

	public PoiAdapter(Context context, List<poiinfo> poiInfoList) {
		this.poiInfoList = poiInfoList;
		this.context = context;
		inflater = LayoutInflater.from(context); // 创建视图容器并设置上下文
	}

	@Override
	public int getCount() {
		return poiInfoList != null ? poiInfoList.size() : 0;
	}

	@Override
	public Object getItem(int postion) {
		return poiInfoList != null ? poiInfoList.get(postion) : null;
	}

	@Override
	public long getItemId(int postion) {
		return postion;
	}

	@Override
	public View getView(int position, View convertView, ViewGroup parent) {
		ViewHolder viewHolder = null;
		if (convertView == null) {
			viewHolder = new ViewHolder();
			convertView = inflater.inflate(R.layout.item, null);
			viewHolder.poiName = (TextView) convertView.findViewById(R.id.tv_poiName);
			viewHolder.poiAddress = (TextView) convertView.findViewById(R.id.tv_poiAddress);
			viewHolder.poiDistance = (TextView) convertView.findViewById(R.id.tv_poiDistance);
			convertView.setTag(viewHolder);
		} else {
			viewHolder = (ViewHolder) convertView.getTag();
		}
		PoiInfo mPoiInfo = poiInfoList.get(position);
		viewHolder.poiName.setText(mPoiInfo.getName());
		viewHolder.poiAddress.setText(mPoiInfo.getAddress());
		viewHolder.poiDistance.setText(mPoiInfo.getDistance().toString());
		return convertView;
	}

	final class ViewHolder {
		TextView poiName;
		TextView poiAddress;
		TextView poiDistance;
	}

}

</poiinfo></poiinfo>

列表实体:

package com.example.android;

public class PoiInfo {

	private String name;
	private String address;
	private Integer distance;

	public PoiInfo() {
		super();
	}

	public PoiInfo(String name, String address, Integer distance) {
		super();
		this.name = name;
		this.address = address;
		this.distance = distance;
	}

	public String getName() {
		return name;
	}

	public void setName(String name) {
		this.name = name;
	}

	public String getAddress() {
		return address;
	}

	public void setAddress(String address) {
		this.address = address;
	}

	public Integer getDistance() {
		return distance;
	}

	public void setDistance(Integer distance) {
		this.distance = distance;
	}

	@Override
	public String toString() {
		return "POIInfo [name=" + name + ", address=" + address + ", distance="
				+ distance + "]";
	}

}

到这里就完成了。

然后声明一下由于才刚学1个月的android开发,本人水平有限,对于这个功能,应该还有不足之处和一些BUG,吐舌头

做出这个demo花了我6个小时时间编码,查阅百度地图api以及一些博客。写出这文章用了2个小时(第一次写-_-||)。

虽然效率很慢,但是我能感觉到自己水平略有提升,在这里希望和我一样正在奋斗的程序员继续加油。

抱歉!评论已关闭.