自动补全(新)会返回地点预测结果,以响应包含文本搜索字符串和控制搜索区域的地理界限的请求。自动补全功能可以根据输入的完整字词和子字符串进行匹配,从而解析地点名称、地址和 Plus Codes。您的应用可以在用户输入内容时发送查询,从而即时进行地点和查询预测。
例如,您可以使用包含部分用户输入内容“Sicilian piz”的字符串作为输入内容来调用自动补全功能,并将搜索区域限制为加利福尼亚州旧金山。然后,响应会包含与搜索字符串和搜索区域匹配的地点预测列表,例如名为“Sicilian Pizza Kitchen”的餐厅。返回的地点预测旨在呈现给用户,以帮助他们选择所需的地点。您可以发出地点详情(新)请求,以获取有关任何返回的地点预测的更多信息。
您可以通过以下两种主要方式将自动补全(新)功能集成到应用中:
- 添加地点自动补全 widget:通过
PlaceAutocomplete
类提供即输即找的搜索自动补全体验,该类会在用户输入内容时显示预测结果。 - 以编程方式获取地点预测结果:直接调用 API 以检索预测结果,并在自定义用户界面中显示这些结果。
添加地点自动补全 widget
为了更轻松地提供一致的地点自动补全体验,您可以向应用中添加地点自动补全 widget。该 widget 提供了一个专用的全屏界面,用于处理用户输入内容并向用户显示地点预测结果,同时向应用返回 AutocompletePrediction
对象。然后,您可以发出地点详情(新)请求,以获取有关任何地点预测结果的更多信息。
与以程序化方式获取地点预测结果类似,地点自动补全 widget 可让您使用会话令牌将自动补全请求分组到会话中,以便进行结算。您可以在调用 setAutocompleteSessionToken()
时传递会话令牌,以创建 widget 的 intent。如果您未提供会话令牌,该 widget 会为您创建一个,您可以通过调用 getSessionTokenFromIntent()
来访问该令牌。如需详细了解如何使用会话令牌,请参阅关于会话令牌。
如需向应用添加地点自动补全微件,请执行以下操作:
(可选)定义会话令牌。如果您未提供会话令牌,该 widget 会为您创建一个。
使用所需参数和会话令牌定义
autocompleteIntent
。为
StartActivityForResult
定义ActivityResultLauncher
。 此启动器将处理从自动补全 activity 返回的结果。在
ActivityResultLauncher
的回调中处理结果。这包括提取AutocompletePrediction
和AutocompleteSessionToken
(如果您尚未提供自己的AutocompletePrediction
和AutocompleteSessionToken
)、处理错误,以及选择性地发出fetchPlace()
请求以获取有关地点的更多详细信息。使用
placeAutocompleteActivityResultLauncher
启动 intent
以下示例演示了如何使用 Kotlin 和 Java 添加地点自动补全 widget:
Kotlin
// Provide the API key that has enabled "Places API (New)" in the Google Cloud Console. Places.initializeWithNewPlacesApiEnabled(/* Context= */ context, /* API Key= */ key) // Optional, create a session token for Autocomplete request and the followup FetchPlace request. val sessionToken: AutocompleteSessionToken = AutocompleteSessionToken.newInstance() val autocompleteIntent: Intent = PlaceAutocomplete.createIntent(this) { // ... provide input params for origin, countries, types filter ... setAutocompleteSessionToken(sessionToken) } val placeAutocompleteActivityResultLauncher: ActivityResultLauncher<Intent> = registerForActivityResult(ActivityResultContracts.StartActivityForResult()) { result: ActivityResult -> val intent = result.data if (intent != null && result.resultCode == PlaceAutocompleteActivity.RESULT_OK) { // get prediction object val prediction: AutocompletePrediction? = PlaceAutocomplete.getPredictionFromIntent(intent!!) // get session token val sessionToken: AutocompleteSessionToken? = PlaceAutocomplete.getSessionTokenFromIntent(intent!!) // create PlacesClient to make FetchPlace request (optional) val placesClient: PlacesClient = Places.createClient(this) val response = placesClient.awaitFetchPlace(prediction.placeId, Field.DISPLAY_NAME) { sessionToken = sessionToken // optional } } } // Launch Activity placeAutocompleteActivityResultLauncher.launch(autocompleteIntent)
Java
// Provide the API key that has enabled "Places API (New)" in the Google Cloud Console. Places.initializeWithNewPlacesApiEnabled(/* Context= */ context, /* API Key= */ key); // Optional, create a session token for Autocomplete request and the followup FetchPlace request AutocompleteSessionToken sessionToken = AutocompleteSessionToken.newInstance(); Intent autocompleteIntent = new PlaceAutocomplete.IntentBuilder() // ... set input params for origin, countries, types filter ... .setSessionToken(sessionToken) // optional .build(this); ActivityResultLauncher<Intent> placeAutocompleteActivityResultLauncher = registerForActivityResult( new ActivityResultContracts.StartActivityForResult(), new ActivityResultCallback<ActivityResult>() { @Override public void onActivityResult(ActivityResult result) { Intent intent = result.getData(); if (result.getResultCode() == PlaceAutocompleteActivity.RESULT_OK) { // get prediction object AutocompletePrediction prediction = PlaceAutocomplete.getPredictionFromIntent( Preconditions.checkNotNull(intent)); // get session token AutocompleteSessionToken sessionToken = PlaceAutocomplete.getSessionTokenFromIntent( Preconditions.checkNotNull(intent)); // create PlacesClient to make FetchPlace request (optional) PlacesClient placesClient = Places.createClient(this); FetchPlaceRequest request = FetchPlaceRequest.builder(prediction.getPlaceId(), Arrays.asList(Field.DISPLAY_NAME)) .setSessionToken(sessionToken).build(); Task<FetchPlaceResponse> task = placesClient.fetchPlace(request); } } } ); // Launch Activity placeAutocompleteActivityResultLauncher.launch(autocompleteIntent);
以编程方式获取地点预测结果
您的应用可以通过调用 PlacesClient.findAutocompletePredictions()
并传递 FindAutocompletePredictionsRequest
对象,从自动补全 API 获取预测的地点名称和/或地址列表。以下示例展示了对 PlacesClient.findAutocompletePredictions()
的完整调用。
Places.initializeWithNewPlacesApiEnabled(context, apiKey); final List<Field> placeFields = getPlaceFields(); LatLng center = new LatLng(37.7749, -122.4194); CircularBounds circle = CircularBounds.newInstance(center, /* radius = */ 5000); final FindAutocompletePredictionsRequest autocompletePlacesRequest = FindAutocompletePredictionsRequest.builder() .setQuery("Sicilian piz") .setRegionCode("ES") .setLocationRestriction(circle) .build()); placesClient.findAutocompletePredictions(autoCompletePlacesRequest) .addOnSuccessListener( (response) -> { List<AutocompletePrediction> predictions = response.getResult().getAutocompletePredictions(); } ).addOnFailureListener( exception -> { Log.e(TAG, "some exception happened" + exception.getMessage()); }) );
自动补全(新)响应
该 API 会在 Task
中返回 FindAutocompletePredictionsResponse
。FindAutocompletePredictionsResponse
包含一个最多有 5 个 AutocompletePrediction
对象(表示预测的地点)的列表。如果没有与查询和过滤条件对应的已知地点,则该列表可能为空。
对于每个预测地点,您可以调用以下方法来检索地点详细信息:
getFullText(CharacterStyle)
返回地点说明的完整文本。这是主要文本和次要文本的组合。示例:“Eiffel Tower, Avenue Anatole France, Paris, France”。此外,此方法还允许您使用CharacterStyle
以您选择的样式突出显示与搜索内容匹配的说明部分。CharacterStyle
参数是可选的。如果您不需要任何突出显示,请将其设置为 null。getPrimaryText(CharacterStyle)
返回描述某个地点的主要文本。这通常是地点的名称。示例:“埃菲尔铁塔”和“皮特街 123 号”。getSecondaryText(CharacterStyle)
返回地点说明的辅助文本。例如,在显示自动补全预测时,此属性可用作第二行。示例:“Avenue Anatole France, Paris, France”(法国巴黎的阿纳托尔·法兰西大街)和“Sydney, New South Wales”(新南威尔士州悉尼)。getPlaceId()
返回预测地点的地点 ID。地点 ID 是唯一标识地点的文本标识符,您可以使用它在日后再次检索Place
对象。如需详细了解自动补全服务中的地点 ID,请参阅地点详情(新)。如需了解地点 ID 的一般信息,请参阅地点 ID 概览。getTypes()
返回与相应地点相关联的地点类型列表。getDistanceMeters()
返回相应地点与请求中指定的原点之间的直线距离(以米为单位)。
必需参数
-
查询
要搜索的文本字符串。指定完整字词和子字符串、地点名称、地址和 Plus Codes。 自动补全(新)服务将根据此字符串返回候选匹配结果,并按照其判断的相关性对结果进行排序。
如需设置查询参数,请在构建
FindAutocompletePredictionsRequest
对象时调用setQuery()
方法。
可选参数
-
主要类型
一个列表,最多可包含表 A 或表 B 中的五种类型值,用于过滤响应中返回的地点。 地点必须与指定的主要类型值之一匹配,才能包含在响应中。
一个地点只能有一个主要类型(来自表 A 或表 B)与之关联。例如,主要类型可以是
"mexican_restaurant"
或"steak_house"
。如果出现以下情况,请求会被拒绝并显示
INVALID_REQUEST
错误:- 指定了超过五种类型。
- 指定了任何无法识别的类型。
如需设置主要类型参数,请在构建
FindAutocompletePredictionsRequest
对象时调用setTypesFilter()
方法。 -
国家/地区
仅包含指定国家/地区列表中的结果,以最多 15 个 ccTLD(“顶级域名”)双字符值的列表形式指定。如果省略,则对响应不应用任何限制。例如,如需将区域限制为德国和法国,请执行以下操作:
如果您同时指定了
locationRestriction
和includedRegionCodes
,则结果位于这两个设置的交集区域。如需设置国家/地区参数,请在构建
FindAutocompletePredictionsRequest
对象时调用setCountries()
方法。 -
输入偏移
从零开始的 Unicode 字符偏移量,用于指示查询中的光标位置。 光标位置可能会影响返回的预测结果。如果为空,则默认为查询的长度。
如需设置输入偏移量参数,请在构建
FindAutocompletePredictionsRequest
对象时调用setInputOffset()
方法。 位置倾向或位置限制
您可以指定位置偏差或位置限制(但不能同时指定这两者)来定义搜索区域。位置限制是指指定结果必须位于的区域,而位置偏差是指指定结果必须靠近的区域。主要区别在于,使用位置偏差时,系统仍可能会返回指定区域以外的结果。
位置偏差
指定要搜索的区域。此位置用作偏向,而非限制,因此系统仍可能会返回指定区域以外的结果。
如需设置位置信息偏差参数,请在构建
FindAutocompletePredictionsRequest
对象时调用setLocationBias()
方法。位置限制
指定要搜索的区域。系统不会返回指定区域以外的结果。
如需设置地理位置限制参数,请在构建
FindAutocompletePredictionsRequest
对象时调用setLocationRestriction()
方法。
将位置偏差或位置限制区域指定为矩形视口或圆形。
圆由中心点和半径(以米为单位)定义。半径必须介于 0.0 到 50000.0 之间(含边界值)。默认值为 0.0。对于地理位置限制,您必须将半径设置为大于 0.0 的值。否则,请求不会返回任何结果。
矩形是纬度-经度视口,表示为两个对角相对的
low
和high
点。视口被视为一个封闭区域,这意味着它包含其边界。纬度范围必须介于 -90 度到 90 度之间(含),经度范围必须介于 -180 度到 180 度之间(含):- 如果
low
=high
,则视口由该单个点组成。 - 如果
low.longitude
>high.longitude
,则经度范围会反转(视口会跨越 180 度经度线)。 - 如果
low.longitude
= -180 度且high.longitude
= 180 度,则视口包含所有经度。 - 如果
low.longitude
= 180 度且high.longitude
= -180 度,则经度范围为空。
low
和high
都必须填充,并且所表示的框不能为空。空视口会导致错误。- 如果
-
来源
用于计算到目的地的直线距离的起点(使用
getDistanceMeters()
进行访问)。如果省略此值,则不会返回直线距离。必须指定为纬度和经度坐标:如需设置来源参数,请在构建
FindAutocompletePredictionsRequest
对象时调用setOrigin()
方法。 -
区域代码
用于设置响应格式(包括地址格式)的地区代码,以 ccTLD(“顶级域名”)双字符值的形式指定。大多数 ccTLD 代码都与 ISO 3166-1 代码完全一致,但也有一些明显的例外情况。例如,英国的 ccTLD 为“uk”(.co.uk),而其 ISO 3166-1 代码为“gb”(从技术上讲,是指“大不列颠及北爱尔兰联合王国”这一实体)。
如果您指定的区域代码无效,则 API 会返回
INVALID_ARGUMENT
错误。此参数可能会根据适用法律影响结果。如需设置区域代码参数,请在构建
FindAutocompletePredictionsRequest
对象时调用setRegionCode()
方法。 -
会话令牌
会话令牌是由用户生成的字符串,用于将自动补全(新)调用(包括通过 widget 发出的调用和程序化调用)跟踪为“会话”。自动补全功能使用会话令牌将用户自动补全搜索的查询和选择阶段归入不同的会话,以便进行结算。会话在用户开始输入查询内容时开始,并在用户选择地点时结束。在每个会话中,用户可以输入多项查询内容,并最终选择一个地点。会话结束后,令牌将失效;您的应用必须为每个会话生成一个新的令牌。我们建议您针对所有程序化自动补全会话使用会话令牌(当您嵌入 fragment 或使用 intent 启动自动补全时,API 会自动处理此问题)。
自动补全功能使用
AutocompleteSessionToken
来标识每个会话。您的应用应在每次新会话开始时传递新的会话令牌,然后在后续对fetchPlace()
的调用中传递该令牌以及地点 ID,以检索用户所选地点的地点详情。如需设置会话令牌参数,请在构建
FindAutocompletePredictionsRequest
对象时调用setSessionToken()
方法。如需了解详情,请参阅会话令牌。
自动补全(新)示例
使用地理位置限制和地理位置偏差
自动补全(新)默认使用 IP 偏向来控制搜索区域。借助 IP 偏向,API 会使用设备的 IP 地址来偏向结果。您可以选择性地使用位置限制或位置偏差(但不能同时使用两者)来指定搜索区域。
位置限制用于指定搜索区域。系统不会返回指定区域以外的结果。以下示例使用位置限制将请求限制为以旧金山为中心、半径为 5,000 米的圆形位置限制:
Places.initializeWithNewPlacesApiEnabled(context, apiKey); final List<Field> placeFields = getPlaceFields(); LatLng center = new LatLng(37.7749, -122.4194); CircularBounds circle = CircularBounds.newInstance(center, /* radius = */ 5000); final FindAutocompletePredictionsRequest autocompletePlacesRequest = FindAutocompletePredictionsRequest.builder() .setQuery("Amoeba") .setLocationRestriction(circle) .build()); placesClient.findAutocompletePredictions(autoCompletePlacesRequest) .addOnSuccessListener( (response) -> { List<AutocompletePrediction> predictions = response.getResult().getAutocompletePredictions(); } ).addOnFailureListener( exception -> { Log.e(TAG, "some exception happened" + exception.getMessage()); }) );
使用位置偏差时,位置会作为偏差,这意味着系统可能会返回指定位置附近的结果,包括指定区域之外的结果。以下示例将之前的请求更改为使用位置偏差:
Places.initializeWithNewPlacesApiEnabled(context, apiKey); final List<Field> placeFields = getPlaceFields(); LatLng center = new LatLng(37.7749, -122.4194); CircularBounds circle = CircularBounds.newInstance(center, /* radius = */ 5000); final FindAutocompletePredictionsRequest autocompletePlacesRequest = FindAutocompletePredictionsRequest.builder() .setQuery("Amoeba") .setLocationBias(circle) .build()); placesClient.findAutocompletePredictions(autoCompletePlacesRequest) .addOnSuccessListener( (response) -> { List<AutocompletePrediction> predictions = response.getResult().getAutocompletePredictions(); } ).addOnFailureListener( exception -> { Log.e(TAG, "some exception happened" + exception.getMessage()); }) );
使用主要类型
使用 primary types 参数可将请求的结果限制为 表 A 和表 B 中列出的特定类型。您可以指定一个最多包含 5 个值的数组。如果省略,则返回所有类型。
以下示例指定了“Soccer”的查询字符串,并使用 primaryTypes 参数将结果限制为 "sporting_goods_store"
类型的场所:
Places.initializeWithNewPlacesApiEnabled(context, apiKey); final List<Field> placeFields = getPlaceFields(); final List<Place.Field> primaryTypes = Arrays.asList("sporting_goods_store"); LatLng center = new LatLng(37.7749, -122.4194); CircularBounds circle = CircularBounds.newInstance(center, /* radius = */ 5000); final FindAutocompletePredictionsRequest autocompletePlacesRequest = FindAutocompletePredictionsRequest.builder() .setQuery("Soccer") .setIncludedPrimaryTypes(primaryTypes) .setLocationBias(circle) .build()); placesClient.findAutocompletePredictions(autoCompletePlacesRequest) .addOnSuccessListener( (response) -> { List<AutocompletePrediction> predictions = response.getResult().getAutocompletePredictions(); } ).addOnFailureListener( exception -> { Log.e(TAG, "some exception happened" + exception.getMessage()); }) );
如果您省略了 primary types 参数,结果可能会包含您不想要的类型的商家,例如 "athletic_field"
。
使用来源
如果您在请求中添加了出发地参数(指定为纬度和经度坐标),则 API 会在响应中添加从出发地到目的地的直线距离(使用 getDistanceMeters()
进行访问)。以下示例将出发地设置为旧金山的中心:
Places.initializeWithNewPlacesApiEnabled(context, apiKey); final List<Field> placeFields = getPlaceFields(); LatLng center = new LatLng(37.7749, -122.4194); CircularBounds circle = CircularBounds.newInstance(center, /* radius = */ 5000); final FindAutocompletePredictionsRequest autocompletePlacesRequest = FindAutocompletePredictionsRequest.builder() .setQuery("Amoeba") .setOrigin(center) .setLocationRestriction(circle) .build()); placesClient.findAutocompletePredictions(autoCompletePlacesRequest) .addOnSuccessListener( (response) -> { List<AutocompletePrediction> predictions = response.getResult().getAutocompletePredictions(); } ).addOnFailureListener( exception -> { Log.e(TAG, "some exception happened" + exception.getMessage()); }) );