欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  IT编程

Android通过原生方式获取经纬度与城市信息的方法

程序员文章站 2022-06-23 18:25:00
一、概述在项目中需要获取用户所在位置的经纬度和城市上送给风控系统。一般来说,定位有两种方式: 用第三方sdk定位,如百度地图、高德地图、谷歌地图; 用android原生sdk中的api定位;本文讲...

一、概述

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

  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<string> 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<string> 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<address> getaddress(location location) {
  list<address> 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加权限

<!-- 粗略的位置权限 -->
<uses-permission android:name="android.permission.access_coarse_location"></uses-permission> 
<!-- 精确的位置权限 -->
<uses-permission android:name="android.permission.access_fine_location"></uses-permission>
<uses-permission android:name="android.permission.internet"></uses-permission>

三、总结

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

Android通过原生方式获取经纬度与城市信息的方法

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

Android通过原生方式获取经纬度与城市信息的方法

总结

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