Places SDK for Android 可为您的应用提供有关地点的丰富信息,包括地点的名称和地址、以纬度/经度坐标指定的地理位置、地点类型(如夜总会、宠物店、博物馆)等。如需访问特定地点的此类信息,您可以使用地点 ID,这是用于唯一标识地点的稳定标识符。
地点详情
Place
对象提供有关特定地点的信息。您可以通过以下方式获取 Place
对象:
- 调用
PlacesClient.fetchPlace()
- 请参阅有关按 ID 获取地点的指南。 - 调用
PlacesClient.findCurrentPlace()
- 请参阅有关获取当前地点的指南。
请求地点时,您必须指定要返回的地点数据。为此,请传递 Place.Field 值列表,用于指定要返回的数据。此列表会影响到每个请求的费用,因此非常重要。
由于地点数据结果不能为空,因此只会返回包含数据的地点结果(例如,如果请求的地点没有照片,结果中将不会出现 photos
字段)。
以下示例传递了包含三个 Place.Field 值的列表,以指定请求返回的数据:
Kotlin
// Specify the fields to return. val placeFields = listOf(Place.Field.NAME, Place.Field.RATING, Place.Field.OPENING_HOURS)
Java
// Specify the fields to return. final ListplaceFields = Arrays.asList(Place.Field.NAME, Place.Field.RATING, Place.Field.OPENING_HOURS);
访问地点对象数据字段
获取 Place
对象后,请使用该对象的方法访问请求中指定的数据字段。如果 Place
对象中缺少该字段,相关方法会返回 null。下面列出了一些可用的方法示例。
如需查看所有方法的完整列表,请参阅 Place
API 参考文档。
getAddress()
- 地点的地址,采用人类可读懂的格式。getAddressComponents()
- 此地点的地址组成部分的List
。提供这些组件是为了提取有关地点地址的结构化信息,例如查找地点所在的城市。请勿使用这些组件进行地址格式设置,而应调用getAddress()
,它会提供本地化格式的地址。getId()
- 地点的文本标识符。请在本页面的其余部分详细了解地点 ID。getLatLng()
- 地点的地理位置,由纬度和经度坐标指定。getName()
- 地点的名称。getOpeningHours()
- 地点的OpeningHours
。调用OpeningHours.getWeekdayText()
即可返回一个字符串列表,这些字符串表示一周中每天的营业时间和结束营业时间。调用OpeningHours.getPeriods()
以返回period
对象列表,其中包含更详细的信息,相当于getWeekdayText()
提供的数据。Place
对象还包含getCurrentOpeningHours()
方法(用于返回地点在未来 7 天内的营业时间)和getSecondaryOpeningHours()
(用于返回地点在未来 7 天内的次要营业时间)。isOpen()
- 一个布尔值,表示该地点当前是否正在营业。如果未指定时间,则默认值为现在。仅当Place.Field.UTC_OFFSET
和Place.Field.OPENING_HOURS
均可用时,系统才会返回isOpen
。为确保结果准确无误,请在原始地点请求中请求Place.Field.BUSINESS_STATUS
和Place.Field.UTC_OFFSET
字段。 如果未申请,系统会假定该企业仍在运营。 请观看此视频,了解如何将isOpen
与“地点详情”搭配使用。
以下是一些简单示例:
Kotlin
val name = place.name val address = place.address val location = place.latLng
Java
final CharSequence name = place.getName(); final CharSequence address = place.getAddress(); final LatLng location = place.getLatLng();
访问 3.3.0 版中添加的地点数据
Places SDK for Android 3.3.0 版向 Place
中添加了新数据:
- 地点类型:与地点相关联的新类型值。
- 评价:某个地点的最多 5 条评价。
- 名称语言代码:地点名称的语言代码。
以下部分介绍了如何访问这些新数据。
访问新的地点类型
每个地点都可以有一个或多个与其相关联的 type 值。Places SDK for Android 3.3.0 版添加了许多新的类型值。如需查看完整列表,请参阅扩展的地点类型。
在 Places SDK for Android 3.2.0 及更低版本中,您使用 Place.getTypes()
方法访问与地点关联的类型值。Place.getTypes()
会返回一个类型列表,作为由 Place.Types
定义的枚举值。
Place.getPlaceTypes()
方法以字符串值列表的形式返回类型值。返回的值取决于您的 Places SDK for Android 版本:
- Places SDK for Android(新):返回地点类型(新)中显示的表 A 和表 B 定义的字符串,包括在版本 3.3.0 中添加的所有地点类型。
- Places SDK for Android:返回由
Place.Types
定义的枚举,其中不包括版本 3.3.0 中添加的新类型。
如需了解这两个 SDK 版本之间的主要区别,请参阅选择 SDK 版本。
访问地点评价
Places SDK for Android(新)添加了 Review
类,其中包含对地点的评价。Place
对象最多可以包含五条评价。
Review
类还可以包含提供方说明和作者提供方说明。如果您在应用中显示评价,则还必须显示提供方说明或作者出处。如需了解详情,请参阅显示评价。
如需使用评价填充 Place
对象,您必须执行以下操作:
- 在设置 Google Cloud 项目时启用新 SDK。
- 在 activity 或 fragment 中初始化新的 SDK。
- 在地点详情请求的字段列表中添加
Place.Field.REVIEWS
。 - 调用
PlacesClient.fetchPlace()
。PlacesClient.findCurrentPlace()
不支持评价字段。 - 使用
Place.getReviews()
方法访问Place
对象中的评价数据字段。
访问地点名称语言代码
现有的 Place.getName()
方法会返回包含地点名称的文本字符串。如需使用地点名称填充 Place
对象,您必须在地点详情请求的字段列表中添加 Place.Field.NAME
。
Place
对象现在包含名称字符串的语言代码。如需使用语言代码填充 Place
对象,您必须执行以下操作:
- 在设置 Google Cloud 项目时启用新 SDK。
- 在 activity 或 fragment 中初始化新的 SDK。
- 在请求的字段列表中添加
Place.Field.NAME
。此值可将响应配置为在Place
对象中同时包含地点名称和语言代码。 - 调用
PlacesClient.fetchPlace()
。PlacesClient.findCurrentPlace()
不支持语言代码字段。 - 使用
Place.getNameLanguageCode()
方法访问Place
对象中的语言代码字段。
在版本 3.3.0 中设置地区代码
Places SDK for Android(新)向“地点详情”添加了地区代码请求参数。地区代码用于设置响应的格式,将其指定为 两个字符的 CLDR 代码值。此参数还会对搜索结果产生偏差影响。没有默认值。您必须启用新版 SDK 才能设置地区代码。
如果响应中地址字段的国家/地区名称与地区代码匹配,则地址中省略国家/地区代码。
除了某些明显的例外情况之外,大多数 CLDR 代码都与 ISO 3166-1 代码相同。例如,英国的 ccTLD 为“uk”(.co.uk),而其 ISO 3166-1 代码为“gb”(特指“大不列颠及北爱尔兰联合王国”)。该参数可能会影响根据适用法律的结果。
按 ID 获取地点
地点 ID 是唯一标识地点的文本标识符。在 Places SDK for Android 中,您可以通过调用 Place.getId()
来检索地点 ID。
地点自动补全服务还会返回与提供的搜索查询和过滤条件匹配的每个地点的地点 ID。您可以存储地点 ID,并在之后使用它来检索 Place
对象。
如需按 ID 获取地点,请调用 PlacesClient.fetchPlace()
,并传递 FetchPlaceRequest
。
该 API 会在 Task
中返回 FetchPlaceResponse
。FetchPlaceResponse
包含与提供的地点 ID 匹配的 Place
对象。
以下代码示例展示了如何调用 fetchPlace()
来获取指定地点的详细信息。
Kotlin
// Define a Place ID. val placeId = "INSERT_PLACE_ID_HERE" // Specify the fields to return. val placeFields = listOf(Place.Field.ID, Place.Field.NAME) // Construct a request object, passing the place ID and fields array. val request = FetchPlaceRequest.newInstance(placeId, placeFields) placesClient.fetchPlace(request) .addOnSuccessListener { response: FetchPlaceResponse -> val place = response.place Log.i(PlaceDetailsActivity.TAG, "Place found: ${place.name}") }.addOnFailureListener { exception: Exception -> if (exception is ApiException) { Log.e(TAG, "Place not found: ${exception.message}") val statusCode = exception.statusCode TODO("Handle error with given status code") } }
Java
// Define a Place ID. final String placeId = "INSERT_PLACE_ID_HERE"; // Specify the fields to return. final List<Place.Field> placeFields = Arrays.asList(Place.Field.ID, Place.Field.NAME); // Construct a request object, passing the place ID and fields array. final FetchPlaceRequest request = FetchPlaceRequest.newInstance(placeId, placeFields); placesClient.fetchPlace(request).addOnSuccessListener((response) -> { Place place = response.getPlace(); Log.i(TAG, "Place found: " + place.getName()); }).addOnFailureListener((exception) -> { if (exception instanceof ApiException) { final ApiException apiException = (ApiException) exception; Log.e(TAG, "Place not found: " + exception.getMessage()); final int statusCode = apiException.getStatusCode(); // TODO: Handle error with given status code. } });
获取营业状态
PlacesClient.isOpen(IsOpenRequest request)
方法会返回一个 IsOpenResponse
对象,以根据调用中指定的时间指示该地点当前是否正在营业。
此方法接受 IsOpenRequest
类型的单个参数,该参数包含:
Place
对象,或用于指定地点 ID 的字符串。- 可选的时间值,用于指定从 1970-01-01T00:00:00Z 开始的时间(以毫秒为单位)。如果未指定时间,则默认值为现在。
此方法要求 Place
对象中存在以下字段:
Place.Field.BUSINESS_STATUS
Place.Field.CURRENT_OPENING_HOURS
Place.Field.OPENING_HOURS
Place.Field.UTC_OFFSET
如果 Place
对象中未提供这些字段,或者您传递了地点 ID,该方法会使用 PlacesClient.fetchPlace()
来获取这些字段。如需详细了解如何创建包含必填字段的 Place 对象,请参阅地点详情。
以下示例可确定某个地点目前是否营业。在此示例中,您只需将地点 ID 传递给 isOpen()
:
Kotlin
val isOpenCalendar: Calendar = Calendar.getInstance() val placeId = "ChIJD3uTd9hx5kcR1IQvGfr8dbk" val request: IsOpenRequest = try { IsOpenRequest.newInstance(placeId, isOpenCalendar.timeInMillis) } catch (e: IllegalArgumentException) { e.printStackTrace() return } val isOpenTask: Task<IsOpenResponse> = placesClient.isOpen(request) isOpenTask.addOnSuccessListener { response -> val isOpen = response.isOpen } // ...
Java
@NonNull Calendar isOpenCalendar = Calendar.getInstance(); String placeId = "ChIJD3uTd9hx5kcR1IQvGfr8dbk"; IsOpenRequest isOpenRequest; try { isOpenRequest = IsOpenRequest.newInstance(placeId, isOpenCalendar.getTimeInMillis()); } catch (IllegalArgumentException e) { e.printStackTrace(); return; } Task<IsOpenResponse> placeTask = placesClient.isOpen(isOpenRequest); placeTask.addOnSuccessListener( (response) -> isOpen = response.isOpen()); // ...
下一个示例展示了如何调用 isOpen()
,其中传递了一个 Place
对象。Place
对象必须包含有效的地点 ID:
Kotlin
val isOpenCalendar: Calendar = Calendar.getInstance() var place: Place val placeId = "ChIJD3uTd9hx5kcR1IQvGfr8dbk" // Specify the required fields for an isOpen request. val placeFields: List<Place.Field> = listOf( Place.Field.BUSINESS_STATUS, Place.Field.CURRENT_OPENING_HOURS, Place.Field.ID, Place.Field.OPENING_HOURS, Place.Field.UTC_OFFSET ) val placeRequest: FetchPlaceRequest = FetchPlaceRequest.newInstance(placeId, placeFields) val placeTask: Task<FetchPlaceResponse> = placesClient.fetchPlace(placeRequest) placeTask.addOnSuccessListener { placeResponse -> place = placeResponse.place val isOpenRequest: IsOpenRequest = try { IsOpenRequest.newInstance(place, isOpenCalendar.timeInMillis) } catch (e: IllegalArgumentException) { e.printStackTrace() return@addOnSuccessListener } val isOpenTask: Task<IsOpenResponse> = placesClient.isOpen(isOpenRequest) isOpenTask.addOnSuccessListener { isOpenResponse -> val isOpen = isOpenResponse.isOpen } // ... } // ...
Java
@NonNull Calendar isOpenCalendar = Calendar.getInstance(); String placeId = "ChIJD3uTd9hx5kcR1IQvGfr8dbk"; // Specify the required fields for an isOpen request. List<Place.Field> placeFields = new ArrayList<>(Arrays.asList( Place.Field.BUSINESS_STATUS, Place.Field.CURRENT_OPENING_HOURS, Place.Field.ID, Place.Field.OPENING_HOURS, Place.Field.UTC_OFFSET )); FetchPlaceRequest request = FetchPlaceRequest.newInstance(placeId, placeFields); Task<FetchPlaceResponse> placeTask = placesClient.fetchPlace(request); placeTask.addOnSuccessListener( (placeResponse) -> { Place place = placeResponse.getPlace(); IsOpenRequest isOpenRequest; try { isOpenRequest = IsOpenRequest.newInstance(place, isOpenCalendar.getTimeInMillis()); } catch (IllegalArgumentException e) { e.printStackTrace(); return; } Task<IsOpenResponse> isOpenTask = placesClient.isOpen(isOpenRequest); isOpenTask.addOnSuccessListener( (isOpenResponse) -> isOpen = isOpenResponse.isOpen()); // ... }); // ...
在应用中显示提供方说明
当应用显示地点信息(包括地点评价)时,还必须显示所有提供方说明。如需了解详情,请参阅归因。
更多关于地点 ID 的内容
Places SDK for Android 中使用的地点 ID 与 Places API 中使用的标识符相同。每个地点 ID 只能指代一个地点,但一个地点可以有多个地点 ID。还有其他情况也可能会导致地点获取新的地点 ID。例如,如果商家搬到新位置,就可能发生这种情况。
通过指定地点 ID 请求地点时,您可以确信自己始终会在响应中收到相同的地点(如果该地点仍然存在)。但请注意,响应包含的地点 ID 可能会与您的请求中的地点 ID 不同。
如需了解详情,请参阅地点 ID 概览。