Android核心知识点笔记github:https://github.com/AndroidCot/Android

一、概述

在项目中需要获取用户所在位置的经纬度和城市上送给风控系统。一般来说,定位有两种方式:

  1. 用第三方SDK定位,如百度地图、高德地图、谷歌地图;
  2. 用Android原生SDK中的api定位;

本文讲述定位的第二种方式–用Android原生的SDK中的api定位,如果项目定位要求较高还是建议使用第三方地图库。

二、Android原生SDK中的api定位

Android原生方式获取经纬度两种定位方式:GPS定位和Wifi定位

  • GPS定位相比Wifi定位更精准且可在无网络情况下使用,但在室内基本暴毙无法使用。
  • WiFi定位没有室内外限制,也不需要开启GPS但需要联网。但测试发现WiFi定位时onLocationChanged函数(用于监听经纬度变化)触发间隔无法小于30s。

示例代码如下:

public class TestLocationActivity extends AppCompatActivity {    public static final int LOCATION_CODE = 301;    private LocationManager locationManager;    private String locationProvider = null;    @Override    protected void onCreate(@Nullable Bundle savedInstanceState) {        super.onCreate(savedInstanceState);        getLocation();    }    private void getLocation(){        //1.获取位置管理器        locationManager = (LocationManager) getSystemService(Context.LOCATION_SERVICE);        //2.获取位置提供器,GPS或是NetWork        List providers = locationManager.getProviders(true);        if (providers.contains(LocationManager.GPS_PROVIDER)) {            //如果是GPS            locationProvider = LocationManager.GPS_PROVIDER;            Log.v("TAG", "定位方式GPS");        } else if (providers.contains(LocationManager.NETWORK_PROVIDER)) {            //如果是Network            locationProvider = LocationManager.NETWORK_PROVIDER;            Log.v("TAG", "定位方式Network");        }else {            Toast.makeText(this, "没有可用的位置提供器", Toast.LENGTH_SHORT).show();            return;        }        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {            //获取权限(如果没有开启权限,会弹出对话框,询问是否开启权限)            if (ContextCompat.checkSelfPermission(this, Manifest.permission.ACCESS_FINE_LOCATION)                     != PackageManager.PERMISSION_GRANTED ||                 ActivityCompat.checkSelfPermission(this, Manifest.permission.ACCESS_COARSE_LOCATION)                     != PackageManager.PERMISSION_GRANTED) {                //请求权限                ActivityCompat.requestPermissions(this, new String[]{Manifest.permission.ACCESS_FINE_LOCATION,                        Manifest.permission.ACCESS_COARSE_LOCATION}, LOCATION_CODE);            } else {                //3.获取上次的位置,一般第一次运行,此值为null                Location location = locationManager.getLastKnownLocation(locationProvider);                if (location!=null){                    Toast.makeText(this, location.getLongitude() + " " +                                          location.getLatitude() + "",Toast.LENGTH_SHORT).show();                    Log.v("TAG", "获取上次的位置-经纬度:"+location.getLongitude()+"   "+location.getLatitude());                    getAddress(location);                }else{                    //监视地理位置变化,第二个和第三个参数分别为更新的最短时间minTime和最短距离minDistace                    locationManager.requestLocationUpdates(locationProvider, 3000, 1,locationListener);                }            }        } else {            Location location = locationManager.getLastKnownLocation(locationProvider);            if (location!=null){                Toast.makeText(this, location.getLongitude() + " " +                                      location.getLatitude() + "", Toast.LENGTH_SHORT).show();                Log.v("TAG", "获取上次的位置-经纬度:"+location.getLongitude()+"   "+location.getLatitude());                getAddress(location);            }else{                //监视地理位置变化,第二个和第三个参数分别为更新的最短时间minTime和最短距离minDistace                locationManager.requestLocationUpdates(locationProvider, 3000, 1,locationListener);            }        }    }    public LocationListener locationListener = new LocationListener() {        // Provider的状态在可用、暂时不可用和无服务三个状态直接切换时触发此函数        @Override        public void onStatusChanged(String provider, int status, Bundle extras) {        }        // Provider被enable时触发此函数,比如GPS被打开        @Override        public void onProviderEnabled(String provider) {        }        // Provider被disable时触发此函数,比如GPS被关闭        @Override        public void onProviderDisabled(String provider) {        }        //当坐标改变时触发此函数,如果Provider传进相同的坐标,它就不会被触发        @Override        public void onLocationChanged(Location location) {            if (location != null) {                //如果位置发生变化,重新显示地理位置经纬度                Toast.makeText(TestLocationActivity.this, location.getLongitude() + " " +                                                           location.getLatitude() + "", Toast.LENGTH_SHORT).show();                Log.v("TAG", "监视地理位置变化-经纬度:"+location.getLongitude()+"   "+location.getLatitude());            }        }    };    @Override    public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {        switch (requestCode) {            case LOCATION_CODE:                if(grantResults.length > 0 && grantResults[0] == getPackageManager().PERMISSION_GRANTED                        && grantResults[1] == PackageManager.PERMISSION_GRANTED) {                    Toast.makeText(this, "申请权限", Toast.LENGTH_LONG).show();                    try {                        List providers = locationManager.getProviders(true);                        if (providers.contains(LocationManager.NETWORK_PROVIDER)) {                            //如果是Network                            locationProvider = LocationManager.NETWORK_PROVIDER;                        }else if (providers.contains(LocationManager.GPS_PROVIDER)) {                            //如果是GPS                            locationProvider = LocationManager.GPS_PROVIDER;                        }                        Location location = locationManager.getLastKnownLocation(locationProvider);                        if (location!=null){                            Toast.makeText(this, location.getLongitude() + " " +                                                  location.getLatitude() + "", Toast.LENGTH_SHORT).show();                            Log.v("TAG", "获取上次的位置-经纬度:"+location.getLongitude()+"   "+location.getLatitude());                        }else{                            // 监视地理位置变化,第二个和第三个参数分别为更新的最短时间minTime和最短距离minDistace                            locationManager.requestLocationUpdates(locationProvider, 0, 0,locationListener);                        }                    }catch (SecurityException e){                        e.printStackTrace();                    }                } else {                    Toast.makeText(this, "缺少权限", Toast.LENGTH_LONG).show();                    finish();                }                break;        }    }    //获取地址信息:城市、街道等信息    private List getAddress(Location location) {        List result = null;        try {            if (location != null) {                Geocoder gc = new Geocoder(this, Locale.getDefault());                result = gc.getFromLocation(location.getLatitude(),                        location.getLongitude(), 1);                Toast.makeText(this, "获取地址信息:"+result.toString(), Toast.LENGTH_LONG).show();                Log.v("TAG", "获取地址信息:"+result.toString());            }        } catch (Exception e) {            e.printStackTrace();        }        return result;    }    @Override    protected void onDestroy() {        super.onDestroy();        locationManager.removeUpdates(locationListener);    }}

在AndroidManifest.xml加权限

 复制代码

三、总结

首先将手机定位服务设置,调到下图所示:

这可能会获取不到经纬度。为什么在网络和GPS都可用的情况下只执行GPS而不是网络?也许是从精确度考虑的,但是走GPS进入监听的listener后,不会执行onLocationChanged()方法,因为我是在室内,没有移动,所以如果你获取不到经纬度,就要将定位服务调到仅使用网络定位或者关闭手机GPS这样就可以获取到了。

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-3qLJ8Ng8-1595992608560)(https://upload-images.jianshu.io/upload_images/24146606-bddf410ed8b2de20.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240)]

更多相关文章

  1. android系统信息(内存、cpu、sd卡、电量、版本)获取
  2. android获取设备唯一标识完美解决方案
  3. Android上传图片到七牛云看这篇就够了
  4. Android通讯录数据库介绍与基本操作(增删改查)
  5. Android——获取手机当前信号强度(dbm/asu值)
  6. 抛开android获取app的签名 —— 一次源码探索之旅
  7. android 获取versionName和versionCode以及作用
  8. android 流量统计实现思路
  9. Android(安卓)--小功能 Android中几种图像特效处理 (一)

随机推荐

  1. 开局崩盘!IDEA 2020 无法启动的解决办法|
  2. RocketMQ 源码分析 —— 集成 Spring Boo
  3. 如何自制一个Spring Boot Starter并推送
  4. Spring Boot项目利用MyBatis Generator进
  5. 自制一个 elasticsearch-spring-boot-sta
  6. RocketMQ 源码分析 —— Message 拉取与
  7. 疫情防控不能松懈,利用数据挖掘做好重点区
  8. python六大数据类型
  9. 黑科技神器-uTools
  10. Drawable、Bitmap、Canvas和Paint的区别