**European Economic Area (EEA) developers**

> [!NOTE]
> If your billing address is in the European Economic Area, effective on 8 July 2025, the [Google Maps Platform EEA Terms of Service](https://cloud.google.com/terms/maps-platform/eea) will apply to your use of the Services. Functionality varies by region. [Learn more](https://developers.google.com/maps/comms/eea/faq.md.txt).

> [!NOTE]
> This product is in [Legacy status](https://developers.google.com/maps/legacy.md.txt). As of October 2026, Places API (Legacy) can no longer be enabled for new Google Cloud projects. Existing projects remain fully supported. For new features and improved performance, [migrate
> to Places API (New)](https://developers.google.com/maps/documentation/places/android-sdk/legacy/migrate-overview).

The Places SDK for Android (Legacy) 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`](https://developers.google.com/maps/documentation/places/android-sdk/legacy/reference/com/google/android/libraries/places/api/model/Place)
object provides information about a specific place. You can get hold of a
[`Place`](https://developers.google.com/maps/documentation/places/android-sdk/legacy/reference/com/google/android/libraries/places/api/model/Place)
object by calling
[`PlacesClient.fetchPlace()`](https://developers.google.com/maps/documentation/places/android-sdk/legacy/reference/com/google/android/libraries/places/api/net/PlacesClient#fetchPlace(com.google.android.libraries.places.api.net.FetchPlaceRequest))
-- See the guide to
[getting a place by ID](https://developers.google.com/maps/documentation/places/android-sdk/legacy/place-details.md.txt#get-place).
[Video](https://www.youtube.com/watch?v=5iE4kqbEKoY)

When you request a place, you must specify which place data to return. To do this, pass a list of
[Place.Field](https://developers.google.com/maps/documentation/places/android-sdk/legacy/reference/com/google/android/libraries/places/api/model/Place.Field)
values specifying the data to return. This list is an important consideration because it affects the
[cost for each request](https://developers.google.com/maps/documentation/places/android-sdk/legacy/usage-and-billing).

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 won't be present in the result.

The following example passes a list of three
[Place.Field](https://developers.google.com/maps/documentation/places/android-sdk/legacy/reference/com/google/android/libraries/places/api/model/Place.Field) values
to specify the data returned by a request:

### Kotlin

```kotlin
// Specify the fields to return.
val placeFields = listOf(Place.Field.DISPLAY_NAME, Place.Field.RATING)
```

### Java

```java
// Specify the fields to return.
final List<Place.Field> placeFields = Arrays.asList(Place.Field.DISPLAY_NAME, Place.Field.RATING);
  
```

### 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.

> [!NOTE]
> For a complete list of all methods, see the [`Place`](https://developers.google.com/maps/documentation/places/android-sdk/legacy/reference/com/google/android/libraries/places/api/model/Place) API reference.

- `getAddress()` -- The place's address, in human-readable format.
- `getAddressComponents()` -- A `List` 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. Don't use these components for address formatting; instead, call `getAddress()`, 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()` -- The `OpeningHours`
  of the place. Call `OpeningHours.getWeekdayText()` to return a
  list of strings that represent opening and closing hours for each day of
  the week. Call `OpeningHours.getPeriods()` to return a list of
  `period` objects with more detailed information that is
  equivalent to the data provided by `getWeekdayText()`.

  > [!NOTE]
  > **Note:** If a place is always open, the time period is represented as Sunday at midnight, and the `closeEvent` is null.

  The `Place` object also contains the
  [`getCurrentOpeningHours()`](https://developers.google.com/maps/documentation/places/android-sdk/legacy/reference/com/google/android/libraries/places/api/model/Place#getCurrentOpeningHours())
  method which returns a place's hours of operation over the next seven days, and
  [`getSecondaryOpeningHours()`](https://developers.google.com/maps/documentation/places/android-sdk/legacy/reference/com/google/android/libraries/places/api/model/Place#getSecondaryOpeningHours())
  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 both `Place.Field.UTC_OFFSET` and
  `Place.Field.OPENING_HOURS` are available. To ensure accurate
  results, request the `Place.Field.BUSINESS_STATUS` and
  `Place.Field.UTC_OFFSET` fields in your original place request.
  If not requested, it is assumed that the business is operational.
  See [this video](https://youtu.be/vAK5o8h8C28) for how to use
  `isOpen` with Place Details.

  > [!NOTE]
  > **Note:** This method is deprecated. Instead use [`PlacesClient.isOpen(IsOpenRequest request)`](https://developers.google.com/maps/documentation/places/android-sdk/legacy/reference/com/google/android/libraries/places/api/net/PlacesClient#isOpen(com.google.android.libraries.places.api.net.IsOpenRequest)). For more, see [Get open status](https://developers.google.com/maps/documentation/places/android-sdk/legacy/place-details.md.txt#get-open).

Some examples:

### Kotlin

```kotlin
        val name = place.displayName
        val address = place.formattedAddress
        val location = place.location

      
```

### Java

```java
                    final CharSequence name = place.getDisplayName();
                    final CharSequence address = place.getFormattedAddress();
                    final LatLng location = place.getLocation();

      
```

## 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()`](https://developers.google.com/maps/documentation/places/android-sdk/legacy/reference/com/google/android/libraries/places/api/model/Place#getId()).
The
[Place Autocomplete](https://developers.google.com/maps/documentation/places/android-sdk/legacy/autocomplete.md.txt) 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`](https://developers.google.com/maps/documentation/places/android-sdk/legacy/reference/com/google/android/libraries/places/api/model/Place)
object again later.

To get a place by ID, call
[`PlacesClient.fetchPlace()`](https://developers.google.com/maps/documentation/places/android-sdk/reference/com/google/android/libraries/places/api/net/PlacesClient.md.txt#fetchPlace(com.google.android.libraries.places.api.net.FetchPlaceRequest)),
passing a [`FetchPlaceRequest`](https://developers.google.com/maps/documentation/places/android-sdk/reference/com/google/android/libraries/places/api/net/FetchPlaceRequest.md.txt).

The API returns a
[`FetchPlaceResponse`](https://developers.google.com/maps/documentation/places/android-sdk/reference/com/google/android/libraries/places/api/net/FetchPlaceResponse.md.txt)
in a
[`Task`](https://developers.google.com/android/reference/com/google/android/gms/tasks/Task.md.txt).
The
[`FetchPlaceResponse`](https://developers.google.com/maps/documentation/places/android-sdk/reference/com/google/android/libraries/places/api/net/FetchPlaceResponse.md.txt)
contains a
[`Place`](https://developers.google.com/maps/documentation/places/android-sdk/reference/com/google/android/libraries/places/api/model/Place.md.txt)
object matching the supplied place ID.

The following code example shows calling `fetchPlace()` to
get details for the specified place.

### Kotlin

```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

```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.
                    }
                });

      
```

> [!NOTE]
> **Note:** For more information on initializing `PlacesClient`, see [Initialize the Places API client](https://developers.google.com/maps/documentation/places/android-sdk/config.md.txt#connect-client).

> [!NOTE]
> You can use a [CancellationToken](https://developers.google.com/android/reference/com/google/android/gms/tasks/CancellationToken.md.txt)
> to attempt to cancel a request to any of the request classes (for example,
> `FetchPlaceRequest`). Cancellation is done on a best-effort basis.
> Once a cancellation request is issued, no response will be returned.
> **Issuing a cancellation token does NOT guarantee that a particular request
> will be cancelled, and you may still be charged for the request even if no
> response is returned**.

## Get open status

The [`PlacesClient.isOpen(IsOpenRequest request)`](https://developers.google.com/maps/documentation/places/android-sdk/legacy/reference/com/google/android/libraries/places/api/net/PlacesClient#isOpen(com.google.android.libraries.places.api.net.IsOpenRequest))
method returns an [`IsOpenResponse`](https://developers.google.com/maps/documentation/places/android-sdk/legacy/reference/com/google/android/libraries/places/api/net/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`](https://developers.google.com/maps/documentation/places/android-sdk/legacy/reference/com/google/android/libraries/places/api/net/IsOpenRequest) that contains:

- A [`Place`](https://developers.google.com/maps/documentation/places/android-sdk/legacy/reference/com/google/android/libraries/places/api/model/Place) object, or a string specifying a place ID.

  > [!NOTE]
  > **Note:** The `Place` object must contain a valid 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()`](https://developers.google.com/maps/documentation/places/android-sdk/legacy/reference/com/google/android/libraries/places/api/net/PlacesClient#fetchPlace(com.google.android.libraries.places.api.net.FetchPlaceRequest))
to fetch them. For more information on creating the Place object with the necessary fields,
see [Place details](https://developers.google.com/maps/documentation/places/android-sdk/legacy/place-details.md.txt#place-details).

> [!NOTE]
> **Note:** The Places [Basic Data SKU](https://developers.google.com/maps/documentation/places/android-sdk/legacy/usage-and-billing#basic-data-ess-sku) is charged for calls to `fetchPlace()` for `Place.Field.UTC_OFFSET` and `Place.Field.BUSINESS_STATUS`. The Places [Contact Data SKU](https://developers.google.com/maps/documentation/places/android-sdk/legacy/usage-and-billing#contact-data-ent-sku) is charged for calls to `fetchPlace()` for `Place.Field.CURRENT_OPENING_HOURS` and `Place.Field.OPENING_HOURS`.

The following example determines if a place is currently open. In this example, you only pass
the place ID to `isOpen()`:

### Kotlin

```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

```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());
        });

      
```

The next example shows calling `isOpen()` where you pass a `Place` object.
The `Place` object must contain a valid place ID:

### Kotlin

```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

```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());

      
```

## 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](https://developers.google.com/maps/documentation/places/android-sdk/legacy/attributions#other_attribution_requirements).

## More about place IDs

The place ID used in the Places SDK for Android (Legacy) is the same identifier
as used in the [Places API (Legacy)](https://developers.google.com/maps/documentation/places/web-service).
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](https://developers.google.com/maps/documentation/places/android-sdk/legacy/place-id).