来自:http://blog.csdn.net/u010142437/article/details/11577077
在使用百度地图结合GPS进行定位一文中,我们已经介绍了利用GPS结合百度地图进行定位,另外我们也可以使用百度SDK里面集成的方法,直接进行定位,这样就不需要我们自己去写GPS定位的方法了,代码原型来自百度Demo,代码如下:
Activity:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
|
package
com.home;
import
android.app.Activity;
import
android.content.Context;
import
android.graphics.drawable.Drawable;
import
android.os.Bundle;
import
android.util.AttributeSet;
import
android.util.Log;
import
android.view.Menu;
import
android.view.MotionEvent;
import
android.view.View;
import
android.view.View.OnClickListener;
import
android.widget.Button;
import
android.widget.RadioGroup;
import
android.widget.TextView;
import
android.widget.Toast;
import
android.widget.RadioGroup.OnCheckedChangeListener;
import
com.baidu.location.BDLocation;
import
com.baidu.location.BDLocationListener;
import
com.baidu.location.LocationClient;
import
com.baidu.location.LocationClientOption;
import
com.baidu.mapapi.map.LocationData;
import
com.baidu.mapapi.map.MapController;
import
com.baidu.mapapi.map.MapView;
import
com.baidu.mapapi.map.MyLocationOverlay;
import
com.baidu.mapapi.map.PopupClickListener;
import
com.baidu.mapapi.map.PopupOverlay;
import
com.baidu.platform.comapi.basestruct.GeoPoint;
/**
* 此demo用来展示如何结合定位SDK实现定位,并使用MyLocationOverlay绘制定位位置 同时展示如何使用自定义图标绘制并点击时弹出泡泡
*
*/
public
class
LocationOverlayActivity
extends
Activity {
// 定位相关
LocationClient mLocClient;
LocationData locData =
null
;
public
MyLocationListenner myListener =
new
MyLocationListenner();
// 定位图层
locationOverlay myLocationOverlay =
null
;
// 弹出泡泡图层
private
PopupOverlay pop =
null
;
// 弹出泡泡图层,浏览节点时使用
private
TextView popupText =
null
;
// 泡泡view
private
View viewCache =
null
;
// 地图相关,使用继承MapView的MyLocationMapView目的是重写touch事件实现泡泡处理
// 如果不处理touch事件,则无需继承,直接使用MapView即可
MyLocationMapView mMapView =
null
;
// 地图View
private
MapController mMapController =
null
;
// UI相关
OnCheckedChangeListener radioButtonListener =
null
;
Button requestLocButton =
null
;
boolean
isRequest =
false
;
// 是否手动触发请求定位
boolean
isFirstLoc =
true
;
// 是否首次定位
@Override
public
void
onCreate(Bundle savedInstanceState) {
super
.onCreate(savedInstanceState);
setContentView(R.layout.activity_locationoverlay);
CharSequence titleLable =
"定位功能"
;
setTitle(titleLable);
requestLocButton = (Button) findViewById(R.id.button1);
OnClickListener btnClickListener =
new
OnClickListener() {
@Override
public
void
onClick(View v) {
// 手动定位请求
requestLocClick();
}
};
requestLocButton.setOnClickListener(btnClickListener);
RadioGroup group = (RadioGroup)
this
.findViewById(R.id.radioGroup);
radioButtonListener =
new
OnCheckedChangeListener() {
@Override
public
void
onCheckedChanged(RadioGroup group,
int
checkedId) {
if
(checkedId == R.id.defaulticon) {
// 传入null则,恢复默认图标
modifyLocationOverlayIcon(
null
);
}
if
(checkedId == R.id.customicon) {
// 修改为自定义marker
modifyLocationOverlayIcon(getResources().getDrawable(
R.drawable.icon_geo));
}
}
};
group.setOnCheckedChangeListener(radioButtonListener);
// 地图初始化
mMapView = (MyLocationMapView) findViewById(R.id.bmapView);
mMapController = mMapView.getController();
mMapView.getController().setZoom(
14
);
mMapView.getController().enableClick(
true
);
mMapView.setBuiltInZoomControls(
true
);
// 创建 弹出泡泡图层
createPaopao();
// 定位初始化
mLocClient =
new
LocationClient(
this
);
locData =
new
LocationData();
mLocClient.registerLocationListener(myListener);
LocationClientOption option =
new
LocationClientOption();
option.setOpenGps(
true
);
// 打开gps
option.setCoorType(
"bd09ll"
);
// 设置坐标类型
option.setScanSpan(
5000
);
mLocClient.setLocOption(option);
mLocClient.start();
// 定位图层初始化
myLocationOverlay =
new
locationOverlay(mMapView);
// 设置定位数据
myLocationOverlay.setData(locData);
// 添加定位图层
mMapView.getOverlays().add(myLocationOverlay);
myLocationOverlay.enableCompass();
// 修改定位数据后刷新图层生效
mMapView.refresh();
}
/**
* 手动触发一次定位请求
*/
public
void
requestLocClick() {
isRequest =
true
;
mLocClient.requestLocation();
Toast.makeText(LocationOverlayActivity.
this
,
"正在定位……"
,
Toast.LENGTH_SHORT).show();
}
/**
* 修改位置图标
*
* @param marker
*/
public
void
modifyLocationOverlayIcon(Drawable marker) {
// 当传入marker为null时,使用默认图标绘制
myLocationOverlay.setMarker(marker);
// 修改图层,需要刷新MapView生效
mMapView.refresh();
}
/**
* 创建弹出泡泡图层
*/
public
void
createPaopao() {
viewCache = getLayoutInflater()
.inflate(R.layout.custom_text_view,
null
);
popupText = (TextView) viewCache.findViewById(R.id.textcache);
// 泡泡点击响应回调
PopupClickListener popListener =
new
PopupClickListener() {
@Override
public
void
onClickedPopup(
int
index) {
Log.v(
"click"
,
"clickapoapo"
);
}
};
pop =
new
PopupOverlay(mMapView, popListener);
MyLocationMapView.pop = pop;
}
/**
* 定位SDK监听函数
*/
public
class
MyLocationListenner
implements
BDLocationListener {
@Override
public
void
onReceiveLocation(BDLocation location) {
if
(location ==
null
)
return
;
locData.latitude = location.getLatitude();
locData.longitude = location.getLongitude();
// 如果不显示定位精度圈,将accuracy赋值为0即可
locData.accuracy = location.getRadius();
locData.direction = location.getDerect();
// 更新定位数据
myLocationOverlay.setData(locData);
// 更新图层数据执行刷新后生效
mMapView.refresh();
// 是手动触发请求或首次定位时,移动到定位点
if
(isRequest || isFirstLoc) {
// 移动地图到定位点
mMapController.animateTo(
new
GeoPoint(
(
int
) (locData.latitude * 1e6),
(
int
) (locData.longitude * 1e6)));
isRequest =
false
;
}
// 首次定位完成
isFirstLoc =
false
;
}
public
void
onReceivePoi(BDLocation poiLocation) {
if
(poiLocation ==
null
) {
return
;
}
}
}
// 继承MyLocationOverlay重写dispatchTap实现点击处理
public
class
locationOverlay
extends
MyLocationOverlay {
public
locationOverlay(MapView mapView) {
super
(mapView);
}
@Override
protected
boolean
dispatchTap() {
// 处理点击事件,弹出泡泡
popupText.setBackgroundResource(R.drawable.popup);
popupText.setText(
"我的位置"
);
pop.showPopup(BMapUtil.getBitmapFromView(popupText),
new
GeoPoint(
(
int
) (locData.latitude * 1e6),
(
int
) (locData.longitude * 1e6)),
8
);
return
true
;
}
}
@Override
protected
void
onPause() {
mMapView.onPause();
super
.onPause();
}
@Override
protected
void
onResume() {
mMapView.onResume();
super
.onResume();
}
@Override
protected
void
onDestroy() {
// 退出时销毁定位
if
(mLocClient !=
null
)
mLocClient.stop();
mMapView.destroy();
super
.onDestroy();
}
@Override
protected
void
onSaveInstanceState(Bundle outState) {
super
.onSaveInstanceState(outState);
mMapView.onSaveInstanceState(outState);
}
@Override
protected
void
onRestoreInstanceState(Bundle savedInstanceState) {
super
.onRestoreInstanceState(savedInstanceState);
mMapView.onRestoreInstanceState(savedInstanceState);
}
@Override
public
boolean
onCreateOptionsMenu(Menu menu) {
return
true
;
}
}
/**
* 继承MapView重写onTouchEvent实现泡泡处理操作
*
* @author Administrator
*
*/
class
MyLocationMapView
extends
MapView {
static
PopupOverlay pop =
null
;
// 弹出泡泡图层,点击图标使用
public
MyLocationMapView(Context context) {
super
(context);
}
public
MyLocationMapView(Context context, AttributeSet attrs) {
super
(context, attrs);
}
public
MyLocationMapView(Context context, AttributeSet attrs,
int
defStyle) {
super
(context, attrs, defStyle);
}
@Override
public
boolean
onTouchEvent(MotionEvent event) {
if
(!
super
.onTouchEvent(event)) {
// 消隐泡泡
if
(pop !=
null
&& event.getAction() == MotionEvent.ACTION_UP)
pop.hidePop();
}
return
true
;
}
}
|
地图工具类:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
|
package
com.home;
import
android.graphics.Bitmap;
import
android.view.View;
public
class
BMapUtil {
/**
* 从view 得到图片
*
* @param view
* @return
*/
public
static
Bitmap getBitmapFromView(View view) {
view.destroyDrawingCache();
view.measure(View.MeasureSpec.makeMeasureSpec(
0
,
View.MeasureSpec.UNSPECIFIED), View.MeasureSpec
.makeMeasureSpec(
0
, View.MeasureSpec.UNSPECIFIED));
view.layout(
0
,
0
, view.getMeasuredWidth(), view.getMeasuredHeight());
view.setDrawingCacheEnabled(
true
);
Bitmap bitmap = view.getDrawingCache(
true
);
return
bitmap;
}
}
|
配置文件:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
|
<?
xml
version
=
"1.0"
encoding
=
"utf-8"
?>
<
manifest
xmlns:android
=
"http://schemas.android.com/apk/res/android"
package
=
"com.home"
android:versionCode
=
"1"
android:versionName
=
"1.0"
>
<
uses-sdk
android:minSdkVersion
=
"10"
android:targetSdkVersion
=
"10"
/>
<!-- 使用网络功能所需权限 -->
<
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
>
<!-- 使用GPS需要的权限 -->
<
uses-permission
android:name
=
"android.permission.ACCESS_FINE_LOCATION"
/>
<!--
添加屏幕支持
android:anyDensity="true"
这个属性指明应用程序是否包含了能够适用于任何屏幕密度的资源。
对于支持Android1.6(API Level 4)和更高版本的应用程序,这个属性的默认值是true,
并且除非绝对的确认这是应用程序正常工作所必须的,否则不应该把它设置为false。
只是在应用程序直接操作位图时才需要禁止这个属性。
android:largeScreens="true"
这个属性用于指示应用程序是否支持较大外形的屏幕。
一个large类型的屏幕被定义成一个比normal类型的手持设备的屏幕明显还要大的屏幕,
并且为了让应用程序能够良好的使用,使用这个属性时要特别小心,尽管可以依赖系统来调整尺寸,
以便能够填充屏幕。
这个属性的默认值实际上在某些版本之间是不同的,因此最好在任何时候都明确的声明这个属性。
如果设置为false,系统会启用屏幕兼容模式,这时要格外的小心。
android:normalScreens="true"
这个属性用于指示应用程序是否支持普通外形的屏幕。
典型的是HVGA中等密度的屏幕,但是WQVGA低密度和WVGA高密度屏幕也被认为是普通屏幕。
这个属性的默认值是true。
android:smallScreens="true"
这个属性用于指定应用程序是否支持较小外形的屏幕。
一个small类型的屏幕被定义成一个比normal(传统的HVGA)类型的屏幕还要小的屏幕。
外部服务(如Google Play)不会把不支持小屏的应用程序提供给小屏设备,
因为很少有能够确保该应用程序在小屏幕的设备上正常工作的平台。这个属性的默认值是true。
android:resizeable="true"
这个属性用于指示针对不同的屏幕尺寸,应用程序是否可以调整尺寸。默认值是true。
-->
<
supports-screens
android:anyDensity
=
"true"
android:largeScreens
=
"true"
android:normalScreens
=
"true"
android:resizeable
=
"true"
android:smallScreens
=
"true"
/>
<
application
android:name
=
"com.home.DemoApplication"
android:allowBackup
=
"true"
android:icon
=
"@drawable/ic_launcher"
android:label
=
"@string/app_name"
android:theme
=
"@style/AppTheme"
>
<
activity
android:name
=
"com.home.LocationOverlayActivity"
android:label
=
"@string/app_name"
>
<
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:process
=
":remote"
>
</
service
>
</
application
>
</
manifest
>
|
注意:该配置文件与之前的有个区别,多了一个service,它是百度jar包下的一个服务类,这是定位必须要的,不然就不能定位。
Application类同之前一样。
布局文件:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
|
<?
xml
version
=
"1.0"
encoding
=
"utf-8"
?>
<
RelativeLayout
xmlns:android
=
"http://schemas.android.com/apk/res/android"
android:layout_width
=
"match_parent"
android:layout_height
=
"match_parent"
>
<
com.home.MyLocationMapView
android:id
=
"@+id/bmapView"
android:layout_width
=
"fill_parent"
android:layout_height
=
"fill_parent"
android:clickable
=
"true"
/>
<
LinearLayout
android:layout_width
=
"wrap_content"
android:layout_height
=
"wrap_content"
android:layout_alignParentRight
=
"true"
android:layout_marginTop
=
"80dip"
android:background
=
"#D000"
android:minWidth
=
"100dip"
android:orientation
=
"vertical"
android:padding
=
"2dp"
>
<
RadioGroup
android:id
=
"@+id/radioGroup"
android:layout_width
=
"wrap_content"
android:layout_height
=
"wrap_content"
android:contentDescription
=
"定位icon"
>
<
RadioButton
android:id
=
"@+id/defaulticon"
android:layout_width
=
"wrap_content"
android:layout_height
=
"wrap_content"
android:checked
=
"true"
android:text
=
"默认图标"
>
</
RadioButton
>
<
RadioButton
android:id
=
"@+id/customicon"
android:layout_width
=
"wrap_content"
android:layout_height
=
"wrap_content"
android:text
=
"自定义图标"
>
</
RadioButton
>
</
RadioGroup
>
</
LinearLayout
>
<
Button
android:id
=
"@+id/button1"
android:layout_width
=
"wrap_content"
android:layout_height
=
"wrap_content"
android:layout_alignParentRight
=
"true"
android:layout_alignParentTop
=
"true"
android:layout_marginRight
=
"25dp"
android:layout_marginTop
=
"10dip"
android:background
=
"@drawable/custom_loc"
/>
</
RelativeLayout
>
|
custom_text_view.xml:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
|
<?
xml
version
=
"1.0"
encoding
=
"utf-8"
?>
<
LinearLayout
xmlns:android
=
"http://schemas.android.com/apk/res/android"
android:layout_width
=
"wrap_content"
android:layout_height
=
"wrap_content"
android:orientation
=
"horizontal"
>
<
TextView
android:id
=
"@+id/popleft"
android:layout_width
=
"wrap_content"
android:layout_height
=
"wrap_content"
android:background
=
"@drawable/popup_side"
android:gravity
=
"center"
android:text
=
"更新位置"
android:textColor
=
"#3814ed"
android:textSize
=
"12sp"
android:textStyle
=
"bold"
/>
<
LinearLayout
android:id
=
"@+id/popinfo"
android:layout_width
=
"wrap_content"
android:layout_height
=
"wrap_content"
android:orientation
=
"vertical"
>
<
TextView
android:id
=
"@+id/textcache"
android:layout_width
=
"wrap_content"
android:layout_height
=
"wrap_content"
android:background
=
"@drawable/popup_middle"
android:gravity
=
"center"
android:textColor
=
"@android:color/black"
android:textSize
=
"12sp"
android:textStyle
=
"bold"
/>
<
TextView
android:id
=
"@+id/popdown"
android:layout_width
=
"fill_parent"
android:layout_height
=
"wrap_content"
android:background
=
"@drawable/popup_down"
android:textColor
=
"@android:color/black"
android:textSize
=
"12sp"
/>
</
LinearLayout
>
<
TextView
android:id
=
"@+id/popright"
android:layout_width
=
"wrap_content"
android:layout_height
=
"wrap_content"
android:background
=
"@drawable/popup_side"
android:gravity
=
"center"
android:text
=
"更新marker"
android:textColor
=
"#3814ed"
android:textSize
=
"12sp"
android:textStyle
=
"bold"
/>
</
LinearLayout
>
|
附上图片效果:
来自:http://blog.csdn.net/u010142437/article/details/11577077