Android百度地图之定位图层

来自: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 >

附上图片效果:

d8.png

来自:http://blog.csdn.net/u010142437/article/details/11577077

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值