The Places SDK for Android provides your app with rich information about places, including the place's name and address, the geographical location specified as latitude/longitude coordinates, the type of place (such as night club, pet store, museum), and more. To access this information for a specific place, you can use the place ID, a stable identifier that uniquely identifies a place.
Place details
The
Place
object provides information about a specific place. You can get hold of a
Place
object in the following ways:
- Call
PlacesClient.fetchPlace()
– See the guide to getting a place by ID. - Call
PlacesClient.findCurrentPlace()
– See the guide to getting the current place.
When you request a place, you must specify which place data to return. To do this, pass a list of Place.Field values specifying the data to return. This list is an important consideration because it affects the cost for each request.
Because place data results cannot be empty, only place results with data are
returned (for example, if a requested place has no photos, the photos
field will not be present in the result).
The following example passes a list of three Place.Field values to specify the data returned by a request:
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);
Access Place object data fields
After you obtain the Place
object, use methods of the object to access the
data fields specified in the request. If the field is missing from the Place
object,
the related method returns null. Shown below are examples of a few of the available methods.
For a complete list of all methods, see the
Place
API reference.
getAddress()
– The place's address, in human-readable format.getAddressComponents()
– AList
of address components for this place. These components are provided for the purpose of extracting structured information about a place's address, for example finding the city in which a place is located. Do not use these components for address formatting; instead, callgetAddress()
, which provides a localized formatted address.getId()
– The textual identifier for the place. Read more about place IDs in the rest of this page.getLatLng()
– The geographical location of the place, specified as latitude and longitude coordinates.getName()
– The place's name.getOpeningHours()
– TheOpeningHours
of the place. CallOpeningHours.getWeekdayText()
to return a list of strings that represent opening and closing hours for each day of the week. CallOpeningHours.getPeriods()
to return a list ofperiod
objects with more detailed information that is equivalent to the data provided bygetWeekdayText()
.The
Place
object also contains thegetCurrentOpeningHours()
method which returns a place's hours of operation over the next seven days, andgetSecondaryOpeningHours()
which returns a place's secondary hours of operation over the next seven days.isOpen()
– A boolean indicating whether the place is currently open. If no time is specified, the default is now.isOpen
will only be returned if bothPlace.Field.UTC_OFFSET
andPlace.Field.OPENING_HOURS
are available. To ensure accurate results, request thePlace.Field.BUSINESS_STATUS
andPlace.Field.UTC_OFFSET
fields in your original place request. If not requested, it is assumed that the business is operational. See this video for how to useisOpen
with Place Details.
Some simple examples:
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();
Access Place data added in version 3.3.0
Places SDK for Android version 3.3.0 adds new data to
Place
:
- Place types: New type values associated with a place.
- Reviews: Up to five reviews for a place.
- Name language code: The language code for the name of a place.
The following sections describe how to access this new data.
Access new place types
Each place can have one or more type values associated with it. The Places SDK for Android version 3.3.0 adds many new type values. For the complete list, see Expanded place types.
In Places SDK for Android version 3.2.0 and earlier, you used the
Place.getTypes()
method to access the type values associated with a place. Place.getTypes()
returns a
list of types as enum values defined by
Place.Types
.
The Place.getPlaceTypes()
method returns the type values as a list of string values. The values returned depend on your
version of the Places SDK for Android:
- Places SDK for Android (New): Returns the strings defined by Table A and Table B shown on Place Types (New), including all the added place types added in version 3.3.0.
- Places SDK for Android: Returns the enums defined by
Place.Types
, which does not include the new types added in version 3.3.0.
To learn the key differences between the two SDK versions, see Choose your SDK version.
Access place reviews
The Places SDK for Android (New) adds the
Review
class, which contains a review of a place. The Place
object can contain up to five
reviews.
The Review
class can also contain an attribution and an author attribution. If you
display the review in your app, then you must also display any attribution or author attribution.
For more information, see Display a review.
To populate the Place
object with reviews, you must:
- Enable the new SDK when you Set up your Google Cloud project.
- Initialize the new SDK within an activity or fragment.
- Include
Place.Field.REVIEWS
in the field list of the place details request. - Call
PlacesClient.fetchPlace()
. The reviews field is not supported byPlacesClient.findCurrentPlace()
. - Use the
Place.getReviews()
method to access the reviews data field in thePlace
object.
Access place name language code
The existing Place.getName()
method returns a text string containing the name of a place. To populate the Place
object with the place name, you must include the Place.Field.NAME
in the field list of
the place details request.
The Place
object now contains the language code for the name string. To
populate the Place
object with language code, you must:
- Enable the new SDK when you Set up your Google Cloud project.
- Initialize the new SDK within an activity or fragment.
- Include the
Place.Field.NAME
in the field list of the request. This value configures response to include both the place name and language code in thePlace
object. - Call
PlacesClient.fetchPlace()
.PlacesClient.findCurrentPlace()
does not support the language code field. - Use the
Place.getNameLanguageCode()
method to access the language code field in thePlace
object.
Set region code in version 3.3.0
Places SDK for Android (New) adds the region code request parameter to Place Details. The region code is used to format the response, specified as a two-character CLDR code value. This parameter can also have a bias effect on the search results. There is no default value. You must enable the new SDK to set the region code.
If the country name of the address field in the response matches the region code, the country code is omitted from address.
Most CLDR codes are identical to ISO 3166-1 codes, with some notable exceptions. For example, the United Kingdom's ccTLD is "uk" (.co.uk) while its ISO 3166-1 code is "gb" (technically for the entity of "The United Kingdom of Great Britain and Northern Ireland"). The parameter can affect results based on applicable law.
Get a place by ID
A place ID is a textual identifier that uniquely identifies a place. In
the Places SDK for Android, you can retrieve the ID of a place by calling
Place.getId()
.
The
Place Autocomplete service
also returns a place ID for each place that matches the supplied search query
and filter. You can store the place ID and use it to retrieve the
Place
object again later.
To get a place by ID, call
PlacesClient.fetchPlace()
,
passing a FetchPlaceRequest
.
The API returns a
FetchPlaceResponse
in a
Task
.
The
FetchPlaceResponse
contains a
Place
object matching the supplied place ID.
The following code example shows calling fetchPlace()
to
get details for the specified place.
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. } });
Get open status
The PlacesClient.isOpen(IsOpenRequest request)
method returns an IsOpenResponse
object indicating whether the place is
currently open based on the time specified in the call.
This method takes a single argument of type IsOpenRequest
that contains:
- A
Place
object, or a string specifying a place ID. - An optional time value specifying the time in milliseconds from 1970-01-01T00:00:00Z. If no time is specified, the default is now.
This method requires that the following fields exist in the Place
object:
Place.Field.BUSINESS_STATUS
Place.Field.CURRENT_OPENING_HOURS
Place.Field.OPENING_HOURS
Place.Field.UTC_OFFSET
If these fields are not provided in the Place
object, or if you pass a place ID,
the method uses
PlacesClient.fetchPlace()
to fetch them. For more information on creating the Place object with the necessary fields,
see Place details.
The following example determines if a place is currently open. In this example, you only pass
the place ID to 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()); // ...
The next example shows calling isOpen()
where you pass a Place
object.
The Place
object must contain a valid 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()); // ... }); // ...
Display attributions in your app
When your app displays place information, including place reviews, the app must also display any attributions. For more information, see attributions.
More about place IDs
The place ID used in the Places SDK for Android is the same identifier as used in the Places API. Each place ID can refer to only one place, but a single place can have more than one place ID. There are other circumstances which may cause a place to get a new place ID. For example, this may happen if a business moves to a new location.
When you request a place by specifying a place ID, you can be confident that you will always receive the same place in the response (if the place still exists). Note, however, that the response may contain a place ID that is different from the one in your request.
For more information, see the place ID overview.