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 . Каждый идентификатор места может относиться только к одному месту, но у одного места может быть несколько идентификаторов. Существуют и другие обстоятельства, при которых место может получить новый идентификатор. Например, это может произойти при переезде компании.
Запрашивая место, указывая его идентификатор, вы можете быть уверены, что в ответе всегда будет указано одно и то же место (если оно всё ещё существует). Однако обратите внимание, что в ответе может содержаться идентификатор места, отличный от указанного в вашем запросе.
Более подробную информацию см. в обзоре идентификаторов мест .