android:应用程序内定位处理,百度定位,高德定位,系统定位处理.

来源:互联网 发布:佛教历史 知乎 编辑:程序博客网 时间:2024/05/01 16:36

文章来自:http://blog.csdn.net/intbird

    • 应用内确保定位返回结果思考
    • 关于定位的几点体验
    • 地图上使用定位
    • 定位信息说明
    • 应用内使用定位服务代码
    • 代码基础使用方法

应用内确保定位返回结果思考

如果定位结果为网络定位,已包含地址具体信息,直接保存结果,标记为网络定位

如果是gps定位信息,则只有经纬度,进行反地理编码,保存具体信息结果,标记为网络定位

如果长时间取不到位置,则由定时器计时指定时间返回上次位置,也就是最长8s返回定位,标记为定时器返回

如果始终没有取到位置,那么返回(0,0) ,并且后台再次获取位置,直到位置有效或者超出次数限制而停止

多次返回去重:如需要处理位置的重复返回多次,根据类型去获取Map中上次该类型的信息,对比,主要判断该类型的时间间隔,精度纬度偏差等等

关于定位的几点体验:

  • 百度定位:定位返回很快,很及时,推荐使用,单次定位,能很大程度的保证应用获取位置,5.1的定位有了位置提醒;
  • 高德定位:和系统的很像,需要设置定位的米和时间,有时候不返回,有时候返回一大推,不清楚它机制是什么,不推荐;
  • 系统定位:单纯的户外使用返回还是很不错的,如果是做一个骑行记录轨迹的,系统的不会产生重复记录,即看你的参数设置,不动可不返回结果;

地图上使用定位:

地图上没有自带的定位方式,即地图和定位是独立的,可以让任意的位置信息放入 我的位置 上,也可以用高德地图,用百度定位,让使用中的地图去显示小蓝点,当然也可以是自己定位的任意样式;

定位信息说明:

-百度定位:定位类型可以默认就很好;
在startLocation()时貌似会返回两次定位结果,request好像是返回一次结果,百度定位的时间联网时时网络时间,时间格式是字符串,在网络定位时会返回具体信息,如果是断网情况下,返回当前手机时间,不定位不耗电,定位经纬度位数比较短;
-高德地图:定位类型有三种,AmapNetWork即可,request(),应该和系统定位是一致的,返回时间为当前手机时间,如果没有订到位置,getLastKnow为上一次定位时间,lbs包含更多信息,定位经纬度位数比较长;
-系统定位:定位类型有三种,network,gps,passive,在室内使用返回成功几乎不可能,在网络定位还好,

应用内使用定位服务代码:

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;    }}
  1. 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);                }            }        }    }}
  1. 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) {        }    }}
  1. 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;

1 1
原创粉丝点击