文章来自:http://blog.csdn.net/intbird
- 关于定位的几点体验
- 地图上使用定位
- 定位信息说明
- 应用内确保定位返回结果思考
- 应用内使用定位服务代码
- 代码基础使用方法
关于定位的几点体验:
- 百度定位:定位返回很快,很及时,推荐使用,单次定位,能很大程度的保证应用获取位置,5.1的定位有了位置提醒;
- 高德定位:和系统的很像,需要设置定位的米和时间,有时候不返回,有时候返回一大推,不清楚它机制是什么,不推荐;
- 系统定位:单纯的户外使用返回还是很不错的,如果是做一个骑行记录轨迹的,系统的不会产生重复记录,即看你的参数设置,不动可不返回结果;
地图上使用定位:
地图上没有自带的定位方式,即地图和定位是独立的,可以让任意的位置信息放入 我的位置 上,也可以用高德地图,用百度定位,让使用中的地图去显示小蓝点,当然也可以是自己定位的任意样式;
定位信息说明:
-百度定位:定位类型可以默认就很好;
在startLocation()时貌似会返回两次定位结果,request好像是返回一次结果,百度定位的时间联网时时网络时间,时间格式是字符串,在网络定位时会返回具体信息,如果是断网情况下,返回当前手机时间,不定位不耗电,定位经纬度位数比较短;
-高德地图:定位类型有三种,AmapNetWork即可,request(),应该和系统定位是一致的,返回时间为当前手机时间,如果没有订到位置,getLastKnow为上一次定位时间,lbs包含更多信息,定位经纬度位数比较长;
-系统定位:定位类型有三种,network,gps,passive,在室内使用返回成功几乎不可能,在网络定位还好,
应用内确保定位返回结果思考
如果定位结果包含反地理编码信息,则直接保存结果,如果是gps定位信息,则进行反地理编码,保存结果
如果长时间取不到位置,则由定时器返回上次位置
如需要处理位置的重复返回多次,根据HashMap的类型去获取上次该类型的具体信息,主要为判断该类型的时间间隔,精度纬度偏差等等,如果偏差较小,可拦截该次定位结果
应用内使用定位服务代码:
BDLocationManager.java
GDLocationManager.java
MyAppLocation.java;
MyAppLocationListener.java;
注意使用的经纬度类型问题,由于涉及业务,Utils里两个文件不贴出来.定位本来就很简单,就是处理封装一下保证应用的位置准确和速度.有需要后台监控位置变化的,这里不做介绍.
1. BDLocationManager.java
import com.baidu.location.BDLocation;import com.baidu.location.BDLocationListener;import com.baidu.location.LocationClient;import com.baidu.location.LocationClientOption;/** * 百度定位5.1 * @author intbird * */public class BDLocationManager { private static BDLocationManager instance = null; private static final int timeOutLocation = 8*1000; private static final int timeSpanLocation= 500;//单次定位 public LocationClient mLocationClient; private MyBDLocationListener mBDLocationListener; private MyAppLocationListener myAppListener; public static BDLocationManager getInstance(){ if (instance == null){ instance = new BDLocationManager(); } return instance; } private BDLocationManager(){ super(); //定位初始化 mLocationClient = new LocationClient(AppContext.getInstance().getApplicationContext()); mBDLocationListener = new MyBDLocationListener(); mLocationClient.registerLocationListener(mBDLocationListener); LocationClientOption option = new LocationClientOption(); option.setOpenGps(true);//打开gps option.setAddrType("all"); option.setCoorType("bd09ll"); //设置坐标类型 option.setScanSpan(timeSpanLocation); option.setTimeOut(timeOutLocation); mLocationClient.setLocOption(option); } public void start(MyAppLocationListener listener){ this.myAppListener = listener; if (mLocationClient != null){ if(mLocationClient.isStarted()){ mLocationClient.requestLocation(); }else{ mLocationClient.start(); } } } public void destroy(){ //mLocationClient.stop(); //mLocationClient.unRegisterLocationListener(mBDLocationListener); } private class MyBDLocationListener implements BDLocationListener { @Override public void onReceiveLocation(BDLocation location) { if(location==null) return; int locType = location.getLocType(); if(locType==BDLocation.TypeGpsLocation || locType==BDLocation.TypeNetWorkLocation|| locType==BDLocation.TypeOffLineLocation|| locType==BDLocation.TypeCacheLocation ){ MyAppLocation.getInstance().onLocationSussess(location, myAppListener); destroy(); }else{ MyAppLocation.getInstance().onLocationedFaild(myAppListener); if(locType==BDLocation.TypeServerError){ MyToast.showToast(Frame.getInstance().getAppContext(),"定位失败,请允许使用位置服务"); } } } }; public BDLocation getLastKnowLocation(){ if(mLocationClient!=null){ return mLocationClient.getLastKnownLocation(); } return null; }}
- GDLocationManager.java
import android.location.Location;import android.os.Bundle;import com.amap.api.location.AMapLocation;import com.amap.api.location.AMapLocationListener;import com.amap.api.location.LocationManagerProxy;import com.amap.api.location.LocationProviderProxy;/** * 高德定位,NOTE:有时可能不返回定位结果; * @author intbird * */public class GDLocationManager { private static GDLocationManager instance = null; private int locTimemills = 2 * 60 * 1000; private int locMeters = 300; private LocationManagerProxy aMapManager; private MyAMapLocationListener aMapLocationListener; private MyAppLocationListener myAppListener; public static GDLocationManager getInstance(){ if (instance == null){ instance = new GDLocationManager(); } return instance; } private GDLocationManager(){ super(); aMapManager = LocationManagerProxy.getInstance(AppContext.getInstance().getApplicationContext()); aMapLocationListener = new MyAMapLocationListener(); } public void start(MyAppLocationListener listener) { this.myAppListener = listener; if (aMapManager == null) { aMapManager.requestLocationData(LocationProviderProxy.AMapNetwork, locTimemills, locMeters, aMapLocationListener); } } public void destroy() { if (aMapManager != null) { aMapManager.removeUpdates(instance.aMapLocationListener); aMapManager.destroy(); } } public AMapLocation getLastKnowLocation(){ if(aMapManager!=null){ return aMapManager.getLastKnownLocation(LocationProviderProxy.AMapNetwork); } return null; } private class MyAMapLocationListener implements AMapLocationListener{ @Override public void onLocationChanged(Location location) { } @Override public void onStatusChanged(String provider, int status, Bundle extras) { } @Override public void onProviderEnabled(String provider) { } @Override public void onProviderDisabled(String provider) { } @Override public void onLocationChanged(AMapLocation amapLocation) { if(amapLocation != null){ if(amapLocation.getAMapException().getErrorCode() == 0) { MyAppLocation.getInstance().onLocationSussess(amapLocation, myAppListener); destroy(); }else { MyAppLocation.getInstance().onLocationedFaild(myAppListener); } } } }}
- MyAppLocation.java;
java
HashMap<MapType, HashMap<String, String>> mapGpsContains
= new HashMap<MapType, HashMap<String,String>>();//用于位置去重;
import java.text.SimpleDateFormat;import java.util.Calendar;import android.os.CountDownTimer;import android.text.TextUtils;import com.amap.api.location.AMapLocation;import com.amap.api.services.core.LatLonPoint;import com.amap.api.services.geocoder.RegeocodeAddress;import com.amap.api.services.geocoder.RegeocodeResult;import com.baidu.location.BDLocation;import com.idonoo.frame.GlobalInfo;import com.idonoo.frame.dao.DbGPSInfo;import com.idonoo.frame.types.MapType;/** * 负责app内定位信息 * @author intbird * */public class MyAppLocation { private static MyAppLocation bdLocation; public static MyAppLocation getInstance() { if(bdLocation==null){ bdLocation = new MyAppLocation(); } return bdLocation; } private MyAppLocationListener locationListener; private CountDownTimer timer; private int timeOutCacelLocation = 8*1000; public MyAppLocation(){ GlobalInfo.getInstance().setGpsInfo(LocationInfoUtil.getGpsInfo());//看哪个先调用; getTimerLocation(); } /** * 仅用于保存位置使用.尽量使用true,已防止经纬度和地址不匹配; * @param isSilentRegeo 是否静默使用定位且反地理编码 */ public void startLocation(boolean isSilentRegeo){ if(isSilentRegeo){ MyDefaultAppLocationInfoListener listener= new MyDefaultAppLocationInfoListener(); listener.setRegeLocationInfo(true); startLocation(listener); }else{ startLocation(null); } } /** * App 默认定位方式接入方法 * @param listener */ public void startLocation(MyAppLocationListener listener){ startLocation(MapType.eBaiDuMap,listener); } public void startLocation(MapType mapType,MyAppLocationListener listener){ this.locationListener = listener; switch(mapType){ case eBaiDuMap: default: BDLocationManager.getInstance().start(listener); break; case eGaoDeMap: GDLocationManager.getInstance().start(listener); break; } timer.start(); } public void onLocationSussess(BDLocation location,MyAppLocationListener listener){ LocationInfoUtil.setGPSInfo(location); long timeMills = System.currentTimeMillis(); if(!TextUtils.isEmpty(location.getTime())){ try{ Calendar c = Calendar.getInstance(); c.setTime(new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").parse(location.getTime())); timeMills = c.getTimeInMillis(); }catch(Exception ex){ } } if(location.getLocType()==BDLocation.TypeNetWorkLocation) if(listener!=null) listener.setRegeLocationInfo(false); double[] point = LocationPointUtil.getAmapLocationFormBD(location.getLatitude(), location.getLongitude()); onLocationSussess(timeMills,point[0],point[1],listener); } public void onLocationSussess(AMapLocation location,MyAppLocationListener listener){ LocationInfoUtil.setGPSInfo(location); long timeMills = location.getTime(); if(!TextUtils.isEmpty(location.getProvider())&&location.getProvider().contains("lbs")) if(listener!=null) listener.setRegeLocationInfo(false); onLocationSussess(timeMills,location.getLatitude(),location.getLongitude(),listener); } public void onLocationSussess(long timeMills,double lan,double lon,MyAppLocationListener listener){ if(listener != null){ //先返回位置,在返回位置信息,即[返回两次]; listener.onLocation(timeMills,lan, lon); if(listener.isRegeLocationInfo()){ getLocationInfo(lan, lon, listener); }else{ listener.onLocation(GlobalInfo.getInstance().getGpsInfo()); } } timer.cancel(); } public void onLocationedFaild(MyAppLocationListener listener){ double[] locs = getLastKnowLocation(); if(listener != null){ listener.onLocation(-1,locs[0], locs[1]); } timer.cancel(); } private void getLocationInfo(final double lan,final double lon,final MyAppLocationListener listener) { GDGeoManager.getInstance().reverseGeocode(new LatLonPoint(lan, lon), new GDGeoManagerListener() { @Override public void onGeocodeStart() { } @Override public void onRegeocodeSearched(RegeocodeResult regeocodeResult, int i) { if (i != 0 || regeocodeResult == null) return; RegeocodeAddress address = regeocodeResult.getRegeocodeAddress(); if (address == null||TextUtils.isEmpty(address.getFormatAddress())) return; DbGPSInfo gpsInfo = LocationInfoUtil.getGPSInfo(regeocodeResult); LocationInfoUtil.setGPSInfo(gpsInfo); if(listener!=null) listener.onLocation(gpsInfo); } }); } public double[] getLastKnowLocation(){ BDLocation locBD = BDLocationManager.getInstance().getLastKnowLocation(); if(locBD != null&&LocationPointUtil.isChinaLonLant(locBD.getLatitude(),locBD.getLongitude())) return LocationPointUtil.getAmapLocationFormBD(locBD.getLatitude(),locBD.getLongitude()); AMapLocation locGD = GDLocationManager.getInstance().getLastKnowLocation(); if(locGD != null&&LocationPointUtil.isChinaLonLant(locGD.getLatitude(),locGD.getLongitude())) return new double[]{locGD.getLatitude(),locGD.getLongitude()}; DbGPSInfo gpsInfo = GlobalInfo.getInstance().getGpsInfo(); if(gpsInfo!=null&&LocationPointUtil.isChinaLonLant(gpsInfo.getLatitude(),gpsInfo.getLongitude())){ return new double[]{gpsInfo.getLatitude(), gpsInfo.getLongitude()}; } startLocation(true); return new double[]{0.0, 0.0}; } private void getTimerLocation(){ timer = new CountDownTimer(timeOutCacelLocation, 1000) { @Override public void onTick(long millisUntilFinished) { } @Override public void onFinish() { if(locationListener!=null){ onLocationedFaild(locationListener); } } }; } //默认定位类,可不理会; protected class MyDefaultAppLocationInfoListener extends MyAppLocationListener{ @Override public void onLocation(long timeMills,double lan, double lon) { } @Override public void onLocation(DbGPSInfo info) { } }}
- MyAppLocationListener.java;
import com.idonoo.frame.dao.DbGPSInfo;import com.idonoo.frame.types.MapType;public abstract class MyAppLocationListener { public boolean isRegeLocationInfo = false; private MapType mapType; public boolean isRegeLocationInfo() { return isRegeLocationInfo; } public void setRegeLocationInfo(boolean isNeedRese) { this.isRegeLocationInfo = isNeedRese; } public MapType getMapType() { return mapType; } public void setMapType(MapType mapType) { this.mapType = mapType; } public abstract void onLocation(long timeMills,double lan, double lon); public abstract void onLocation(DbGPSInfo info);}
代码基础使用方法
直接使用,最长定位时间为MyAppLocation中设定的8s,超过8s返回上次,或者返回0且在此进行定位请求;
MyAppLocation.getInstance().startLocation(true);//默认检索位置的详细信息,不返回给界面,默认后台存储具体信息入库;
先返回经纬度,后返回改经纬度的具体信息,在BaseActivity中添加改代码,在任何Activity可用;
public void startLocation(boolean isShowProgress,boolean isRegeInfo){ if(isShowProgress) showProgress("获取位置..."); MyAppLocationInfoListener listener = new MyAppLocationInfoListener(); listener.setRegeLocationInfo(isRegeInfo); MyAppLocation.getInstance().startLocation(listener); } public void onLocationed(double lan,double lon) { dismissProgress(); } public void onLocationed(DbGPSInfo info) { dismissProgress(); }
附加一个系统定位的,可无视.
package com.idonoo.shareCar.vendor.record;import java.util.List;import android.content.Context;import android.location.Location;import android.location.LocationListener;import android.location.LocationManager;import android.os.Bundle;import android.text.TextUtils;import com.idonoo.frame.Frame;import com.idonoo.frame.model.Locations;import com.idonoo.frame.types.MapType;/** * 系统定位 * @author intbird * */public class LocationAS { private LocationManager locationMangaerForGPS; private LocationManager locationMangaerForNetWork; private LocationManager locationMangaerForUncertain; private MySALocationListener locationListener; //minTime should be the primary tool to conserving battery life private int locTimemills = 2 * 60 * 1000; private int locMeters = 300; public void setLocTimemills(int locTimemills) { this.locTimemills = locTimemills; } public void setLocMeters(int locMeters) { this.locMeters = locMeters; } public void start(LocationPointCallBack callBack){ locationListener = new MySALocationListener(callBack); locationMangaerForUncertain = (LocationManager)Frame.getInstance().getAppContext().getSystemService(Context.LOCATION_SERVICE); locationMangaerForGPS = (LocationManager)Frame.getInstance().getAppContext().getSystemService(Context.LOCATION_SERVICE); locationMangaerForNetWork = (LocationManager)Frame.getInstance().getAppContext().getSystemService(Context.LOCATION_SERVICE); try{//RuntimeException - if the calling thread has no Looper //SecurityException - if no suitable permission is present locationMangaerForUncertain.requestLocationUpdates(LocationManager.PASSIVE_PROVIDER, locTimemills, locMeters, locationListener); locationMangaerForGPS.requestLocationUpdates(LocationManager.GPS_PROVIDER, locTimemills, locMeters, locationListener); locationMangaerForNetWork.requestLocationUpdates(LocationManager.NETWORK_PROVIDER, locTimemills, locMeters, locationListener); }catch(Exception ex){ } } private void startProvider(String currentProvider,boolean enableStatus){ if(TextUtils.isEmpty(currentProvider)) return ; if(locationListener==null||locationMangaerForUncertain==null) return ; List<String> privoders = locationMangaerForUncertain.getAllProviders(); if(privoders==null) return ; if(enableStatus==false){ Location location=null; for(String privoder : privoders){ if(privoder.equalsIgnoreCase(currentProvider)||TextUtils.isEmpty(privoder)) continue; if(privoder.equalsIgnoreCase(LocationManager.GPS_PROVIDER)){ try{ location = locationMangaerForGPS.getLastKnownLocation(LocationManager.GPS_PROVIDER); locationMangaerForGPS.requestLocationUpdates(LocationManager.GPS_PROVIDER, locTimemills, locMeters, locationListener); }catch(Exception ex){ } } else if(privoder.equalsIgnoreCase(LocationManager.NETWORK_PROVIDER)){ try{ location = locationMangaerForNetWork.getLastKnownLocation(LocationManager.NETWORK_PROVIDER); locationMangaerForNetWork.requestLocationUpdates(LocationManager.NETWORK_PROVIDER, locTimemills, locMeters, locationListener); }catch(Exception ex){ } }else { try{ location = locationMangaerForUncertain.getLastKnownLocation(LocationManager.PASSIVE_PROVIDER); locationMangaerForUncertain.requestLocationUpdates(privoder,locTimemills, locMeters, locationListener); }catch(Exception ex){ } } } if(location != null&&locationListener.mCallBack!=null){ locationListener.mCallBack.locted("AS",new Locations(location.getTime(),location.getTime(),location.getLongitude(), location.getLatitude(), MapType.eAndServer.getValue(),location.getProvider())); } } } //the provider is disabled by the user, updates will stop. public void stop(){ if(null!=locationListener&&null!=locationMangaerForGPS){ locationMangaerForGPS.removeUpdates(locationListener); locationMangaerForNetWork.removeUpdates(locationListener); locationMangaerForUncertain.removeUpdates(locationListener); } } private class MySALocationListener implements LocationListener { private LocationPointCallBack mCallBack; public MySALocationListener(LocationPointCallBack callBack){ this.mCallBack= callBack; } @Override public void onStatusChanged(String provider, int status, Bundle extras) { } @Override public void onProviderEnabled(String provider) { startProvider(provider,true); } @Override public void onProviderDisabled(String provider) { startProvider(provider,false); } @Override public void onLocationChanged(Location location) { if(location != null){ if(mCallBack != null && isCallBack(location.getTime())){ mCallBack.locted("AS",new Locations(location.getTime(),location.getTime(),location.getLongitude(), location.getLatitude(), MapType.eAndServer.getValue(),location.getProvider())); } } } }}
end;