我如何从 android studio 中的坐标获取地址

How can i get address from coordinates in android studio

我对反向地理编码有疑问。当我想将我的坐标转换为地址时,Geocoder returns 这个错误:

Caused by: java.io.IOException: grpc failed

这是我的代码:

 val btnbymap = mycustomview.findViewById<Button>(R.id.edit_by_map)


            btnbymap.setOnClickListener {

                if (ContextCompat.checkSelfPermission(
                        vl.context,
                        android.Manifest.permission.ACCESS_FINE_LOCATION
                    ) == PackageManager.PERMISSION_GRANTED && ActivityCompat.checkSelfPermission(
                        vl.context,
                        android.Manifest.permission.ACCESS_COARSE_LOCATION
                    ) == PackageManager.PERMISSION_GRANTED
                ) {


                    fusedLocationProviderClient.lastLocation.addOnSuccessListener(requireActivity()) {


                        location = it

                        val gcd = Geocoder(context, Locale.getDefault())

                        val addresses: List<Address> =
                            gcd.getFromLocationName("name", 1)
                        addresses[0].getAddressLine(0)
                        Toast.makeText(context, "${addresses}", Toast.LENGTH_LONG).show()


                    }

                } else {
                    requestPermissions(
                        arrayOf(
                            android.Manifest.permission.ACCESS_FINE_LOCATION,
                            android.Manifest.permission.ACCESS_COARSE_LOCATION
                        ), RequestCode
                    )
                }

            }
        }

我该如何解决这个问题?是否有任何替代地理编码反向?

如果你想像你说的那样从坐标中获取地址,你应该使用:

val addresses: List<Address> = geoCoder.getFromLocation(latitude, longitude, 1)

val result = addresses[0].locality

geoCoder.getFromLocationName() 当你想从字符串地址中知道纬度和经度时使用。

此外,要检索您所在位置的纬度和经度,您可以使用以下方法:

fusedLocationClient.lastLocation.addOnSuccessListener {location: Location? ->
if(location != null) {
val myLatitude = location.latitude
val myLongitude = location.longitude
}
}

因为您要求替代方案,所以我会 post 此处提供解决方法。 Google 地图是必经之路,它将根据我的经验为您提供准确地址。这使用改造来进行 Api 调用

            class GetLocationDetail(addressCallBack: LocationData.AddressCallBack, context: Context) {
                private val addressCallBack: LocationData.AddressCallBack
                private val context: Context
                fun getAddress(latitude: Double, longitude: Double, key: String) {
                    try {
                        val geocoder = Geocoder(context, Locale.getDefault())
                        val addresses: List<Address> = geocoder.getFromLocation(latitude, longitude, 1)
                        if (addresses != null && addresses.size > 0) {
                            val address: String =
                                addresses[0].getAddressLine(0) // If any additional address line present than only, check with max available address lines by getMaxAddressLineIndex()
                            val city: String = addresses[0].getLocality()
                            val state: String = addresses[0].getAdminArea()
                            val country: String = addresses[0].getCountryName()
                            val postalCode: String = addresses[0].getPostalCode()
                            val knownName: String =
                                addresses[0].getFeatureName() // Only if available else return NULL
                            val locationData = LocationData()
                            locationData.setCity(city)
                            locationData.setFull_address(address)
                            locationData.setPincode(postalCode)
                            locationData.setCountry(country)
                            addressCallBack.locationData(locationData)
                        }
                    } catch (e: IOException) {
                        e.printStackTrace()
                        getAddressFromApi(latitude, longitude, key)
                    }
                }
            
                private fun getAddressFromApi(latitude: Double, longitude: Double, key: String) {
                    val tempBuilder = StringBuilder()
                    tempBuilder.append(latitude)
                    tempBuilder.append(",")
                    tempBuilder.append(longitude)
                    val dataService: DataService = retrofitInstance.create(
                        DataService::class.java
                    )
                    val stringCall: Call<String> = dataService.getData(tempBuilder.toString(), true, key)
                    if (stringCall.isExecuted()) {
                        stringCall.cancel()
                    }
                    stringCall.enqueue(object : Callback<String?>() {
                        fun onResponse(call: Call<String?>?, response: Response<String?>) {
                            try {
                                val jsonObject = JSONObject(response.body())
                                val Results: JSONArray = jsonObject.getJSONArray("results")
                                val zero: JSONObject = Results.getJSONObject(0)
                                val address_components: JSONArray = zero.getJSONArray("address_components")
                                val locationData = LocationData()
                                locationData.setFull_address(zero.getString("formatted_address"))
                                for (i in 0 until address_components.length()) {
                                    val zero2: JSONObject = address_components.getJSONObject(i)
                                    val long_name: String = zero2.getString("long_name")
                                    val mtypes: JSONArray = zero2.getJSONArray("types")
                                    val Type: String = mtypes.getString(0)
                                    if (TextUtils.isEmpty(long_name) === false || long_name != null || long_name.length > 0 || long_name !== "") {
                                        if (Type.equals("street_number", ignoreCase = true)) {
                                            //Address1 = long_name + " ";
                                        } else if (Type.equals("route", ignoreCase = true)) {
                                            //Address1 = Address1 + long_name;
                                        } else if (Type.equals("sublocality", ignoreCase = true)) {
                                            // Address2 = long_name;
                                        } else if (Type.equals("locality", ignoreCase = true)) {
                                            // Address2 = Address2 + long_name + ", ";
                                            locationData.setCity(long_name)
                                        } else if (Type.equals(
                                                "administrative_area_level_2",
                                                ignoreCase = true
                                            )
                                        ) {
                                            // County = long_name;
                                        } else if (Type.equals(
                                                "administrative_area_level_1",
                                                ignoreCase = true
                                            )
                                        ) {
                                            // State = long_name;
                                        } else if (Type.equals("country", ignoreCase = true)) {
                                            locationData.setCountry(long_name)
                                        } else if (Type.equals("postal_code", ignoreCase = true)) {
                                            locationData.setPincode(long_name)
                                        }
                                    }
                                }
                                addressCallBack.locationData(locationData)
                            } catch (e: JSONException) {
                                e.printStackTrace()
                            }
                        }
            
                        fun onFailure(call: Call<String?>?, t: Throwable) {
                            Log.v("response", t.toString())
                        }
                    })
                }
            
                private interface DataService {
                    @GET("api/geocode/json")
                    fun getData(
                        @Query("latlng") latLong: String?,
                        @Query("sensor") sensor: Boolean,
                        @Query("key") key: String?
                    ): Call<String?>?
                }
            
                companion object {
                    private const val BASE_URL = "https://maps.googleapis.com/maps/"
                    private var retrofit: Retrofit? = null
                    private val retrofitInstance: Retrofit?
                        private get() {
                            if (retrofit == null) {
                                retrofit = Builder()
                                    .baseUrl(BASE_URL)
                                    .addConverterFactory(ScalarsConverterFactory.create())
                                    .build()
                            }
                            return retrofit
                        }
                }
            
                init {
                    this.addressCallBack = addressCallBack
                    this.context = context
                }
            }
            
            
            

所需的class位置数据

            class LocationData {
                var city: String? = null
                var country: String? = null
                var pincode: String? = null
                var full_address: String? = null
            
                interface AddressCallBack {
                    fun locationData(locationData: LocationData?)
                }
            }