Геокодер — getFromLocation() устарел
Я получил сообщение о том, что эта функция (или ее конструктор) устарела. Есть новый конструктор этой функции, который принимает дополнительный параметр'Geocoder.GeocodeListener listener'
но для этого нового конструктора требуется уровень API 33 и выше. Что мне делать для более низких уровней API, какое решение?
4 ответа
Я думаю, что самый чистый способ справиться с этим устареванием - это переместить getFromLocation в новую функцию расширения и добавить @Suppress("DEPRECATION") следующим образом:
@Suppress("DEPRECATION")
fun Geocoder.getAddress(
latitude: Double,
longitude: Double,
address: (android.location.Address?) -> Unit
) {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.TIRAMISU) {
getFromLocation(latitude, longitude, 1) { address(it.firstOrNull()) }
return
}
try {
address(getFromLocation(latitude, longitude, 1)?.firstOrNull())
} catch(e: Exception) {
//will catch if there is an internet problem
address(null)
}
}
И вот как использовать:
Geocoder(requireContext(), Locale("in"))
.getAddress(latlng.latitude, latlng.longitude) { address: android.location.Address? ->
if (address != null) {
//do your logic
}
}
Поскольку это устарело на уровне API 33, я считаю, что это единственный вариант для более низких уровней API.
Я адаптировал код @Eko Yulianto, чтобы избежать необходимости раскрывать обратный вызов.
private suspend fun Geocoder.getAddress(
latitude: Double,
longitude: Double,
): Address? = withContext(Dispatchers.IO) {
try {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.TIRAMISU) {
suspendCoroutine { cont ->
getFromLocation(latitude, longitude, 1) {
cont.resume(it.firstOrNull())
}
}
} else {
suspendCoroutine { cont ->
@Suppress("DEPRECATION")
val address = getFromLocation(latitude, longitude, 1)?.firstOrNull()
cont.resume(address)
}
}
} catch (e: Exception) {
Timber.e(e)
null
}
}
Недавно у меня возникла проблема, из-за которой я продолжал получать исключение Java.IO.IOException: сбой grpc.
Я переместил этот код геокодера в класс Runnable и выполнил этот код как отдельный поток, например:
GeocoderThread geocoderThread = new GeocoderThread(latitude, longitude, this);
Thread gcThread = new Thread(geocoderThread);
gcThread.start();
try{
gcThread.join();
}
catch(InterruptedException e1) {
e1.printStackTrace();
}
city = geocoderThread.getCity();
И это мой класс Runnable:
public class GeocoderThread implements Runnable{
Geocoder geo;
double latitude;
double longitude;
String city;
public GeocoderThread(double lat, double lon, Context ctx) {
latitude = lat;
longitude = lon;
geo = new Geocoder(ctx, Locale.getDefault());
}
@Override
public void run() {
try
{
//deprecated, need to put this in a runnable thread
List<Address> address = geo.getFromLocation(latitude, longitude, 2);
if(address.size() > 0)
{
city = address.get(0).getLocality();
}
}
catch (IOException e) {
System.out.println(e.getMessage());
e.printStackTrace();
}
catch (NullPointerException e) {
System.out.println(e.getMessage());
e.printStackTrace();
}
}
public String getCity() {
return city;
}
}