在application标签中声明service组件,为了避免多个app公用1个service出现的权限问题,新版本各个app单独拥有自己的定位service.
<!-- com.baidu.location.f 为百度定位的服务 --> <service android:name="com.baidu.location.f" android:enabled="true" android:process=":remote" > </service><!-- 需要出示的权限 --> <uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION"/> <uses-permission android:name="android.permission.ACCESS_FINE_LOCATION"/> <uses-permission android:name="android.permission.ACCESS_WIFI_STATE"/> <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE"/> <uses-permission android:name="android.permission.CHANGE_WIFI_STATE"/> <uses-permission android:name="android.permission.READ_PHONE_STATE"/> <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/> <uses-permission android:name="android.permission.INTERNET" /> <uses-permission android:name="android.permission.MOUNT_UNMOUNT_FILESYSTEMS"/> <uses-permission android:name="android.permission.READ_LOGS"/>
(1).实例化LocationClient
{ //Context需要时全进程有效的context,推荐用getApplicationConext获取全进程有效的context mLocationClient = new LocationClient(getApplicationContext()); mLocationClient.setAK("我的密钥");//写入密钥 //注册监听函数 mLocationClient.registerLocationListener( myListener ); }(2).实现BDLocationListener接口
public class MyLocationListener implements BDLocationListener { @Override public void onReceiveLocation(BDLocation location) { /* * mLocClient.requestLocation();执行后,前提client已经开启 */ if (location == null) return; if (location.getLocType() == BDLocation.TypeGpsLocation){//卫星定位 location.getSpeed(); location.getSatelliteNumber(); } else if (location.getLocType() == BDLocation.TypeNetWorkLocation){//网络定位 location.getAddrStr();//LocationClientOption.setAddrType("all");需要设置 } } public void onReceivePoi(BDLocation poiLocation) { /* * mLocClient.requestPoi();执行后,前提client已经开启 */ if (poiLocation == null){ return ; } poiLocation.getTime(); poiLocation.getLocType(); poiLocation.getLatitude(); poiLocation.getLongitude(); poiLocation.getRadius(); if (poiLocation.getLocType() == BDLocation.TypeGpsLocation){//卫星定位 poiLocation.getSpeed(); poiLocation.getSatelliteNumber(); } else if (poiLocation.getLocType() == BDLocation.TypeNetWorkLocation){//网络定位 poiLocation.getAddrStr();//LocationClientOption.setAddrType("all");需要设置 } } }(3).设置定位参数
LocationClientOption option = new LocationClientOption(); option.setOpenGps(true); //打开GPS /* * 返回的定位结果包含地址信息, 如果不设置,location.getAddrStr();返回为null */ option.setAddrType("all"); option.setCoorType("bd09ll");//返回的定位结果是百度经纬度,默认值gcj02 option.setScanSpan(1000 * 60); //设置发起定位请求的间隔时间 option.disableCache(true); //禁止启用缓存定位 option.setPoiNumber(5); //最多返回POI个数 option.setPoiDistance(1000); //poi查询距离 option.setPoiExtraInfo(true); //是否需要POI的电话和地址等详细信息 mClient.setLocOption(getClientOptions());(4).发起定位请求
/** * 在请求定位之前应该确定mCLient已经启动 */ if (mClient != null && mClient.isStarted()) mClient.requestLocation(); //onReceiveLocation();将得到定位数据 else{ }// 发起POI查询请求 if (mClient != null && mClient.isStarted()) mClient.requestPoi(); //onReceivePoi();将得到定位数据 else{ }
// MyLocationOverlay实例化 locationOverlay = new MyLocationOverlay(mMapView); locationOverlay.enableCompass(); locationData = new LocationData(); // 设置定位数据 locationOverlay.setData(locationData); // 设置中心图片 // locationOverlay.setMarker(getResources().getDrawable(R.drawable.ic_launcher)); // 设置定位的模式(NORMAL, FOLLOWING,COMPASS )三种 locationOverlay.setLocationMode(LocationMode.FOLLOWING); // 添加定位图层 mMapView.getOverlays().add(locationOverlay); // 修改定位数据后刷新图层生效 mMapView.refresh();如果想处理MyLocationOverlay的tap时间,必须覆写dispatchTap()方法,但是mMapController.enableClick(true)
/** * 覆写MyLocationOverlay,处理Tap(简单的click)事件 * */ private class LocationOverlay extends MyLocationOverlay { public LocationOverlay(MapView mapView) { super(mapView); } @Override protected boolean dispatchTap() { /* * click事件的处理,如果想处理事件必须,mMapController.enableClick(true); * 否则无响应 */ Toast.makeText(getApplicationContext(), "click~~", 0).show(); return true; } }
/** * * @author zimo * @see http://blog.csdn.net/zimo2013 */ public class LocationProvider { private static final String TAG = "LocationProvider"; private LocationClient mClient; private BDLocationListener mListener; public LocationProvider(Context context){ mClient = new LocationClient(context); //配置密钥key mClient.setAK("我的密钥"); //配置定位参数信息 mClient.setLocOption(getClientOptions()); } /** * 请求开始定位 */ public void start(){ if(mListener == null){ LogUtil.e(TAG, "请在调用start()之前,先调用setLocationListener设定监听器"); return; } if(!mClient.isStarted()){ LogUtil.i(TAG, "定位开启!"); mClient.start(); } mClient.requestLocation(); } public void stop(){ if(mClient.isStarted()){ LogUtil.i(TAG, "定位关闭!"); mClient.stop(); } } public void setLocationListener(BDLocationListener l){ mListener = l; mClient.registerLocationListener(l); } private LocationClientOption getClientOptions(){ LocationClientOption option = new LocationClientOption(); option.setOpenGps(true); //打开GPS /* * 返回的定位结果包含地址信息, 如果不设置,location.getAddrStr();返回为null */ option.setAddrType("all"); option.setCoorType("bd09ll");//返回的定位结果是百度经纬度,默认值gcj02 option.setScanSpan(1000 * 60); //设置发起定位请求的间隔时间 option.disableCache(true); //禁止启用缓存定位 option.setPoiNumber(5); //最多返回POI个数 option.setPoiDistance(1000); //poi查询距离 option.setPoiExtraInfo(true); //是否需要POI的电话和地址等详细信息 return option; } }public class MainActivity extends Activity implements BDLocationListener { BMapManager mBMapMan = null; MapView mMapView = null; LocationClient client; LocationData locationData; MyLocationOverlay locationOverlay; MapController mMapController; LocationProvider provider; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); mBMapMan = new BMapManager(getApplication()); mBMapMan.init("647a2e8859989d9d6e1e6d5db525e177", null); // 注意:请在试用setContentView前初始化BMapManager对象,否则会报错 setContentView(R.layout.activity_main); mMapView = (MapView) findViewById(R.id.bmapsView); mMapView.setBuiltInZoomControls(true); mMapController = mMapView.getController(); // 设置启用内置的缩放控件 mMapController.setZoom(14); // 得到mMapView的控制权,可以用它控制和驱动平移和缩放 GeoPoint point = new GeoPoint((int) (39.915 * 1E6), (int) (116.404 * 1E6)); // 用给定的经纬度构造一个GeoPoint,单位是微度 (度 * 1E6) mMapController.setCenter(point);// 设置地图中心点 mMapController.setZoom(14);// 设置地图zoom级别 locationData = new LocationData(); locationOverlay = new MyLocationOverlay(mMapView); // 设置定位数据 locationOverlay.setData(locationData); // 添加定位图层 mMapView.getOverlays().add(locationOverlay); locationOverlay.enableCompass(); // 修改定位数据后刷新图层生效 mMapView.refresh(); } public void click(View view) { //click button请求定位 provider = new LocationProvider(getApplicationContext()); provider.setLocationListener(this); provider.start(); //开始定位 } @Override public void onReceiveLocation(BDLocation location) { locationData.latitude = location.getLatitude(); locationData.longitude = location.getLongitude(); // 如果不显示定位精度圈,将accuracy赋值为0即可 locationData.accuracy = location.getRadius(); // 此处可以设置 locData的方向信息, 如果定位 SDK 未返回方向信息,用户可以自己实现罗盘功能添加方向信息。 locationData.direction = location.getDerect(); // 更新定位数据 locationOverlay.setData(locationData); // 更新图层数据执行刷新后生效 mMapView.refresh(); Toast.makeText(getApplicationContext(), location.getAddrStr(), 1) .show(); mMapController.animateTo(new GeoPoint( (int) (locationData.latitude * 1e6), (int) (locationData.longitude * 1e6))); } @Override public void onReceivePoi(BDLocation location) { } @Override protected void onResume() { mMapView.onResume(); if (mBMapMan != null) { mBMapMan.start(); } super.onResume(); } @Override protected void onPause() { mMapView.onPause(); if (mBMapMan != null) { mBMapMan.stop(); } //如果没有必要,应该停止定位 if(provider != null){ provider.stop(); provider = null; } super.onPause(); } @Override protected void onDestroy() { mMapView.destroy(); if (mBMapMan != null) { mBMapMan.destroy(); mBMapMan = null; } super.onDestroy(); } }