定位功能之MyLocationOverlay,PopupOverlay的使用

转载请注明出处

这一篇文章主要讲解的是百度地图的定位功能,然后还有MyLocationOverlay和PopupOverlay两个地图覆盖物的使用,Overlay是“图层”或“覆盖物”的意思,MyLocationOverlay从名字上面理解就是我的位置图层,他能够实现在地图上显示当前位置的图标以及指南针,MyLocationOverlay只负责显示我的位置,位置数据请使用百度定位SDK获取,将获取的位置数据放在一个LocationData结构中并用该结构设置MyLcationOverlay的数据源,即可创建MyLocationOverlay,PopupOverlay就是弹出窗口图层了,跟PopupWindow类似的东西,下面会介绍他们的使用方法

定位我们使用的是百度Android 定位SDKv4.0,我们先了解下定位原理和定位精度

定位原理

使用百度Android定位SDK必须注册GPS和网络使用权限。定位SDK采用GPS、基站、Wi-Fi信号进行定位。当应用程序向定位SDK发起定位请求时,定位SDK会根据应用的定位因素(GPS、基站、Wi-Fi信号)的实际情况(如是否开启GPS、是否连接网络、是否有信号等)来生成相应定位依据进行定位。用户可以设置满足自身需求的定位依据:若用户设置GPS优先,则优先使用GPS进行定位,如果GPS定位未打开或者没有可用位置信息,且网络连接正常,定位SDK则会返回网络定位(即Wi-Fi与基站)的最优结果。为了使获得的网络定位结果更加精确,请打开手机的Wi-Fi开关。

定位精度

了解了百度定位的原理和定位精度之后,接下来我们就来使用百度定位SDKv4.0吧

一 . 导入库文件

在使用百度定位SDKv4.0之前,我们要下载最新的库文件,下载地址:点击下载相关库文件,将liblocSDK4.so文件拷贝到libs/armeabi目录下。将locSDK4.0.jar文件拷贝到工程的libs目录下

二 . 布局文件,一个百度地图控件,加一个手动点击实现定位的按钮,放在一个相对布局里面,很简单的布局

<?xml version="1.0" encoding="utf-8"?><RelativeLayout xmlns:android=""android:layout_width="fill_parent"android:layout_height="fill_parent" ><com.baidu.mapapi.map.MapViewandroid:id="@+id/bmapView"android:layout_width="fill_parent"android:layout_height="fill_parent"android:clickable="true" /><Buttonandroid:id="@+id/request"android:layout_width="wrap_content"android:layout_height="wrap_content"android:layout_alignParentRight="true"android:layout_alignParentTop="true"android:layout_marginRight="10dp"android:layout_marginTop="10dip"android:background="@drawable/custom_loc" /></RelativeLayout>

三 . 界面MainActivity代码,先贴上,然后适当讲解相关代码,我注释也比较清楚

package com.example.baidumapdemo;import android.app.Activity;import android.graphics.Bitmap;import android.os.Bundle;import android.util.Log;import android.view.LayoutInflater;import android.view.View;import android.view.View.MeasureSpec;import android.view.View.OnClickListener;import android.widget.Button;import android.widget.TextView;import android.widget.Toast;import com.baidu.location.BDLocation;import com.baidu.location.BDLocationListener;import com.baidu.location.LocationClient;import com.baidu.location.LocationClientOption;import com.baidu.mapapi.BMapManager;import com.baidu.mapapi.MKGeneralListener;import com.baidu.mapapi.map.LocationData;import com.baidu.mapapi.map.MKEvent;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;public class MainActivity extends Activity {private Toast mToast;private BMapManager mBMapManager;private MapView mMapView = null;private MapController mMapController = null;/** * 定位SDK的核心类 */private LocationClient mLocClient;/** * 用户位置信息 */private LocationData mLocData;/** * 我的位置图层 */privateLocationOverlay myLocationOverlay = null;/** * 弹出窗口图层 */private PopupOverlay mPopupOverlay = null;private boolean isRequest = false;//是否手动触发请求定位private boolean isFirstLoc = true;//是否首次定位/** * 弹出窗口图层的View */private View mPopupView;private BDLocation location;@Overrideprotected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);//使用地图sdk前需先初始化BMapManager,这个必须在setContentView()先初始化mBMapManager = new BMapManager(this);//第一个参数是API key,//第二个参数是常用事件监听,用来处理通常的网络错误,授权验证错误等,你也可以不添加这个回调接口mBMapManager.init("7ae13368159d6a513eaa7a17b9413b4b", new MKGeneralListenerImpl());setContentView(R.layout.activity_main);//点击按钮手动请求定位((Button) findViewById(R.id.request)).setOnClickListener(new OnClickListener() {@Overridepublic void onClick(View v) {requestLocation();}});mMapView = (MapView) findViewById(R.id.bmapView); //获取百度地图控件实例mMapController = mMapView.getController(); //获取地图控制器mMapController.enableClick(true); //设置地图是否响应点击事件mMapController.setZoom(14); //设置地图缩放级别mMapView.setBuiltInZoomControls(true); //显示内置缩放控件mMapView.setTraffic(true); //设置交通信息图//mMapView.setSatellite(true); //设置卫星图//mMapController.setOverlooking(-45); //设置地图俯视角度 ,范围:0~ -45mPopupView = LayoutInflater.from(this).inflate(R.layout.pop_layout, null);//实例化弹出窗口图层mPopupOverlay = new PopupOverlay(mMapView ,new PopupClickListener() {/*** 点击弹出窗口图层回调的方法*/@Overridepublic void onClickedPopup(int arg0) {//隐藏弹出窗口图层mPopupOverlay.hidePop();}});//实例化定位服务,LocationClient类必须在主线程中声明mLocClient = new LocationClient(getApplicationContext());mLocClient.registerLocationListener(new BDLocationListenerImpl());//注册定位监听接口/** * LocationClientOption 该类用来设置定位SDK的定位方式。 */LocationClientOption option = new LocationClientOption();option.setOpenGps(true); //打开GPRSoption.setAddrType("all");//返回的定位结果包含地址信息option.setCoorType("bd09ll");//返回的定位结果是百度经纬度,默认值gcj02option.setPriority(LocationClientOption.GpsFirst); // 设置GPS优先option.setScanSpan(5000); //设置发起定位请求的间隔时间为5000msoption.disableCache(false);//禁止启用缓存定位//option.setPoiNumber(5); //最多返回POI个数 //option.setPoiDistance(1000); //poi查询距离//option.setPoiExtraInfo(true); //是否需要POI的电话和地址等详细信息mLocClient.setLocOption(option); //设置定位参数mLocClient.start(); //调用此方法开始定位//定位图层初始化myLocationOverlay = new LocationOverlay(mMapView);//实例化定位数据,并设置在我的位置图层mLocData = new LocationData();myLocationOverlay.setData(mLocData);//添加定位图层mMapView.getOverlays().add(myLocationOverlay);//修改定位数据后刷新图层生效mMapView.refresh();}/** * 定位接口,需要实现两个方法 * @author xiaanming * */public class BDLocationListenerImpl implements BDLocationListener {/** * 接收异步返回的定位结果,参数是BDLocation类型参数 */@Overridepublic void onReceiveLocation(BDLocation location) {if (location == null) {return;}StringBuffer sb = new StringBuffer(256);sb.append("time : ");sb.append(location.getTime());sb.append("\nerror code : ");sb.append(location.getLocType());sb.append("\nlatitude : ");sb.append(location.getLatitude());sb.append("\nlontitude : ");sb.append(location.getLongitude());sb.append("\nradius : ");sb.append(location.getRadius());if (location.getLocType() == BDLocation.TypeGpsLocation){sb.append("\nspeed : ");sb.append(location.getSpeed());sb.append("\nsatellite : ");sb.append(location.getSatelliteNumber());} else if (location.getLocType() == BDLocation.TypeNetWorkLocation){sb.append("\naddr : ");sb.append(location.getAddrStr());}Log.e("log", sb.toString());MainActivity.this.location = location;mLocData.latitude = location.getLatitude();mLocData.longitude = location.getLongitude();//如果不显示定位精度圈,将accuracy赋值为0即可mLocData.accuracy = location.getRadius();mLocData.direction = location.getDerect();//将定位数据设置到定位图层里myLocationOverlay.setData(mLocData);//更新图层数据执行刷新后生效mMapView.refresh();if(isFirstLoc || isRequest){//将给定的位置点以动画形式移动至地图中心mMapController.animateTo(new GeoPoint((int) (location.getLatitude() * 1e6), (int) (location.getLongitude() * 1e6)));showPopupOverlay(location);isRequest = false;}isFirstLoc = false;}/** * 接收异步返回的POI查询结果,参数是BDLocation类型参数 */@Overridepublic void onReceivePoi(BDLocation poiLocation) {}}//继承MyLocationOverlay重写dispatchTap方法private class LocationOverlay extends MyLocationOverlay{public LocationOverlay(MapView arg0) {super(arg0);}/** * 在“我的位置”坐标上处理点击事件。 */@Overrideprotected boolean dispatchTap() {//点击我的位置显示PopupOverlayshowPopupOverlay(location);return super.dispatchTap();}}/** * 显示弹出窗口图层PopupOverlay * @param location */private void showPopupOverlay(BDLocation location){ TextView popText = ((TextView)mPopupView.findViewById(R.id.location_tips)); popText.setText("[我的位置]\n" + location.getAddrStr()); mPopupOverlay.showPopup(getBitmapFromView(popText),new GeoPoint((int)(location.getLatitude()*1e6), (int)(location.getLongitude()*1e6)),15);}/** * 手动请求定位的方法 */public void requestLocation() {isRequest = true;if(mLocClient != null && mLocClient.isStarted()){showToast("正在定位……");mLocClient.requestLocation();}else{Log.d("log", "locClient is null or not started");}}/*** 显示Toast消息* @param msg*/private void showToast(String msg){if(mToast == null){mToast = Toast.makeText(this, msg, Toast.LENGTH_SHORT);}else{mToast.setText(msg);mToast.setDuration(Toast.LENGTH_SHORT);}mToast.show();}/** * 将View转换成Bitmap的方法 * @param view * @return */public static Bitmap getBitmapFromView(View view) {view.measure(MeasureSpec.makeMeasureSpec(0, MeasureSpec.UNSPECIFIED), MeasureSpec.makeMeasureSpec(0, MeasureSpec.UNSPECIFIED));view.layout(0, 0, view.getMeasuredWidth(), view.getMeasuredHeight());view.buildDrawingCache();Bitmap bitmap = view.getDrawingCache();return bitmap;}/** * 常用事件监听,用来处理通常的网络错误,授权验证错误等 * @author xiaanming * */public class MKGeneralListenerImpl implements MKGeneralListener{/** * 一些网络状态的错误处理回调函数 */@Overridepublic void onGetNetworkState(int iError) {if (iError == MKEvent.ERROR_NETWORK_CONNECT) {showToast("您的网络出错啦!");}}/** * 授权错误的时候调用的回调函数 */@Overridepublic void onGetPermissionState(int iError) {if (iError == MKEvent.ERROR_PERMISSION_DENIED) {showToast("API KEY错误, 请检查!");}}}@Overrideprotected void onResume() {//MapView的生命周期与Activity同步,,当activity挂起时需调用MapView.onPause()mMapView.onResume();super.onResume();}@Overrideprotected void onPause() {//MapView的生命周期与Activity同步,当activity挂起时需调用MapView.onPause()mMapView.onPause();super.onPause();}@Overrideprotected void onDestroy() {//MapView的生命周期与Activity同步,当activity销毁时需调用MapView.destroy()mMapView.destroy();//退出应用调用BMapManager的destroy()方法if(mBMapManager != null){mBMapManager.destroy();mBMapManager = null;}//退出时销毁定位if (mLocClient != null){mLocClient.stop();}super.onDestroy();}}

四 . 在运行程序之前,我们还必须在AndroidManifest.xml进行相关配置和权限的声明

在application标签中声明service组件,每个app拥有自己单独的定位service

以一种进取的和明智的方式同它们奋斗。

定位功能之MyLocationOverlay,PopupOverlay的使用

相关文章:

你感兴趣的文章:

标签云: