一、概述

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

  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加权限

 

三、总结

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

Android通过原生方式获取经纬度与城市信息的方法_第1张图片

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

总结

到此这篇关于Android通过原生方式获取经纬度与城市信息的文章就介绍到这了,更多相关Android原生获取经纬度与城市信息内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!

更多相关文章

  1. 探索新的Android权限模式
  2. Linux文件的特殊权限位SUID、SGID作用及编程设置/读取
  3. Android 事件全局监听(二)需要root权限 ,使用getevent监听Android输
  4. Android运行时权限,6.0—9.0多版本,多终端(手机,TV盒子)130行代码一劳
  5. Android之权限管理
  6. Android 为【apk】文件签名,增加修改系统时间等权限
  7. Android兼容android7.0、及Android8.0以上apk安装权限问题(二)
  8. Android--取得控件在手机屏幕上的位置
  9. Android LBS系列04 位置和地图服务简介

随机推荐

  1. golang可以做些什么?
  2. Golang 是面向对象还是面向过程?
  3. golang吉祥物是啥?
  4. Golang 和 PHP 哪个性能更强?
  5. golang会代替java吗?
  6. Golang 底层也用 Golang 吗?
  7. golang和哪种语言像?
  8. golang和nodejs的区别是什么?
  9. golang如何连接mysql
  10. golang如何读取文件