地理编码器 - getFromLocation() 已弃用

问题描述 投票:0回答:6
我收到一条消息,表明此函数(或其构造函数)已被弃用。该函数有一个新的构造函数,它接受附加参数

'Geocoder.GeocodeListener listener'

 但该新构造函数需要 API 级别 33 及以上。对于较低的 API 级别我该怎么办,解决方案是什么?

android kotlin geocoding deprecation-warning android-tiramisu
6个回答
9
投票

官方文档 - 使用 getFromLocation(double, double, int, android.location.Geocoder.GeocodeListener) 来避免阻塞等待结果的线程。

示例:

//Variables val local = Locale("en_us", "United States") val geocoder = Geocoder(this, local) val latitude = 18.185600 val longitude = 76.041702 val maxResult = 1 //Fetch address from location geocoder.getFromLocation(latitude,longitude,maxResult,object : Geocoder.GeocodeListener{ override fun onGeocode(addresses: MutableList<Address>) { // code } override fun onError(errorMessage: String?) { super.onError(errorMessage) } })
    

6
投票
我认为处理这种弃用的最干净的方法是将 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 } }
    

5
投票
由于这在 API 级别 33 中已被弃用,我相信这是较低 API 级别的唯一选择。


0
投票
方法

getFromLocationName

 仍然存在,但现在需要“边界框”参数 lowerLeftLatitude
lowerLeftLongitude
upperRightLatitude
upperRightLongitude
将“边界框”设置为视图边界坐标应该可以。

@SuppressWarnings({"deprecation", "RedundantSuppression"}) ... Geocoder geoCoder = new Geocoder(requireContext()); if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.TIRAMISU) { geoCoder.getFromLocationName( geocode, maxResults, lowerLeftLatitude, lowerLeftLongitude, upperRightLatitude,upperRightLongitude, addresses -> { Address bestMatch = (addresses.isEmpty() ? null : addresses.get(0)); updatePosition(item, bestMatch); }); } else { try { List<Address> addresses = geoCoder.getFromLocationName(geocode, maxResults); Address bestMatch = (addresses.isEmpty() ? null : addresses.get(0)); updatePosition(item, bestMatch); } catch (IOException e) { if (mDebug) {Log.e(LOG_TAG, e.getMessage());} } }
    

0
投票
我最近遇到了一个问题,我不断收到 Java.IO.IOException: grpc failed.

我所做的是将 Geocoder 代码移至 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; } }
    

0
投票
我改编了@Eko Yulianto 的代码,以避免公开回调。

private suspend fun Geocoder.getAddress( latitude: Double, longitude: Double, ): Address? = withContext(dispatcherProvider.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 } }
    
© www.soinside.com 2019 - 2024. All rights reserved.