• 百度地图之定位图层


    使用百度地图结合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;// 泡泡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;
    	}
    }
    

    地图工具类:

    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>





     



     

  • 相关阅读:
    >>> fout = open('output.txt', 'w') Traceback (most recent call last): File "<stdin>", line 1, in <module> PermissionError: [Errno 13] Permission denied: 'output.txt'
    Python元组术语
    Python元组与列表_元组与字典
    Python元组_参数长度可变
    Python元组_赋值与返回值
    Python元组_不可修改
    第二篇-bmob云端服务器的发现
    第一篇-关于语言与计划
    《JavaScript》JS中的常用方法attr(),splice()
    Java接口interface,匿名内部类
  • 原文地址:https://www.cnblogs.com/riskyer/p/3315342.html
Copyright © 2020-2023  润新知