我如何从Android Studio中的坐标获取地址

问题描述

我对反向地理编码有疑问。当我要将坐标转换为地址时,Geocoder返回此错误

原因:java.io.IOException:grpc失败

这是我的代码

 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
}
}
,

因为您要求替代方法,所以我将在此处发布解决方法。 Google Maps是您的最佳选择,它会根据我的经验为您提供准确的地址。这使用改造来进行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,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,key)
                    }
                }
            
                private fun getAddressFromApi(latitude: 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
                }
            }
            
            
            

必需的类LocationData

            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?)
                }
            }

如果有帮助,请标记为答案:)