Places SDK для Android (устаревшая версия) предоставляет приложению подробную информацию о местах, включая название и адрес, географическое местоположение, указанное в виде координат широты и долготы, тип места (например, ночной клуб, зоомагазин, музей) и т. д. Чтобы получить доступ к этой информации для определенного места, вы можете использовать идентификатор места – стабильный идентификатор, который уникальным образом идентифицирует место.
Об этом месте
Объект Place содержит информацию об определенном месте. Объект Place можно получить, вызвав метод PlacesClient.fetchPlace(). Подробнее о том, как получить место по идентификатору…
При запросе места необходимо указать, какие данные о нем нужно вернуть. Для этого передайте список значений Place.Field, указывающих, какие данные нужно вернуть. Этот список важен, поскольку влияет на стоимость каждого запроса.
Поскольку ответ на запрос информации из таких полей не может быть пустым, возвращаются только результаты для мест, о которых такая информация есть. Например, если у места нет фотографий, поля photos в результатах не будет.
В следующем примере передается список из трех значений Place.Field, чтобы указать данные, возвращаемые запросом:
Kotlin
// Specify the fields to return. val placeFields = listOf(Place.Field.DISPLAY_NAME, Place.Field.RATING)
Java
// 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с информацией о местах.
Ниже приведено несколько примеров.
Kotlin
val name = place.displayName val address = place.formattedAddress val location = place.location
Java
final CharSequence name = place.getDisplayName(); final CharSequence address = place.getFormattedAddress(); final LatLng location = place.getLocation();
Получение информации о месте по его идентификатору
Идентификатор места – это уникальный текстовый идентификатор. В Places SDK для Android идентификатор места можно получить, вызвав метод Place.getId().
Сервис автозаполнение мест также возвращает идентификатор места для каждого места, соответствующего предоставленному поисковому запросу и фильтру. Вы можете сохранить идентификатор места и использовать его для повторного получения объекта Place позже.
Чтобы получить место по идентификатору, вызовите PlacesClient.fetchPlace(), передав FetchPlaceRequest.
API возвращает объект FetchPlaceResponse в Task.
FetchPlaceResponse содержит объект Place, соответствующий указанному идентификатору места.
В примере ниже показан вызов fetchPlace() для получения сведений об указанном месте.
Kotlin
// 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") } }
Java
// 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_STATUSPlace.Field.CURRENT_OPENING_HOURSPlace.Field.OPENING_HOURSPlace.Field.UTC_OFFSET
Если эти поля не указаны в объекте Place или вы передаете идентификатор места, метод использует PlacesClient.fetchPlace(), чтобы получить их. Подробнее о том, как создать объект Place с необходимыми полями, рассказывается в разделе Информация о местах.
В следующем примере показано, как определить, открыто ли место в данный момент. В этом примере вы передаете в isOpen() только идентификатор места:
Kotlin
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") } // ...
Java
@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 должен содержать действительный идентификатор места:
Kotlin
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") } // ... } // ...
Java
@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 (устаревшей версии). Идентификатор может относиться только к одному месту, однако одному месту можно присвоить сразу несколько идентификаторов. Существуют и другие обстоятельства, при которых место может получить новый идентификатор места. Например, это может произойти, если компания переезжает.
Если вы запрашиваете место, указав его идентификатор, то можете быть уверены, что в ответе всегда получите информацию об одном и том же месте (если оно ещё существует). Обратите внимание, что ответ может содержать идентификатор места, отличный от указанного в запросе.
Подробную информацию можно найти в статье Общие сведения об идентификаторах мест.