一、概述

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

  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这样就可以获取到了。

总结

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

更多相关文章

  1. 初学Android,使用自定义的XML资源(十八)
  2. Android中基于心知天气API获取天气信息
  3. [Android算法] Android蓝牙开发浅谈
  4. [Android算法] Android蓝牙开发浅谈
  5. [Android算法] Android蓝牙开发浅谈
  6. Android跳转到通讯录获取用户名称和手机号码的实现思路
  7. 「Android」将网页转换为PDF的初步实现
  8. Android之自定义View实现随手势滑动的小圆球
  9. 为了获取下一个10亿用户,Google的布局其实不仅仅是Android(安卓)G

随机推荐

  1. android 使用Activity类布局时怎样让图片
  2. Android系统开发—对View的clipChildren,
  3. 替换Android自带apk
  4. 新手学Android
  5. Android(安卓)SDK Manager 更新方法
  6. android电源管理简要
  7. Android(安卓)Studio 1.0 官网下载链接
  8. Android(安卓)4.0 横竖屏切换注意事项
  9. 在Android中自动实现横竖屏切换的问题
  10. Android日期空间(DatePickerDialog)中的年