地理编码器 - getFromLocation() 方法已被弃用。

10
我收到一条消息,称此功能(或其构造函数)已被弃用。该函数有一个新的构造函数,接受一个额外的参数'Geocoder.GeocodeListener listener',但是这个新的构造函数需要API Level 33及以上。对于较低的API级别,我该怎么办?有什么解决方案吗?

enter image description here


1
警告是不正确的,在较低的SDK上这是正确的方法。你可以忽略它。另请参见https://dev59.com/g6vka4cB1Zd3GeqP0OTo - user3738870
6个回答

11

官方文档 - 使用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
        }
    }

这个答案对我来说很有效,特别是try { } catch { },因为我没有网络。 - Lance Samaria

5

由于在API级别33中已弃用此选项,我认为这是较低API级别的唯一选择。


1
我改编了@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
    }
}

1
谢谢!当我在多个地址上进行迭代并将结果集传递给流时,我不得不排除一些结果,而这个解决方案对我来说非常有效! - undefined

0

方法getFromLocationName仍然存在,但现在需要"边界框"参数lowerLeftLatitudelowerLeftLongitudeupperRightLatitudeupperRightLongitude
将"边界框"设置为视图边界坐标应该可以解决问题。

@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());}
    }
}

1
还存在另一种没有边界框参数的方法签名: https://developer.android.com/reference/android/location/Geocoder#getFromLocationName(java.lang.String,%20int,%20android.location.Geocoder.GeocodeListener) - Jose_GD

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();

这是我的可运行类:

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

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接