1. 使用Android 自带的SDK 定位,获取所在的经纬度
2. 通过所在经纬度得到对应的城市信息
2.1 通过服务获取城市名(google或者baidu)
百度:http://api.map.baidu.com/geocoder?output=json&location=23.131427,113.379763&ak=esNPFDwwsXWtsQfw4NMNmur1
google:http://maps.google.com/maps/api/geocode/json?latlng=%2023.131427,113.379763&language=zh-CN&sensor=true
2.2 使用Android的API 获取城市
1 /** 2 *使用Android 的API 获取城市 3 * Address[addressLines=[0:"福建省厦门市思明区台南路"],feature=null,admin=福建省,sub-admin=莲前街道,locality=厦门市,thoroughfare=台南路,postalCode=null, 4 * countryCode=CN,countryName=中国,hasLatitude=true,latitude=24.490153327372084,hasLongitude=true,longitude=118.20273875866398,phone=null,url=null,extras=null] 5 */ 6 private fun getAddress(context: Context, location: Location?): List<Address>? { 7 var result: List<Address>? = null 8 try { 9 if (location != null) { 10 val gc = Geocoder(context, Locale.getDefault()) 11 result = gc.getFromLocation(location.latitude, location.longitude, 1) 12 } 13 } catch (e: Exception) { 14 e.printStackTrace() 15 } 16 return result 17 }
参考资料:https://blog.csdn.net/qq_24636637/article/details/50461284 根据经纬度获取城市名
百度地图官方文档:http://api.map.baidu.com/lbsapi/cloud/geocoding-api.htm (旧版,已过时)
对应新的文档:http://lbsyun.baidu.com/index.php?title=webapi/guide/webservice-geocoding-abroad
(配额已用:0%(上限:0.6万次/天,并发峰值:1QPS (上限:50QPS)
1 package com.mostone.locationmanager 2 3 import android.Manifest 4 import android.annotation.SuppressLint 5 import android.content.Context 6 import android.content.pm.PackageManager 7 import android.location.* 8 import android.location.LocationManager 9 import android.os.Build 10 import android.os.Bundle 11 import android.util.Log 12 import androidx.core.app.ActivityCompat 13 import java.util.* 14 15 16 /** 17 * LocationManagerHelper2.kt 18 * <p> 19 * 类的描述: 定位辅助类 20 * 创建时间: 2020/6/24 14:48 21 * 修改备注: 6.0以上需要动态申请权限 22 * <uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" /> 23 * <uses-permission android:name="android.permission..ACCESS_FINE_LOCATION" /> 24 */ 25 26 class LocationManagerHelper2 private constructor() { 27 companion object { 28 val instance by lazy { LocationManagerHelper2() } 29 } 30 31 private var lManager: LocationManager? = null 32 private var locationProvider: String? = null 33 34 @SuppressLint("ServiceCast") 35 fun build(context: Context, listener: (MutableList<Address>?) -> Unit) { 36 //获取LocationManager 37 lManager = (context.getSystemService(Context.LOCATION_SERVICE) 38 as LocationManager?)?.also { manager -> 39 val providers = manager.getProviders(true) 40 when { 41 providers.contains(LocationManager.NETWORK_PROVIDER) -> { // 网络定位 42 Log.d("TAG", "如果是网络定位") 43 locationProvider = LocationManager.NETWORK_PROVIDER 44 } 45 providers.contains(LocationManager.GPS_PROVIDER) -> { // GPS 定位 46 Log.d("TAG", "如果是GPS定位") 47 locationProvider = LocationManager.GPS_PROVIDER 48 } 49 else -> { 50 Log.d("TAG", "没有可用的位置提供器") 51 } 52 } 53 locationProvider?.let { 54 if (checkSelfPermission(context)) return 55 56 //3.获取上次的位置,一般第一次运行,此值为null 57 if (manager.getLastKnownLocation(locationProvider) == null) { 58 // 监视地理位置变化,第二个和第三个参数分别为更新的最短时间minTime和最短距离minDistace 59 manager.requestLocationUpdates( 60 locationProvider, 0L, 0F, 61 getListener(context, listener) 62 ) 63 } else { 64 getAddress(context, manager.getLastKnownLocation(locationProvider), listener) 65 } 66 } 67 } 68 } 69 70 private fun getListener( 71 context: Context, listener: (MutableList<Address>?) -> Unit 72 ): LocationListener { 73 return object : LocationListener { 74 override fun onLocationChanged(location: Location?) { 75 location?.accuracy //精确度 76 getAddress(context, location, listener) 77 lManager?.removeUpdates(this) 78 lManager = null 79 } 80 81 override fun onStatusChanged(p0: String?, p1: Int, p2: Bundle?) { 82 } 83 84 override fun onProviderEnabled(p0: String?) { 85 } 86 87 override fun onProviderDisabled(p0: String?) { 88 lManager?.removeUpdates(this) 89 lManager = null 90 } 91 } 92 } 93 94 private fun checkSelfPermission(context: Context): Boolean { 95 // 需要检查权限,否则编译报错,想抽取成方法都不行,还是会报错。只能这样重复 code 了。 96 return Build.VERSION.SDK_INT >= 23 && 97 ActivityCompat.checkSelfPermission( 98 context, Manifest.permission.ACCESS_FINE_LOCATION 99 ) != PackageManager.PERMISSION_GRANTED && 100 ActivityCompat.checkSelfPermission( 101 context, Manifest.permission.ACCESS_COARSE_LOCATION 102 ) != PackageManager.PERMISSION_GRANTED 103 } 104 105 /** 106 * 使用Android 的API 获取城市 107 * Address[addressLines=[0:"福建省厦门市思明区台南路"],feature=null,admin=福建省,sub-admin=莲前街道,locality=厦门市,thoroughfare=台南路,postalCode=null, 108 * countryCode=CN,countryName=中国,hasLatitude=true,latitude=24.490153327372084,hasLongitude=true,longitude=118.20273875866398,phone=null,url=null,extras=null] 109 */ 110 private fun getAddress( 111 context: Context, location: Location?, 112 listener: (MutableList<Address>?) -> Unit = {} 113 ) { 114 var result: MutableList<Address>? = null 115 try { 116 if (location != null) { 117 val gc = Geocoder(context, Locale.getDefault()) 118 result = gc.getFromLocation(location.latitude, location.longitude, 1) 119 } 120 } catch (e: Exception) { 121 e.printStackTrace() 122 } 123 listener.invoke(result) 124 } 125 }