| import android.content.Context; | |
| import android.content.Intent; | |
| import android.location.Address; | |
| import android.location.Criteria; | |
| import android.location.Geocoder; | |
| import android.location.Location; | |
| import android.location.LocationListener; | |
| import android.location.LocationManager; | |
| import android.location.LocationProvider; | |
| import android.os.Bundle; | |
| import android.provider.Settings; | |
| import java.io.IOException; | |
| import java.util.List; | |
| import java.util.Locale; | |
| /** | |
| * <pre> | |
| * author: Blankj | |
| * blog : http://blankj.com | |
| * time : 16/11/13 | |
| * desc : 定位相关工具类 | |
| * </pre> | |
| */ | |
| public final class LocationUtils { | |
| private static OnLocationChangeListener mListener; | |
| private static MyLocationListener myLocationListener; | |
| private static LocationManager mLocationManager; | |
| private LocationUtils() { | |
| throw new UnsupportedOperationException("u can't instantiate me..."); | |
| } | |
| /** | |
| * 判断Gps是否可用 | |
| * | |
| * @return {@code true}: 是<br>{@code false}: 否 | |
| */ | |
| public static boolean isGpsEnabled() { | |
| LocationManager lm = (LocationManager) Utils.getContext().getSystemService(Context.LOCATION_SERVICE); | |
| return lm.isProviderEnabled(LocationManager.GPS_PROVIDER); | |
| } | |
| /** | |
| * 判断定位是否可用 | |
| * | |
| * @return {@code true}: 是<br>{@code false}: 否 | |
| */ | |
| public static boolean isLocationEnabled() { | |
| LocationManager lm = (LocationManager) Utils.getContext().getSystemService(Context.LOCATION_SERVICE); | |
| return lm.isProviderEnabled(LocationManager.NETWORK_PROVIDER) || lm.isProviderEnabled(LocationManager.GPS_PROVIDER); | |
| } | |
| /** | |
| * 打开Gps设置界面 | |
| */ | |
| public static void openGpsSettings() { | |
| Intent intent = new Intent(Settings.ACTION_LOCATION_SOURCE_SETTINGS); | |
| intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK); | |
| Utils.getContext().startActivity(intent); | |
| } | |
| /** | |
| * 注册 | |
| * <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(long minTime, long minDistance, OnLocationChangeListener listener) { | |
| if (listener == null) return false; | |
| mLocationManager = (LocationManager) Utils.getContext().getSystemService(Context.LOCATION_SERVICE); | |
| mListener = listener; | |
| if (!isLocationEnabled()) { | |
| ToastUtils.showShortToastSafe("无法定位,请打开定位服务"); | |
| 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(); | |
| 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; | |
| } | |
| } | |
| /** | |
| * 设置定位参数 | |
| * | |
| * @return {@link Criteria} | |
| */ | |
| private static Criteria getCriteria() { | |
| Criteria criteria = new Criteria(); | |
| //设置定位精确度 Criteria.ACCURACY_COARSE比较粗略,Criteria.ACCURACY_FINE则比较精细 | |
| criteria.setAccuracy(Criteria.ACCURACY_FINE); | |
| //设置是否要求速度 | |
| criteria.setSpeedRequired(false); | |
| // 设置是否允许运营商收费 | |
| criteria.setCostAllowed(false); | |
| //设置是否需要方位信息 | |
| criteria.setBearingRequired(false); | |
| //设置是否需要海拔信息 | |
| criteria.setAltitudeRequired(false); | |
| // 设置对电源的需求 | |
| 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(Utils.getContext(), 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 getCountryName(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 (mListener != null) { | |
| mListener.onLocationChanged(location); | |
| } | |
| } | |
| /** | |
| * provider的在可用、暂时不可用和无服务三个状态直接切换时触发此函数 | |
| * | |
| * @param provider 提供者 | |
| * @param status 状态 | |
| * @param extras provider可选包 | |
| */ | |
| @Override | |
| public void onStatusChanged(String provider, int status, Bundle extras) { | |
| if (mListener != null) { | |
| mListener.onStatusChanged(provider, status, extras); | |
| } | |
| switch (status) { | |
| case LocationProvider.AVAILABLE: | |
| LogUtils.d("onStatusChanged", "当前GPS状态为可见状态"); | |
| break; | |
| case LocationProvider.OUT_OF_SERVICE: | |
| LogUtils.d("onStatusChanged", "当前GPS状态为服务区外状态"); | |
| break; | |
| case LocationProvider.TEMPORARILY_UNAVAILABLE: | |
| LogUtils.d("onStatusChanged", "当前GPS状态为暂停服务状态"); | |
| break; | |
| } | |
| } | |
| /** | |
| * provider被enable时触发此函数,比如GPS被打开 | |
| */ | |
| @Override | |
| public void onProviderEnabled(String provider) { | |
| } | |
| /** | |
| * provider被disable时触发此函数,比如GPS被关闭 | |
| */ | |
| @Override | |
| public void onProviderDisabled(String 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);//位置状态发生改变 | |
| } | |
| } |
定位相关→LocationUtils
最新推荐文章于 2025-06-24 23:33:31 发布
本工具类提供了Android设备上的定位功能,包括检查GPS和网络定位服务的状态、获取最后一次已知的位置信息、监听位置更新等。同时支持通过经纬度获取地理位置详情。
623

被折叠的 条评论
为什么被折叠?



