文章来自: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;
- 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;