读书人

百度map之定位图层

发布时间: 2013-10-08 16:46:23 作者: rapoo

百度地图之定位图层

在使用百度地图结合GPS进行定位一文中,我们已经介绍了利用GPS结合百度地图进行定位,另外我们也可以使用百度SDK里面集成的方法,直接进行定位,这样就不需要我们自己去写GPS定位的方法了,代码原型来自百度Demo,代码如下:

Activity:

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;// 泡泡viewprivate View viewCache = null;// 地图相关,使用继承MapView的MyLocationMapView目的是重写touch事件实现泡泡处理// 如果不处理touch事件,则无需继承,直接使用MapView即可MyLocationMapView mMapView = null; // 地图Viewprivate MapController mMapController = null;// UI相关OnCheckedChangeListener radioButtonListener = null;Button requestLocButton = null;boolean isRequest = false;// 是否手动触发请求定位boolean isFirstLoc = true;// 是否首次定位@Overridepublic 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() {@Overridepublic void onClick(View v) {// 手动定位请求requestLocClick();}};requestLocButton.setOnClickListener(btnClickListener);RadioGroup group = (RadioGroup) this.findViewById(R.id.radioGroup);radioButtonListener = new OnCheckedChangeListener() {@Overridepublic void onCheckedChanged(RadioGroup group, int checkedId) {if (checkedId == R.id.defaulticon) {// 传入null则,恢复默认图标modifyLocationOverlayIcon(null);}if (checkedId == R.id.customicon) {// 修改为自定义markermodifyLocationOverlayIcon(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);// 打开gpsoption.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() {@Overridepublic void onClickedPopup(int index) {Log.v("click", "clickapoapo");}};pop = new PopupOverlay(mMapView, popListener);MyLocationMapView.pop = pop;}/** * 定位SDK监听函数 */public class MyLocationListenner implements BDLocationListener {@Overridepublic 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);}@Overrideprotected 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;}}@Overrideprotected void onPause() {mMapView.onPause();super.onPause();}@Overrideprotected void onResume() {mMapView.onResume();super.onResume();}@Overrideprotected void onDestroy() {// 退出时销毁定位if (mLocClient != null)mLocClient.stop();mMapView.destroy();super.onDestroy();}@Overrideprotected void onSaveInstanceState(Bundle outState) {super.onSaveInstanceState(outState);mMapView.onSaveInstanceState(outState);}@Overrideprotected void onRestoreInstanceState(Bundle savedInstanceState) {super.onRestoreInstanceState(savedInstanceState);mMapView.onRestoreInstanceState(savedInstanceState);}@Overridepublic 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);}@Overridepublic boolean onTouchEvent(MotionEvent event) {if (!super.onTouchEvent(event)) {// 消隐泡泡if (pop != null && event.getAction() == MotionEvent.ACTION_UP)pop.hidePop();}return true;}}

地图工具类:

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;}}


配置文件:

<?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类同之前一样。

布局文件:

<?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:

<?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>

附上图片效果:

百度map之定位图层





读书人网 >移动开发

热点推荐