位置相關工具類

/** * 位置相關工具類 * <p> * 需添加的權限: * {@code <uses-permission android:name="android.permission.INTERNET"/>} * {@code <uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION"/>} * {@code <uses-permission android:name="android.permission.ACCESS_FINE_LOCATION"/>} * </p> */ public class LocationUtil { private static LocationManager mLocationManager; private static MyLocationListener myLocationListener; private static OnLocationChangeListener mLocationChangedListener; private static OnProviderStatusListener mProviderStatusListener; private LocationUtil() { throw new UnsupportedOperationException("cannot be instantiated"); } /** * 判斷 Gps 是否可用 * * @return {@code true}: 是<br>{@code false}: 否 */ public static boolean isGpsEnabled(Context context) { LocationManager lm = (LocationManager) context.getSystemService(Context.LOCATION_SERVICE); return lm.isProviderEnabled(LocationManager.GPS_PROVIDER); } /** * 判斷定位是否可用 * * @return {@code true}: 是<br>{@code false}: 否 */ public static boolean isLocationEnabled(Context context) { LocationManager lm = (LocationManager) context.getSystemService(Context.LOCATION_SERVICE); return lm.isProviderEnabled(LocationManager.NETWORK_PROVIDER) || lm.isProviderEnabled(LocationManager.GPS_PROVIDER); } /** * 設置 Provider 狀態監聽器 * <p>請在{@link #register(Context context, long minTime, long minDistance, OnLocationChangeListener listener)}前調用</p> * * @param listener {@link OnProviderStatusListener} */ public static void setProviderStatusListener(OnProviderStatusListener listener) { mProviderStatusListener = listener; } /** * 註冊 * <p>使用完記得調用{@link #unregister()}</p> * <p>需添加權限 {@code <uses-permission android:name="android.permission.INTERNET"/>}</p> * <p>需添加權限 {@code <uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION"/>}</p> * <p>需添加權限 {@code <uses-permission android:name="android.permission.ACCESS_FINE_LOCATION"/>}</p> * <p>如果{@code minDistance}爲0,則通過{@code minTime}來定時更新;</p> * <p>{@code minDistance}不爲0,則以{@code minDistance}爲準;</p> * <p>兩者都爲0,則隨時刷新。</p> * * @param minTime 位置信息更新週期(單位:毫秒) * @param minDistance 位置變化最小距離:當位置距離變化超過此值時,將更新位置信息(單位:米) * @param listener 位置刷新的回調接口 * @return {@code true}: 初始化成功<br>{@code false}: 初始化失敗 */ public static boolean register(Context context, long minTime, long minDistance, OnLocationChangeListener listener) { if (listener == null) return false; mLocationManager = (LocationManager) context.getSystemService(Context.LOCATION_SERVICE); mLocationChangedListener = listener; if (!isLocationEnabled(context)) { ToastUtil.show("無法定位,請打開定位服務"); return false; } String provider = mLocationManager.getBestProvider(getCriteria(), true); Location location = mLocationManager.getLastKnownLocation(provider); if (location != null) listener.getLastKnownLocation(location); if (myLocationListener == null) myLocationListener = new MyLocationListener(); // 定位監聽 // 參數 1,設備:有 GPS_PROVIDER 和 NETWORK_PROVIDER 兩種 // 參數 2,位置信息更新週期,單位毫秒 // 參數 3,位置變化最小距離:當位置距離變化超過此值時,將更新位置信息 // 參數 4,監聽 // 備註:參數 2 和 3,如果參數 3 不爲 0,則以參數 3 爲準;參數 3 爲 0,則通過時間來定時更新;兩者爲 0,則隨時刷新 // 1 秒更新一次,或最小位移變化超過1米更新一次; // 注意:此處更新準確度非常低,推薦在 service 裏面啓動一個 Thread,在 run 中 sleep(10000); 然後執行 handler.sendMessage(), 更新位置 mLocationManager.requestLocationUpdates(provider, minTime, minDistance, myLocationListener); return true; } /** * 註銷 */ public static void unregister() { if (mLocationManager != null) { if (myLocationListener != null) { mLocationManager.removeUpdates(myLocationListener); myLocationListener = null; } mLocationManager = null; } if (mLocationChangedListener != null) mLocationChangedListener = null; if (mProviderStatusListener != null) mProviderStatusListener = null; } /** * 設置定位參數 */ private static Criteria getCriteria() { Criteria criteria = new Criteria(); // 設置定位精確度 Criteria.ACCURACY_COARSE 比較粗略,Criteria.ACCURACY_FINE 則比較精細 criteria.setAccuracy(Criteria.ACCURACY_FINE); // 設置是否要求速度 criteria.setSpeedRequired(true); // 設置是否允許運營商收費 criteria.setCostAllowed(false); // 設置是否需要方位信息 criteria.setBearingRequired(true); // 設置是否需要海拔信息 criteria.setAltitudeRequired(true); // 設置對電源的需求 criteria.setPowerRequirement(Criteria.POWER_LOW); return criteria; } /** * 根據經緯度獲取地理位置 * * @param latitude 緯度 * @param longitude 經度 * @return {@link Address} */ public static Address getAddress(double latitude, double longitude) { Geocoder geocoder = new Geocoder(SUtils.getApp(), Locale.getDefault()); try { List<Address> addresses = geocoder.getFromLocation(latitude, longitude, 1); if (addresses.size() > 0) { return addresses.get(0); } } catch (IOException e) { e.printStackTrace(); } return null; } /** * 根據經緯度獲取所在國家 * * @param latitude 緯度 * @param longitude 經度 * @return 所在國家 */ public static String getCountry(double latitude, double longitude) { Address address = getAddress(latitude, longitude); return address == null ? "unknown" : address.getCountryName(); } /** * 根據經緯度獲取所在地 * * @param latitude 緯度 * @param longitude 經度 * @return 所在地 */ public static String getLocality(double latitude, double longitude) { Address address = getAddress(latitude, longitude); return address == null ? "unknown" : address.getLocality(); } /** * 根據經緯度獲取所在街道 * * @param latitude 緯度 * @param longitude 經度 * @return 所在街道 */ public static String getStreet(double latitude, double longitude) { Address address = getAddress(latitude, longitude); return address == null ? "unknown" : address.getAddressLine(0); } private static class MyLocationListener implements LocationListener { /** * 當座標改變時觸發此函數,如果 Provider 傳進相同的座標,它就不會被觸發 * * @param location 座標 */ @Override public void onLocationChanged(Location location) { if (mLocationChangedListener != null) { mLocationChangedListener.onLocationChanged(location); } } /** * Provider 在可用、暫時不可用和無服務三個狀態直接切換時觸發此函數 * * @param provider 提供者 * @param status 狀態 * @param extras Provider 可選包 */ @Override public void onStatusChanged(String provider, int status, Bundle extras) { if (mLocationChangedListener != null) { mLocationChangedListener.onStatusChanged(provider, status, extras); } switch (status) { case LocationProvider.AVAILABLE: LogUtil.d("LocationListener onStatusChanged ========> ", "當前GPS狀態爲可見狀態"); break; case LocationProvider.OUT_OF_SERVICE: LogUtil.d("LocationListener onStatusChanged ========> ", "當前GPS狀態爲服務區外狀態"); break; case LocationProvider.TEMPORARILY_UNAVAILABLE: LogUtil.d("LocationListener onStatusChanged ========> ", "當前GPS狀態爲暫停服務狀態"); break; } } /** * Provider 被 enable 時觸發此函數,比如GPS被打開 */ @Override public void onProviderEnabled(String provider) { if (mProviderStatusListener != null) { mProviderStatusListener.providerEnabled(provider); } } /** * Provider 被 disable 時觸發此函數,比如GPS被關閉 */ @Override public void onProviderDisabled(String provider) { if (mProviderStatusListener != null) { mProviderStatusListener.providerDisabled(provider); } } } public interface OnLocationChangeListener { /** * 獲取最後一次保留的座標 * * @param location 座標 */ void getLastKnownLocation(Location location); /** * 當座標改變時觸發此函數,如果 Provider 傳進相同的座標,它就不會被觸發 * * @param location 座標 */ void onLocationChanged(Location location); /** * Provider 在可用、暫時不可用和無服務三個狀態直接切換時觸發此函數 * * @param provider 提供者 * @param status 狀態 * @param extras Provider 可選包 */ void onStatusChanged(String provider, int status, Bundle extras);// 位置狀態發生改變 } /** * Provider 狀態監聽器 */ public interface OnProviderStatusListener { /** * Provider 被 enable 時觸發此函數,比如GPS被打開 */ void providerEnabled(String provider); /** * Provider 被 disable 時觸發此函數,比如GPS被關閉 */ void providerDisabled(String provider); } }
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章