0

我试图从回调函数中获取地址。我一直在阅读 CallBacks 的文档和一些帖子,但仍然不明白为什么这不起作用,因为在返回“地址”变量时,回调已经完成。

    private fun getAddressForCoordinates(geoCoordinates: GeoCoordinates):String {
    address = "unchanged"
    val maxItems = 1
    val reverseGeocodingOptions = SearchOptions(LanguageCode.EN_GB, maxItems)
    searchEngine.search(geoCoordinates, reverseGeocodingOptions, addressSearchCallback)

    return address

}

private val addressSearchCallback =
    SearchCallback { searchError, list ->
        if (searchError != null) {
            //showDialog("Reverse geocoding", "Error: $searchError")
            Toast.makeText(context, "Error: $searchError", Toast.LENGTH_LONG).show()
            return@SearchCallback
        }

        Toast.makeText(
            context,
            "Reverse geocoded address:" + list!![0].address.addressText,
            Toast.LENGTH_LONG
        ).show()

        address = list[0].address.addressText
    }
4

3 回答 3

0
private void getAddressForCoordinates(GeoCoordinates geoCoordinates) {
    int maxItems = 1;
    SearchOptions reverseGeocodingOptions = new SearchOptions(LanguageCode.EN_GB, maxItems);

    searchEngine.search(geoCoordinates, reverseGeocodingOptions, new SearchCallback() {
        @Override
        public void onSearchCompleted(@Nullable SearchError searchError, @Nullable List<Place> list) {
            if (searchError != null) {
                showDialog("Reverse geocoding", "Error: " + searchError.toString());
                return;
            }

            // If error is null, list is guaranteed to be not empty.
            showDialog("Reverse geocoded address:", list.get(0).getAddress().addressText);
        }
    });
}

SearchEngine,需要提供一个 SearchOptions 实例来设置所需的 LanguageCode。它确定结果地址的语言。然后我们可以调用引擎的 search() 方法在线搜索传递的坐标的地址。如果出现错误,例如设备离线时,SearchError 会保存错误原因。

反向地理编码响应包含错误或结果:SearchError 和结果列表不能同时为空 - 或同时非空。

每个 Place 实例中包含的 Address 对象是一个数据类,其中包含多个 String 字段,描述原始位置的地址,例如国家、城市、街道名称等等。有关更多详细信息,请参阅 API 参考。如果您只对接收可读的地址表示感兴趣,则可以访问 addressText,如上例所示。这是一个字符串,其中包含最相关的地址详细信息,包括地点的标题。

有关 search() 函数及其相关参数的详细文档,请参阅以下链接。

https://developer.here.com/documentation/android-sdk-explore/4.4.0.2/dev_guide/topics/search.html

于 2021-06-11T10:40:31.200 回答
0

4.x HERE SDK中的 SearchEngine需要在线连接,因为它正在从远程后端获取结果。这可能需要几毫秒,具体取决于您的网络连接。因此,无论何时执行搜索请求,都需要等到回调被调用:

searchEngine.search(geoCoordinates, reverseGeocodingOptions, addressSearchCallback)

当你调用它时,你addressSearchCallback作为参数传递。for 的实现addressSearchCallback可能类似于您的示例。只要操作完成,就会调用它。如果设备处于离线状态,则会显示错误。

请注意,该search()方法不会立即返回任何结果。这些被传递给回调,该回调在后台线程上异步发生。因此,您的应用程序可以继续工作而不会阻塞任何 UI。

一旦检索到结果,回调将由 HERE SDK 在主线程上执行。

所以,如果你的代码需要对地址结果做一些事情,你必须onSearchCompleted()SearchCallback. 如果你用没有 lambda 表示法的纯 Java 编写它,它会更明显:你创建一个新SearchCallback对象并将它作为参数传递给 SearchEngine。onSearchCompleted()SearchEngine 存储对象并在它认为合适的时候执行对象的:

private SearchCallback addressSearchCallback = new SearchCallback() {
    @Override
    public void onSearchCompleted(@Nullable SearchError searchError, @Nullable List<Place> list) {
        if (searchError != null) {
            showDialog("Reverse geocoding", "Error: " + searchError.toString());
            return;
        }

        // If error is null, list is guaranteed to be not empty.
        showDialog("Reverse geocoded address:", list.get(0).getAddress().addressText);

        // Here is the place to do something more useful with the Address object ...!
    }
};

我从这个GitHub 代码片段中获取了这个。请注意,还有一个OfflineSearchEngine, 可以在没有互联网连接的情况下工作,但由于某种原因,它遵循相同的模式并异步执行任务。

于 2021-06-07T20:26:02.360 回答
0

从您的代码和评论中,我假设您不熟悉异步执行的概念。这个概念在这里得到了很好的描述。我将引用主要观点:

当您同步执行某事时,您会等待它完成,然后再继续执行另一个任务。当您异步执行某事时,您可以在它完成之前继续执行另一个任务。

search()需要提供回调并且它不只是返回搜索结果的事实很好地表明它很可能是异步的。调用它就像是在说:“在后台搜索数据,当你有数据时告诉我。这是我的电子邮件地址 - 请把我的结果发给我”。其中电子邮件地址是您的回电。调用search()方法不会阻止代码的执行,它不会等待结果 - 它只会安排搜索并几乎立即返回。

异步处理通常比常规的同步代码更棘手,但在许多情况下它更有效。在您的情况下,您可以尝试“转换”库的原始异步 API 以同步您的代码期望的 API - 但这不是推荐的方法。或者你可以重新设计你的代码,让它异步工作。例如,不要这样做:

fun yourMethodThatNeedsAddress() {
    val address = getAddressForCoordinates()
    doSomethingWithAddress(address)
}

你需要这样做:

fun yourMethodThatNeedsAddress() {
    scheduleGetAddressForCoordinates() // renamed getAddressForCoordinates()
}

fun addressSearchCallback() {
    ...
    doSomethingWithAddress(address)
}

因此,无论您计划对获取的地址做什么,都不能在开始搜索后立即执行此操作。您需要等待回调,然后从那里继续处理您的地址。

于 2021-06-02T20:08:34.560 回答