Places SDK для Android предоставляет вашему приложению подробную информацию о местах, включая название и адрес места, географическое положение, указанное в виде координат широты и долготы, тип места (например, ночной клуб, зоомагазин, музей) и многое другое. Чтобы получить доступ к этой информации о конкретном месте, вы можете использовать идентификатор места — стабильный уникальный идентификатор.
Подробности места
Объект Place
предоставляет информацию о конкретном месте. Вы можете получить объект Place
, вызвав метод PlacesClient.fetchPlace()
– см. руководство по получению места по идентификатору .
При запросе местоположения необходимо указать, какие данные о месте нужно вернуть. Для этого передайте список значений Place.Field , определяющих возвращаемые данные. Этот список важен, поскольку он влияет на стоимость каждого запроса .
Поскольку результаты поиска по месту не могут быть пустыми, возвращаются только те, где есть данные. Например, если у запрошенного места нет фотографий, поле photos
не будет представлено в результате.
В следующем примере передается список из трех значений Place.Field для указания данных, возвращаемых запросом:
Котлин
// Specify the fields to return. val placeFields = listOf(Place.Field.DISPLAY_NAME, Place.Field.RATING)
Ява
// Specify the fields to return. final List<Place.Field> placeFields = Arrays.asList(Place.Field.DISPLAY_NAME, Place.Field.RATING);
Доступ к полям данных объекта Place
После получения объекта Place
используйте его методы для доступа к полям данных, указанным в запросе. Если поле отсутствует в объекте Place
, соответствующий метод вернёт значение null. Ниже приведены примеры некоторых доступных методов.
-
getAddress()
– адрес места в удобочитаемом формате. -
getAddressComponents()
–List
компонентов адреса для данного места. Эти компоненты предназначены для извлечения структурированной информации об адресе места, например, для определения города, в котором оно находится. Не используйте эти компоненты для форматирования адреса; вместо этого вызовитеgetAddress()
, который возвращает локализованный форматированный адрес. -
getId()
– текстовый идентификатор места. Подробнее об идентификаторах мест читайте далее на этой странице. -
getLatLng()
– географическое местоположение места, указанное в виде координат широты и долготы. -
getName()
– Название места. getOpeningHours()
– часыOpeningHours
места. Вызовите методOpeningHours.getWeekdayText()
, чтобы вернуть список строк, представляющих часы открытия и закрытия для каждого дня недели. Вызовите методOpeningHours.getPeriods()
чтобы вернуть список объектовperiod
с более подробной информацией, эквивалентной данным, предоставляемым методомgetWeekdayText()
.Объект
Place
также содержит методgetCurrentOpeningHours()
, который возвращает часы работы места на следующие семь дней, иgetSecondaryOpeningHours()
, который возвращает дополнительные часы работы места на следующие семь дней.isOpen()
– логическое значение, указывающее, открыто ли место в данный момент. Если время не указано, по умолчанию используется текущее.isOpen
возвращается только при наличии полейPlace.Field.UTC_OFFSET
иPlace.Field.OPENING_HOURS
. Для обеспечения точности результатов запросите поляPlace.Field.BUSINESS_STATUS
иPlace.Field.UTC_OFFSET
в исходном запросе места. Если поле не указано, предполагается, что место открыто. Посмотрите это видео , чтобы узнать, как использоватьisOpen
с информацией о месте.
Вот несколько примеров:
Котлин
val name = place.displayName val address = place.formattedAddress val location = place.location
Ява
final CharSequence name = place.getDisplayName(); final CharSequence address = place.getFormattedAddress(); final LatLng location = place.getLocation();
Получить место по ID
Идентификатор места — это текстовый идентификатор, который однозначно идентифицирует место. В Places SDK для Android идентификатор места можно получить, вызвав метод Place.getId()
. Служба автозаполнения мест также возвращает идентификатор для каждого места, соответствующего указанному поисковому запросу и фильтру. Вы можете сохранить идентификатор места и использовать его для последующего получения объекта Place
.
Чтобы получить место по идентификатору, вызовите PlacesClient.fetchPlace()
, передав FetchPlaceRequest
.
API возвращает FetchPlaceResponse
в Task
. FetchPlaceResponse
содержит объект Place
, соответствующий указанному идентификатору места.
В следующем примере кода показан вызов fetchPlace()
для получения сведений об указанном месте.
Котлин
// Define a Place ID. val placeId = PlaceIdProvider.getRandomPlaceId() // Specify the fields to return. val placeFields = listOf( Place.Field.ID, Place.Field.DISPLAY_NAME, Place.Field.FORMATTED_ADDRESS, Place.Field.LOCATION ) // 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 val name = place.displayName val address = place.formattedAddress val location = place.location binding.placeName.text = name binding.placeAddress.text = address if (location != null) { binding.placeLocation.text = getString( R.string.place_location, location.latitude, location.longitude ) } else { binding.placeLocation.text = null } Log.i(TAG, "Place found: ${place.displayName}") }.addOnFailureListener { exception: Exception -> if (exception is ApiException) { val message = getString(R.string.place_not_found, exception.message) binding.placeName.text = message Log.e(TAG, "Place not found: ${exception.message}") val statusCode = exception.statusCode TODO("Handle error with given status code") } }
Ява
// Define a Place ID. final String placeId = PlaceIdProvider.getRandomPlaceId(); // Specify the fields to return. final List<Place.Field> placeFields = Arrays.asList( Place.Field.ID, Place.Field.DISPLAY_NAME, Place.Field.FORMATTED_ADDRESS, Place.Field.LOCATION ); // 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(); final CharSequence name = place.getDisplayName(); final CharSequence address = place.getFormattedAddress(); final LatLng location = place.getLocation(); binding.placeName.setText(name); binding.placeAddress.setText(address); if (location != null) { binding.placeLocation.setText( getString(R.string.place_location, location.latitude, location.longitude) ); } else { binding.placeLocation.setText(null); } Log.i(TAG, "Place found: " + place.getDisplayName()); }).addOnFailureListener((exception) -> { if (exception instanceof ApiException apiException) { final String message = getString(R.string.place_not_found, apiException.getMessage()); binding.placeName.setText(message); 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
или строка, указывающая идентификатор места. - Необязательное значение времени, указывающее время в миллисекундах с 1970-01-01T00:00:00Z. Если время не указано, по умолчанию используется текущее.
Этот метод требует, чтобы в объекте Place
существовали следующие поля:
-
Place.Field.BUSINESS_STATUS
-
Place.Field.CURRENT_OPENING_HOURS
-
Place.Field.OPENING_HOURS
-
Place.Field.UTC_OFFSET
Если эти поля отсутствуют в объекте Place
или вы передаёте идентификатор места, метод использует PlacesClient.fetchPlace()
для их извлечения. Подробнее о создании объекта Place с необходимыми полями см. в разделе «Сведения о месте» .
В следующем примере определяется, открыто ли место в данный момент. В этом примере в isOpen()
передаётся только идентификатор места:
Котлин
val isOpenCalendar: Calendar = Calendar.getInstance() val placeId = PlaceIdProvider.getRandomPlaceId() val request: IsOpenRequest = try { IsOpenRequest.newInstance(placeId, isOpenCalendar.timeInMillis) } catch (e: IllegalArgumentException) { Log.e("PlaceIsOpen", "Error: " + e.message) return } val isOpenTask: Task<IsOpenResponse> = placesClient.isOpen(request) isOpenTask.addOnSuccessListener { response -> val isOpen = response.isOpen ?: false binding.isOpenByIdResult.text = getString(R.string.is_open_by_id, isOpen.toString()) Log.d("PlaceIsOpen", "Is open by ID: $isOpen") } // ...
Ява
@NonNull Calendar isOpenCalendar = Calendar.getInstance(); String placeId = PlaceIdProvider.getRandomPlaceId(); IsOpenRequest isOpenRequest; try { isOpenRequest = IsOpenRequest.newInstance(placeId, isOpenCalendar.getTimeInMillis()); } catch (IllegalArgumentException e) { Log.e("PlaceIsOpen", "Error: " + e.getMessage()); return; } Task<IsOpenResponse> placeTask = placesClient.isOpen(isOpenRequest); placeTask.addOnSuccessListener( (response) -> { final boolean isOpen = Boolean.TRUE.equals(response.isOpen()); binding.isOpenByIdResult.setText(getString(R.string.is_open_by_id, String.valueOf(isOpen))); Log.d("PlaceIsOpen", "Is open by ID: " + isOpen); }); placeTask.addOnFailureListener((exception) -> { binding.isOpenByIdResult.setText(getString(R.string.is_open_by_id, "Error: " + exception.getMessage())); Log.e("PlaceIsOpen", "Error: " + exception.getMessage()); });
В следующем примере показан вызов метода isOpen()
, в котором передаётся объект Place
. Объект Place
должен содержать действительный идентификатор места:
Котлин
val isOpenCalendar: Calendar = Calendar.getInstance() var place: Place val placeId = PlaceIdProvider.getRandomPlaceId() // 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.DISPLAY_NAME ) 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) { Log.e("PlaceIsOpen", "Error: " + e.message) return@addOnSuccessListener } val isOpenTask: Task<IsOpenResponse> = placesClient.isOpen(isOpenRequest) isOpenTask.addOnSuccessListener { isOpenResponse -> val isOpen = when (isOpenResponse.isOpen) { true -> getString(R.string.is_open) else -> getString(R.string.is_closed) } binding.isOpenByObjectResult.text = getString( R.string.is_open_by_object, place.displayName, isOpen ) Log.d("PlaceIsOpen", "Is open by object: $isOpen") } // ... } // ...
Ява
@NonNull Calendar isOpenCalendar = Calendar.getInstance(); String placeId = PlaceIdProvider.getRandomPlaceId(); // 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.DISPLAY_NAME )); 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) { Log.e("PlaceIsOpen", "Error: " + e.getMessage()); return; } Task<IsOpenResponse> isOpenTask = placesClient.isOpen(isOpenRequest); isOpenTask.addOnSuccessListener( (isOpenResponse) -> { final boolean isOpen = Boolean.TRUE.equals(isOpenResponse.isOpen()); binding.isOpenByObjectResult.setText(getString(R.string.is_open_by_object, place.getDisplayName(), String.valueOf(isOpen))); Log.d("PlaceIsOpen", "Is open by object: " + isOpen); }); isOpenTask.addOnFailureListener( (exception) -> { // also update the result text field binding.isOpenByObjectResult.setText(getString(R.string.is_open_by_object, place.getDisplayName(), "Error: " + exception.getMessage())); Log.e("PlaceIsOpen", "Error: " + exception.getMessage()); }); }); placeTask.addOnFailureListener( (exception) -> { binding.isOpenByObjectResult.setText("Error: " + exception.getMessage()); Log.e("PlaceIsOpen", "Error: " + exception.getMessage());
Отображение атрибуции в вашем приложении
Когда ваше приложение отображает информацию о месте, включая отзывы, оно также должно отображать информацию об авторстве. Подробнее см. в разделе «Атрибуция» .
Подробнее об идентификаторах мест
Идентификатор места, используемый в Places SDK для Android, совпадает с идентификатором, используемым в Places API . Каждый идентификатор места может относиться только к одному месту, но у одного места может быть несколько идентификаторов. Существуют и другие обстоятельства, при которых место может получить новый идентификатор. Например, это может произойти при переезде компании.
Запрашивая место, указывая его идентификатор, вы можете быть уверены, что в ответе всегда будет указано одно и то же место (если оно всё ещё существует). Однако обратите внимание, что в ответе может содержаться идентификатор места, отличный от указанного в вашем запросе.
Более подробную информацию см. в обзоре идентификаторов мест .