• 定位-----LocationUtils

package com.behe.treasure.util;

import android.Manifest;
import android.annotation.SuppressLint;
import android.content.Context;
import android.location.Address;
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.support.annotation.Nullable;

import java.io.IOException;
import java.util.List;

/**
 * Created by Jevons Lee on 2017/3/31.
 * 定位
 */

public class LocationUtil {

private static OnResponseListener responseListener;
    private static LocationUtil locationUtil;

private LocationManager locationManager;
    private android.location.Location currentBestLocation;
    private NetworkListener networkListener;
    private GPSLocationListener gpsListener;

private LocationUtil() {
    }

/**
     * 定位模式
     */
    public enum Mode{
        NETWORK,    //网络定位
        GPS,        //GPS定位
        AUTO        //自动定位,使用网络或GPS定位
    }

public static final int NO_PERMISSION = 1;  //没权限
    public static final int GPS_CLOSE = 2;  //GPS是关闭的
    public static final int UNAVAILABLE = 3;  //不可用

/**
     * 请求定位
     */
    public static void requestLocation(Context context, Mode mode, OnResponseListener onResponseListener) {
        LocationUtil.responseListener = onResponseListener;
        if (PermissionUtil.checkPermission(context, Manifest.permission.ACCESS_FINE_LOCATION) ||
                PermissionUtil.checkPermission(context,Manifest.permission.ACCESS_COARSE_LOCATION)){
            L.i("获取定位权限,开始定位");
            //开始定位
            locationUtil = new LocationUtil();
            locationUtil.startLocation(context,mode);
        } else {
            L.i("没有定位权限,定位失败");
            String provider = mode == Mode.GPS ? LocationManager.GPS_PROVIDER : LocationManager.NETWORK_PROVIDER;
            onResponseListener.onErrorResponse(provider, NO_PERMISSION);
        }
    }

long l;

/**
     * 开始定位
     */
    private void startLocation(Context context, Mode mode) {
        locationManager = (LocationManager) context.getSystemService(Context.LOCATION_SERVICE);

if (PermissionUtil.checkPermission(context,Manifest.permission.ACCESS_FINE_LOCATION) ||
                PermissionUtil.checkPermission(context,Manifest.permission.ACCESS_COARSE_LOCATION)){
            switch (mode){
                case NETWORK:
                    if (locationManager.isProviderEnabled(LocationManager.NETWORK_PROVIDER)){
                        L.i("网络定位");
                        networkListener = new NetworkListener();
                        locationManager.requestLocationUpdates(LocationManager.NETWORK_PROVIDER, 500, 0.1f, networkListener);
                    } else {
                        responseListener.onErrorResponse(LocationManager.NETWORK_PROVIDER, UNAVAILABLE);
                    }
                    break;
                case GPS:
                    if (locationManager.isProviderEnabled(LocationManager.GPS_PROVIDER)){
                        L.i("GPS定位");
                        gpsListener = new GPSLocationListener();
                        l = System.currentTimeMillis();
                        locationManager.requestLocationUpdates(LocationManager.GPS_PROVIDER, 1000 * 2, 0.1f, gpsListener);
                    } else {
                        responseListener.onErrorResponse(LocationManager.GPS_PROVIDER, GPS_CLOSE);
                    }

break;
                case AUTO:
                    if (locationManager.isProviderEnabled(LocationManager.NETWORK_PROVIDER)){
                        L.i("自动定位选择网络定位");
                        networkListener = new NetworkListener();
                        locationManager.requestLocationUpdates(LocationManager.NETWORK_PROVIDER, 500, 0.1f, networkListener);
                    } else if (locationManager.isProviderEnabled(LocationManager.GPS_PROVIDER)) {
                        L.i("自动定位选择gps");
                        gpsListener = new GPSLocationListener();
                        locationManager.requestLocationUpdates(LocationManager.GPS_PROVIDER, 1000 * 2, 0.1f, gpsListener);
                    } else {
                        responseListener.onErrorResponse(LocationManager.NETWORK_PROVIDER, UNAVAILABLE);
                    }

break;
                default:

break;
            }
        } else {
            L.e("无权限");
        }
    }

/**
     * 停止定位
     */
    public static void stopLocation(){
        if (locationUtil == null){
            L.e("locationUtil is null");
            return;
        }
        if (locationUtil.networkListener != null){
            locationUtil.locationManager.removeUpdates(locationUtil.networkListener);
        }
        if (locationUtil.gpsListener != null){
            locationUtil.locationManager.removeUpdates(locationUtil.gpsListener);
        }
        L.i("停止定位");
    }

private class GPSLocationListener implements LocationListener {

@Override
        public void onLocationChanged(Location location) {
            L.i("onLocationChanged");
            if (location != null) {
                L.i("GPS定位成功");
                L.i("GPS定位耗时:" + ((System.currentTimeMillis() - l) / 1000) + "秒");
                boolean isBetter = isBetterLocation(location, currentBestLocation);
                if (isBetter) {
                    currentBestLocation = location;
                }
                double latitude = currentBestLocation.getLatitude();    //纬度
                double longitude = currentBestLocation.getLongitude();  //经度
                responseListener.onSuccessResponse(latitude, longitude);
            } else {
                L.i("location is null");
            }
        }

@SuppressLint("MissingPermission")
        @Override
        public void onStatusChanged(String provider, int status, Bundle extras) {
            L.i("onStatusChanged:" + status);
            if (status == LocationProvider.OUT_OF_SERVICE || status == LocationProvider.TEMPORARILY_UNAVAILABLE) {
                L.i("GPS定位失败");
                //如果之前没有开启过网络定位,自动切换到网络定位
                if (networkListener == null){
                    //开启网络定位
                    networkListener = new NetworkListener();
                    locationManager.requestLocationUpdates(LocationManager.NETWORK_PROVIDER, 0, 0, networkListener);
                }
            }
        }

@Override
        public void onProviderEnabled(String provider) {
            L.i("onProviderEnabled");
        }

@Override
        public void onProviderDisabled(String provider) {
            L.i("onProviderDisabled");
        }
    }

private class NetworkListener implements LocationListener {

@Override
        public void onLocationChanged(android.location.Location location) {
            if (location != null){
                L.i("网络定位成功");

boolean isBetter = isBetterLocation(location,currentBestLocation);
                if (isBetter){
                    currentBestLocation = location;
                }
                double latitude = currentBestLocation.getLatitude();    //纬度
                double longitude = currentBestLocation.getLongitude();  //经度
                responseListener.onSuccessResponse(latitude, longitude);

}
        }

@Override
        public void onStatusChanged(String provider, int status, Bundle extras) {
            if (status == LocationProvider.OUT_OF_SERVICE || status == LocationProvider.TEMPORARILY_UNAVAILABLE ) {
                L.i("网络定位失败");
                responseListener.onErrorResponse(LocationManager.NETWORK_PROVIDER, UNAVAILABLE);
            }
        }

@Override
        public void onProviderEnabled(String provider) {
            L.e("可用");
        }

@Override
        public void onProviderDisabled(String provider) {
            L.e("不可用");
        }
    }

private static final int TWO_MINUTES = 1000 * 60 * 2;

/**
     * 比较最新获取到的位置是否比当前最好的位置更好
     *
     * @param location  最新获得的位置
     * @param currentBestLocation   当前获取到的最好的位置
     * @return  最新获取的位置比当前最好的位置更好则返回true
     */
    private boolean isBetterLocation(Location location, Location currentBestLocation) {
        if (currentBestLocation == null) {
            // A new locationUtil is always better than no locationUtil
            return true;
        }

//实时性
        // Check whether the new locationUtil fix is newer or older
        long timeDelta = location.getTime() - currentBestLocation.getTime();
        boolean isSignificantlyNewer = timeDelta > TWO_MINUTES; //最新位置比当前位置晚两分钟定位
        boolean isSignificantlyOlder = timeDelta < -TWO_MINUTES;//最新位置比当前位置早两分钟定位
        boolean isNewer = timeDelta > 0;

// If it's been more than two minutes since the current locationUtil, use the new locationUtil
        // because the user has likely moved
        if (isSignificantlyNewer) {
            return true;
            // If the new locationUtil is more than two minutes older, it must be worse
        } else if (isSignificantlyOlder) {
            return false;
        }

//精确性
        // Check whether the new locationUtil fix is more or less accurate
        //locationUtil.getAccuracy()值越小越精确
        int accuracyDelta = (int) (location.getAccuracy() - currentBestLocation.getAccuracy());
        boolean isLessAccurate = accuracyDelta > 0; //最新的位置不如当前的精确
        boolean isMoreAccurate = accuracyDelta < 0; //最新的位置比当前的精确
        //最新的位置不如当前的精确,但是相差在一定范围之内
        boolean isSignificantlyLessAccurate = accuracyDelta > 200;

// Check if the old and new locationUtil are from the same provider
        boolean isFromSameProvider = isSameProvider(location.getProvider(),
                currentBestLocation.getProvider());

// Determine locationUtil quality using a combination of timeliness and accuracy
        if (isMoreAccurate) {
            return true;
        } else if (isNewer && !isLessAccurate) {
            return true;
        } else if (isNewer && !isSignificantlyLessAccurate && isFromSameProvider) {
            return true;
        }
        return false;
    }

/** Checks whether two providers are the same */
    private boolean isSameProvider(String provider1, String provider2) {
        if (provider1 == null) {
            return provider2 == null;
        }
        return provider1.equals(provider2);
    }

public interface OnResponseListener {

/**
         * 定位成功
         * @param latitude  纬度
         * @param longitude 经度
         */
        void onSuccessResponse(double latitude, double longitude);

/**
         * 定位失败
         * @param provider  provider
         * @param status    失败码
         */
        void onErrorResponse(String provider, int status);
    }

/**
     * 获取地址
     * @param context   Context
     * @param latitude  纬度
     * @param longitude 经度
     * @return  Address
     */
    public static @Nullable Address getAddress(Context context, double latitude, double longitude){
        Geocoder geocoder = new Geocoder(context);
        try {
            List<Address> list = geocoder.getFromLocation(latitude,longitude,3);
            if (list.size() > 0){
                Address address = list.get(0);
                L.i("省:" + address.getAdminArea());
                L.i("市:" + address.getLocality());
                L.i("县/区:" + address.getSubLocality());
                return address;
            }
        } catch (IOException e) {
            e.printStackTrace();
        }
        return null;
    }

}

9.10 安卓常用工具类之一 定位-----LocationUtils相关推荐

  1. 9.10 安卓常用工具类之一 对话 ---- DialogUtil

    对话 ---- DialogUtil package com.behe.treasure.util; import android.annotation.SuppressLint; import an ...

  2. 9.10 安卓常用工具类之一 权限 ---- PermissionUtil

    权限 ----  PermissionUtil package com.behe.treasure.util; import android.app.Activity; import android. ...

  3. 【转】 Android快速开发系列 10个常用工具类 -- 不错

    原文网址:http://blog.csdn.net/lmj623565791/article/details/38965311 转载请标明出处:http://blog.csdn.net/lmj6235 ...

  4. Android快速开发系列 10个常用工具类

    目录(?)[+] 转载请标明出处:http://blog.csdn.net/lmj623565791/article/details/38965311,本文出自[张鸿洋的博客] 打开大家手上的项目,基 ...

  5. 关于安卓常用工具类集成

    码云地址: https://github.com/motosheep/androidutils.git 20200514 1增加xrecyclerview--XRecyclerView 2增加震动工具 ...

  6. javascript 总结(常用工具类的封装)(转)

    转载地址:http://dzblog.cn/article/5a6f48afad4db304be1e7a5f javascript 总结(常用工具类的封装) JavaScript 1. type 类型 ...

  7. javascript 总结(常用工具类的封装,转)

    javascript 总结(常用工具类的封装) 前言 因为工作中经常用到这些方法,所有便把这些方法进行了总结. JavaScript 1. type 类型判断 isString (o) { //是否字 ...

  8. javascript常用工具类整理(copy)

    JavaScript常用工具类 类型 日期 数组 字符串 数字 网络请求 节点 存储 其他 1.类型 isString (o) { //是否字符串return Object.prototype.toS ...

  9. Java 常用工具类 Collections 源码分析

    文章出处 文章出自:安卓进阶学习指南 作者:shixinzhang 完稿日期:2017.10.25 Collections 和 Arrays 是 JDK 为我们提供的常用工具类,方便我们操作集合和数组 ...

最新文章

  1. java自学 day1
  2. linux FreeImage安装编译
  3. spring boot / cloud (二) 规范响应格式以及统一异常处理
  4. 跟Kafka学技术系列之时间轮
  5. Intent 匹配规则
  6. 一个简易的渲染循环结构
  7. 25款操作系统全面接触 [2]
  8. 11.11 Ext JS Tooltip 出错 Uncaught TypeError: Cannot read property ‘contains‘ of null
  9. go解析多个html,解析html-Go语言中文社区
  10. 【python|多进程】打印进度条
  11. 从 0 开始了解 Docker(ubuntu )
  12. java发送微信订阅消息
  13. 电信 dns服务器 不稳定,知名DNS服务商114DNS故障,你访问受影响了吗?
  14. 正弦电压有效值推导过程(为什么与频率无关)
  15. 坚果云android功能,坚果云是什么有什么功能_坚果云相关功能作用介绍_3DM手游
  16. C#将指定时区中的时间转换为协调世界时 (UTC)。
  17. python数据分析 - T检验与F检验:二组数据那个更好?(一)
  18. 三维建模分享之蒸汽坦克
  19. 计算机键盘上的基准键是哪两个键,键盘上的基准键分别是什么?
  20. 学习VGG(网络讲解+代码)

热门文章

  1. 分布式事务概述 (资料)
  2. 找出只包含1的最大矩形c语言,一些简单的编程练习题
  3. java 多个pdf文件合并,解决删除提示文件被占用
  4. 使用msf创建木马使用脚本
  5. #WebStorm激活码失效解决方法!
  6. 前端学习之认识HTML
  7. Revit MEP 平面视图中(立管)怎么设置二维表达?
  8. spring中使用Aspectj进行切面编程
  9. 报错#vue-router#unknown custom element: <router-link> - did you register the component correctly?
  10. C#——获取银行卡所属银行,验证银行卡号是否正确