/** * @description: * @author chenshiqiang E-mail:csqwyyx@163.com * @date 2014年4月27日 下午5:26:53 * @version 1.0 */ package com.csq.thesceneryalong.logic.manager; import java.util.ArrayList; import java.util.List; import android.location.Location; import android.location.LocationManager; import android.os.Bundle; import android.os.Handler; import android.os.Handler.Callback; import android.os.Message; import com.amap.api.location.AMapLocation; import com.amap.api.location.AMapLocationListener; import com.amap.api.location.LocationManagerProxy; import com.amap.api.location.LocationProviderProxy; import com.csq.thesceneryalong.app.App; import com.csq.thesceneryalong.utils.location.LastLocationValidate; import com.csq.thesceneryalong.utils.location.LocationUtil; public class MyLocationManager { // ------------------------ Constants ------------------------ private volatile static MyLocationManager instance; public static MyLocationManager getInstance() { synchronized (MyLocationManager.class) { if (instance == null) { instance = new MyLocationManager(); } } return instance; } private MyLocationManager() { locationManager = LocationManagerProxy .getInstance(App.app); mLocationValider = new LastLocationValidate(); } // ------------------------- Fields -------------------------- private LocationManagerProxy locationManager; /** 当前位置 */ private Location mCurrentLocation; private LastLocationValidate mLocationValider = null; private AMapLocationListener locationListener = new AMapLocationListener() { @Override public void onProviderDisabled(String provider) { // Do nothing } @Override public void onProviderEnabled(String provider) { // Do nothing } @Override public void onStatusChanged(String provider, int status, Bundle extras) { // Do nothing } @Override public void onLocationChanged(final AMapLocation loc) { if(loc == null){ return; } if(loc.getTime() == 0){ //网络定位,时间可能为0 loc.setTime(System.currentTimeMillis()); } //纠偏,通知保存的都是gcj的经纬度 LocationUtil.wgsToGcj(loc, false); if(mCurrentLocation == null || mLocationValider.isBetterLocation(loc, mCurrentLocation)){ //位置有效 mCurrentLocation = loc; handler.removeMessages(WHAT_LOCATION_CHANGED); Message msg = handler.obtainMessage(); msg.what = WHAT_LOCATION_CHANGED; msg.obj = mCurrentLocation; handler.sendMessage(msg); } } @Override public void onLocationChanged(Location arg0) { // TODO Auto-generated method stub } }; private final int WHAT_LOCATION_CHANGED = 6; private Handler handler = new Handler(new Callback() { @Override public boolean handleMessage(Message msg) { // TODO Auto-generated method stub if(msg.what == WHAT_LOCATION_CHANGED){ Location loc = (Location) msg.obj; //位置更新相关操作 for(LocationCallback lc : locationCallbacks){ lc.locationChanged(loc); } } return false; } }); /** * 定位最短时间,毫秒 */ private long locateMinTimeSeconds = 5000; /** * 定位最短距离,米 */ private float locateMinDistanceMeters = 8; /** * 所有应用程序位置监听器 */ private List<LocationCallback> locationCallbacks = new ArrayList<LocationCallback>(); // ----------------------- Constructors ---------------------- // -------- Methods for/from SuperClass/Interfaces ----------- // --------------------- Methods public ---------------------- private volatile boolean isListenLocation = false; /** * @description: 开始定位 * @author: chenshiqiang E-mail:csqwyyx@163.com */ public synchronized void startListenLocation(){ if(!isListenLocation){ if(locationManager.getProvider(LocationProviderProxy.AMapNetwork) != null){ // API定位采用GPS定位方式,第一个参数是定位provider,第二个参数时间最短是2000毫秒 //第三个参数距离间隔单位是米,第四个参数是定位监听者 locationManager.requestLocationUpdates(LocationProviderProxy.AMapNetwork, locateMinTimeSeconds, locateMinDistanceMeters, locationListener); } if(locationManager.getProvider(LocationManager.GPS_PROVIDER) != null){ locationManager.requestLocationUpdates(LocationManager.GPS_PROVIDER, locateMinTimeSeconds, locateMinDistanceMeters, locationListener); } isListenLocation = true; } } /** * @description: 停止定位 * @author: chenshiqiang E-mail:csqwyyx@163.com */ public synchronized void stopListenLocation(){ //只要有需要回调位置的地方,不能停止定位 if(isListenLocation && locationCallbacks.isEmpty()){ locationManager.removeUpdates(locationListener); isListenLocation = false; } } /** * @description: 注册一个位置回调 * @author: chenshiqiang E-mail:csqwyyx@163.com * @param listener */ public void registLocationCallback(LocationCallback listener){ locationCallbacks.add(listener); } /** * @description: 取消注册一个位置回调 * @author: chenshiqiang E-mail:csqwyyx@163.com * @param listener */ public void unRegistLocationCallback(LocationCallback listener){ locationCallbacks.remove(listener); } // --------------------- Methods private --------------------- // --------------------- Getter & Setter --------------------- /** * @description: 获取当前位置 * @author: chenshiqiang E-mail:csqwyyx@163.com */ public Location getCurrentLocation() { return mCurrentLocation; } /** * @description: 获取最近gcj位置,先获取mCurrentLocation,再getLastKnowLocation(先gps,再网络) * @author: chenshiqiang E-mail:csqwyyx@163.com */ public Location getLatestKnowLocation() { Location loc = getCurrentLocation(); if(loc == null){ loc = locationManager.getLastKnownLocation(LocationManager.GPS_PROVIDER); if(loc == null){ loc = locationManager.getLastKnownLocation(LocationProviderProxy.AMapNetwork); } //不是通过getLastKnownLocation获得的,都是新的,可以改变原始对象 if(loc != null){ LocationUtil.wgsToGcj(loc, false); } } return loc; } // --------------- Inner and Anonymous Classes --------------- public interface LocationCallback{ public void locationChanged(Location newLoc); } }