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 }