我如何从安卓工作室的坐标中获取地址



我有反向地理编码的问题。当我想将坐标转换为地址时,Geocoder会返回以下错误:

原因:java.io.io异常: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
)
}
}
}

我该怎么解决这个问题?地理编码反向有其他选择吗?

因为您要求替代方案,我将在这里发布一个解决方案。谷歌地图是最好的选择,根据我的经验,它会给你精确的地址。这使用改装使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
}
}



所需的类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?)
}
}

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

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

最新更新