在地图上标记用户当前所处位置其实是一个GPS定位应用。首先通过GPS定位获取到用户当前所在位置的经纬度,再将该经纬度所代表的点在地图上标出来。其实除了在地图上标注自己所处的位置外,我们通常还有这样的需求:“如果我的位置发生改变,要能够实时在地图上体现出来”。
新建项目baidumaplocation.设计main.xml文件这里注意的是MapView控件必须使用来自百度库封装好的com.baidu.mapapi.MapView 。设计代码如下:
Xml代码 [url=]
[/url]
1.<?xml version="1.0" encoding="utf-8"?>
2.<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
3. android:layout_width="fill_parent"
4. android:layout_height="fill_parent"
5. android:orientation="vertical" >
6. <FrameLayout
7. android:id="@+id/map_layout"
8. android:layout_width="fill_parent"
9. android:layout_height="fill_parent"
10. android:orientation="vertical" >
11. <!-- 百度MapView控件 -->
12. <com.baidu.mapapi.MapView
13. android:id="@+id/map_view"
14. android:layout_width="fill_parent"
15. android:layout_height="fill_parent"
16. android:apiKey="0Mg_koWoyZUiYLfZxmPfp4LKInB5LqTnagYueaw"
17. android:clickable="true"
18. android:enabled="true" />
19. <LinearLayout
20. android:layout_width="wrap_content"
21. android:layout_height="wrap_content"
22. android:layout_gravity="center"
23. android:orientation="vertical"
24. android:paddingBottom="105dip" >
25. <!-- 地址信息显示TextView -->
26. <TextView
27. android:id="@+id/map_bubbleText"
28. android:layout_width="wrap_content"
29. android:layout_height="wrap_content"
30. android:background="@drawable/location_tips"
31. android:gravity="left|center"
32. android:maxEms="12"
33. android:paddingLeft="12dip"
34. android:paddingRight="10dip"
35. android:text="@string/load_tips"
36. android:textColor="#cfcfcf"
37. android:textSize="14sp" />
38. </LinearLayout>
39. <LinearLayout
40. android:layout_width="wrap_content"
41. android:layout_height="wrap_content"
42. android:layout_gravity="center"
43. android:orientation="vertical" >
44. <!-- 位置指标显示ImageView -->
45. <ImageView
46. android:id="@+id/point_image"
47. android:layout_width="wrap_content"
48. android:layout_height="wrap_content"
49. android:layout_gravity="center"
50. android:layout_marginBottom="30dip"
51. android:src="@drawable/point_start" />
52. </LinearLayout>
53. </FrameLayout>
54.</LinearLayout>
三:创建覆盖整个地图捕捉触控事件的MyMapOverlay继承Overlay
Java代码 [url=]
[/url]
1.import android.view.MotionEvent;
2.import com.baidu.mapapi.GeoPoint;
3.import com.baidu.mapapi.MapView;
4.import com.baidu.mapapi.Overlay;
5.//覆盖整个地图捕捉触控事件的OverLay
6.public abstract class MyMapOverlay extends Overlay{
7.private int point_X;
8.private int point_Y;
9.private GeoPoint newPoint;
10.public MyMapOverlay(int x,int y){
11.point_X = x;
12.point_Y = y;
13.}
14.boolean flagMove=false;
15.//这里实现根据地图移动时重新获取屏幕中心点的经纬度坐标
16. @Override
17. public boolean onTouchEvent(MotionEvent event, MapView mapView) {
18. System.out.println("X->"+event.getX()+":"+point_X);
19. System.out.println("Y->"+event.getY()+":"+point_Y);
20. if(event.getAction() == MotionEvent.ACTION_DOWN){
21. changePoint(newPoint,1);
22. }else if(event.getAction() == MotionEvent.ACTION_UP){
23. newPoint = mapView.getProjection().fromPixels(point_X,point_Y);
24. changePoint(newPoint,2);
25. }
26. return false;
27. }
28.
29. public abstract void changePoint(GeoPoint newPoint,int type);
30.}
四:LocationActivity类继承百度库的MapActivity以及实现LocationListener接口,代码如下:
package com.location.activity;Java代码 [url=]
[/url]
1.import java.io.IOException;
2.import java.util.List;
3.import java.util.Locale;
4.
5.import android.content.Intent;
6.import android.location.Address;
7.import android.location.Geocoder;
8.import android.location.Location;
9.import android.os.Bundle;
10.import android.os.Handler;
11.import android.os.Message;
12.import android.view.View;
13.import android.view.Window;
14.import android.widget.TextView;
15.
16.import com.android.map.MyMapOverlay;
17.import com.baidu.mapapi.BMapManager;
18.import com.baidu.mapapi.GeoPoint;
19.import com.baidu.mapapi.LocationListener;
20.import com.baidu.mapapi.MKAddrInfo;
21.import com.baidu.mapapi.MKBusLineResult;
22.import com.baidu.mapapi.MKDrivingRouteResult;
23.import com.baidu.mapapi.MKLocationManager;
24.import com.baidu.mapapi.MKPoiResult;
25.import com.baidu.mapapi.MKSearch;
26.import com.baidu.mapapi.MKSearchListener;
27.import com.baidu.mapapi.MKSuggestionResult;
28.import com.baidu.mapapi.MKTransitRouteResult;
29.import com.baidu.mapapi.MKWalkingRouteResult;
30.import com.baidu.mapapi.MapActivity;
31.import com.baidu.mapapi.MapController;
32.import com.baidu.mapapi.MapView;
33.import com.baidu.mapapi.Overlay;
34.
35.public class LocationActivity extends MapActivity implements LocationListener {
36.
37. private MapView mapView;
38. private MapController mMapCtrl;
39. private List<Overlay> mapOverlays;
40. public GeoPoint locPoint;
41. private MyMapOverlay mOverlay;
42. private TextView desText;
43. private String lost_tips;
44. private int point_X;
45. private int point_Y;
46.
47. public final int MSG_VIEW_LONGPRESS = 10001;
48. public final int MSG_VIEW_ADDRESSNAME = 10002;
49. public final int MSG_GONE_ADDRESSNAME = 10003;
50. private Intent mIntent;
51. private int mLatitude;
52. private int mLongitude;
53. private String name;
54. private BMapManager mapManager;
55. private MKLocationManager mLocationManager = null;
56. private boolean isLoadAdrr = true;
57. private MKSearch mMKSearch;
58.
59. @Override
60. public void onCreate(Bundle savedInstanceState) {
61. super.onCreate(savedInstanceState);
62. requestWindowFeature(Window.FEATURE_NO_TITLE);
63. setContentView(R.layout.main);
64. initMap();
65. mIntent = getIntent();
66. mLatitude = mIntent.getIntExtra("latitude", 0);
67. mLongitude = mIntent.getIntExtra("longitude", 0);
68. name = mIntent.getStringExtra("name");
69. mapView = (MapView) findViewById(R.id.map_view);
70. desText = (TextView) this.findViewById(R.id.map_bubbleText);
71. lost_tips = getResources().getString(R.string.load_tips);
72. if (mLatitude != 0 && mLongitude != 0) {
73. locPoint = new GeoPoint((int) (mLatitude * 1E6),
74. (int) (mLongitude * 1E6));
75. desText.setText(name);
76. }
77. mapView.setBuiltInZoomControls(true);
78. mapView.setClickable(true);
79. mMapCtrl = mapView.getController();
80. point_X = this.getWindowManager().getDefaultDisplay().getWidth() / 2;
81. point_Y = this.getWindowManager().getDefaultDisplay().getHeight() / 2;
82. mOverlay = new MyMapOverlay(point_X, point_Y) {
83. @Override
84. public void changePoint(GeoPoint newPoint, int type) {
85. if (type == 1) {
86. mHandler.sendEmptyMessage(MSG_GONE_ADDRESSNAME);
87. } else {
88. locPoint = newPoint;
89. mHandler.sendEmptyMessage(MSG_VIEW_LONGPRESS);
90. }
91.
92. }
93. };
94. mapOverlays = mapView.getOverlays();
95. if (mapOverlays.size() > 0) {
96. mapOverlays.clear();
97. }
98. mapOverlays.add(mOverlay);
99. mMapCtrl.setZoom(20);
100.
101. }
102.
103. private void initMap() {
104.
105. // 初始化MapActivity
106. mapManager = new BMapManager(getApplication());
107. // init方法的第一个参数需填入申请的API Key
108. mapManager.init("C66C0501D0280744759A6957C42543AE38F5D540", null);
109. super.initMapActivity(mapManager);
110. // 实例化搜索地址类
111. mMKSearch = new MKSearch();
112. // 初始化搜索地址实例
113. mMKSearch.init(mapManager, new MySearchListener());
114. mLocationManager = mapManager.getLocationManager();
115. // 注册位置更新事件
116. mLocationManager.requestLocationUpdates(this);
117. // 使用GPS定位
118. mLocationManager
119. .enableProvider((int) MKLocationManager.MK_GPS_PROVIDER);
120. }
121.
122. @Override
123. protected void onResume() {
124. if (mapManager != null) {
125. mapManager.start();
126. }
127. super.onResume();
128.
129. }
130.
131. @Override
132. protected void onPause() {
133. isLoadAdrr = false;
134. if (mapManager != null) {
135. mapManager.stop();
136. }
137. super.onPause();
138. }
139.
140. @Override
141. protected boolean isRouteDisplayed() {
142. // TODO Auto-generated method stub
143. return false;
144. }
145.
146.
147. /**
148. * 通过经纬度获取地址
149. *
150. * @param point
151. * @return
152. */
153. private String getLocationAddress(GeoPoint point) {
154. String add = "";
155. Geocoder geoCoder = new Geocoder(getBaseContext(), Locale.getDefault());
156. try {
157. List<Address> addresses = geoCoder.getFromLocation(
158. point.getLatitudeE6() / 1E6, point.getLongitudeE6() / 1E6,
159. 1);
160. Address address = addresses.get(0);
161. int maxLine = address.getMaxAddressLineIndex();
162. if (maxLine >= 2) {
163. add = address.getAddressLine(1) + address.getAddressLine(2);
164. } else {
165. add = address.getAddressLine(1);
166. }
167. } catch (IOException e) {
168. add = "";
169. e.printStackTrace();
170. }
171. return add;
172. }
173.
174.
175. private Handler mHandler = new Handler() {
176. @Override
177. public void handleMessage(Message msg) {
178. switch (msg.what) {
179. case MSG_VIEW_LONGPRESS:// 处理长按时间返回位置信息
180. {
181. if (null == locPoint)
182. return;
183. mMKSearch.reverseGeocode(locPoint);
184. desText.setVisibility(View.VISIBLE);
185. desText.setText(lost_tips);
186. mMapCtrl.animateTo(locPoint);
187. mapView.invalidate();
188. }
189. break;
190. case MSG_VIEW_ADDRESSNAME:
191. desText.setText((String) msg.obj);
192. desText.setVisibility(View.VISIBLE);
193. break;
194. case MSG_GONE_ADDRESSNAME:
195. desText.setVisibility(View.GONE);
196. break;
197. }
198. }
199. };
200.
201. // 关闭程序也关闭定位
202. @Override
203. protected void onDestroy() {
204. if (mapManager != null) {
205. mapManager.destroy();
206. mapManager = null;
207. }
208. super.onDestroy();
209. }
210.
211. /**
212. * 根据MyLocationOverlay配置的属性确定是否在地图上显示当前位置
213. */
214. @Override
215. protected boolean isLocationDisplayed() {
216. return false;
217. }
218.
219. /**
220. * 当位置发生变化时触发此方法
221. *
222. * @param location
223. * 当前位置
224. */
225. public void onLocationChanged(Location location) {
226. if (location != null) {
227. locPoint = new GeoPoint((int) (location.getLatitude()* 1E6),
228. (int) (location.getLongitude()* 1E6));
229. mHandler.sendEmptyMessage(MSG_VIEW_LONGPRESS);
230. }
231. }
232.
233. /**
234. * 内部类实现MKSearchListener接口,用于实现异步搜索服务
235. *
236. * @author liufeng
237. */
238. public class MySearchListener implements MKSearchListener {
239. /**
240. * 根据经纬度搜索地址信息结果
241. *
242. * @param result
243. * 搜索结果
244. * @param iError
245. * 错误号(0表示正确返回)
246. */
247. public void onGetAddrResult(MKAddrInfo result, int iError) {
248. if (result == null) {
249. return;
250. }
251. Message msg = new Message();
252. msg.what = MSG_VIEW_ADDRESSNAME;
253. msg.obj = result.strAddr;
254. mHandler.sendMessage(msg);
255.
256. }
257.
258. /**
259. * 驾车路线搜索结果
260. *
261. * @param result
262. * 搜索结果
263. * @param iError
264. * 错误号(0表示正确返回)
265. */
266. public void onGetDrivingRouteResult(MKDrivingRouteResult result,
267. int iError) {
268. }
269.
270. /**
271. * POI搜索结果(范围检索、城市POI检索、周边检索)
272. *
273. * @param result
274. * 搜索结果
275. * @param type
276. * 返回结果类型(11,12,21:poi列表 7:城市列表)
277. * @param iError
278. * 错误号(0表示正确返回)
279. */
280. public void onGetPoiResult(MKPoiResult result, int type, int iError) {
281. }
282.
283. /**
284. * 公交换乘路线搜索结果
285. *
286. * @param result
287. * 搜索结果
288. * @param iError
289. * 错误号(0表示正确返回)
290. */
291. public void onGetTransitRouteResult(MKTransitRouteResult result,
292. int iError) {
293. }
294.
295. /**
296. * 步行路线搜索结果
297. *
298. * @param result
299. * 搜索结果
300. * @param iError
301. * 错误号(0表示正确返回)
302. */
303. public void onGetWalkingRouteResult(MKWalkingRouteResult result,
304. int iError) {
305. }
306.
307. public void onGetBusDetailResult(MKBusLineResult arg0, int arg1) {
308. // TODO Auto-generated method stub
309.
310. }
311.
312. public void onGetSuggestionResult(MKSuggestionResult arg0, int arg1) {
313. // TODO Auto-generated method stub
314.
315. }
316. }
317.
318.}
五:在AndroidManifest.xml住添加相关的访问权限
<!-- 访问网络的权限 -->
Xml代码 [url=]
[/url]
1. <uses-permission android:name="android.permission.INTERNET" />
2. <!-- 访问精确位置的权限 -->
3. <uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
4. <!-- 访问网络状态的权限 -->
5. <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
6. <!-- 访问WIFI网络状态的权限 -->
7. <uses-permission android:name="android.permission.ACCESS_WIFI_STATE" />
8. <!-- 改变WIFI网络状态的权限 -->
9. <uses-permission android:name="android.permission.CHANGE_WIFI_STATE" />
10. <!-- 读写存储卡的权限 -->
11. <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
12. <!-- 读取电话状态的权限 -->
13.<uses-permission android:name="android.permission.READ_PHONE_STATE" />