Place Details

Places SDK for Android 為應用程式提供豐富的地點相關資訊,包括地點的名稱和地址、經緯度座標指定的地理位置,以及地點類型 (例如夜店、寵物店、博物館等)。如要存取特定地點的這項資訊,可以使用地點 ID,這是可唯一識別地點的固定 ID。

地點詳細資訊

Place 物件可提供特定地點的相關資訊。您可以透過下列方式保留 Place 物件:

提出地點要求時,您必須指定要傳回的地點資料。方法是傳送 Place.Field 值清單,指定要傳回的資料。由於這份清單會影響每次要求的費用,因此相當重要。

地點資料結果不可為空白,因此系統只會傳回含有資料的地點結果 (例如,如果要求的地點沒有相片,結果中就不會顯示 photos 欄位)。

以下範例會傳遞三個 Place.Field 值的清單,指定要求傳回的資料:

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 List placeFields = Arrays.asList(Place.Field.NAME, Place.Field.RATING, Place.Field.OPENING_HOURS);

存取地點物件資料欄位

取得 Place 物件後,請使用物件的方法存取要求中指定的資料欄位。如果 Place 物件中缺少該欄位,相關方法會傳回空值。以下列舉幾個可用方法的範例。如需所有方法的完整清單,請參閱 Place API 參考資料。

  • getAddress():地點的地址 (清楚易懂的格式)。
  • getAddressComponents() – 這個地點的地址元件 List。這些元件是用於擷取地點地址的結構化資訊,例如尋找地點所在的城市。請勿使用這些元件設定地址格式,請改為呼叫 getAddress(),以取得本地化格式的地址。
  • getId():地點的文字 ID。請參閱本頁面其餘部分,進一步瞭解地點 ID。
  • getLatLng():地點的地理位置,以經緯度座標的形式指定。
  • getName() - 地點的名稱。
  • getOpeningHours():地點的 OpeningHours。呼叫 OpeningHours.getWeekdayText() 即可傳回字串清單,代表一週內每天的營業時間和打烊時間。呼叫 OpeningHours.getPeriods() 可傳回 period 物件清單,其中包含更詳細的資訊,等同於 getWeekdayText() 提供的資料。

    Place 物件還包含 getCurrentOpeningHours() 方法,會傳回未來七天內的地點營業時間;而 getSecondaryOpeningHours(),則會傳回地點未來七天內的次要營業時間。

  • isOpen():表示地點目前營業的布林值。如果沒有指定時間,目前為預設值。只有在 Place.Field.UTC_OFFSETPlace.Field.OPENING_HOURS 都可用時,系統才會傳回 isOpen。為確保結果正確無誤,請在原始地點要求中要求 Place.Field.BUSINESS_STATUSPlace.Field.UTC_OFFSET 欄位。如未要求,系統會假設商家確實正常運作。如要瞭解如何搭配 Place Details 使用 isOpen,請觀看這部影片

以下是一些簡單的範例:

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

      

存取 3.3.0 版中新增的地點資料

Places SDK for Android 3.3.0 版新增資料至 Place

  • 地點類型:與地點相關聯的新類型值。
  • 評論:地點最多五則評論。
  • 名稱語言代碼:地點名稱的語言代碼。

以下各節將說明如何存取這項新資料。

存取新的地點類型

每個地點都可以有一或多個相關聯的 type 值。Places SDK for Android 3.3.0 版新增了許多類型值。如需完整清單,請參閱「展開的地點類型」一文。

在 Places SDK for Android 3.2.0 以下版本中,您可以使用 Place.getTypes() 方法存取與地點相關聯的類型值。Place.getTypes() 會以 Place.Types 定義的列舉值傳回類型清單。

Place.getPlaceTypes() 方法會以字串值清單的形式傳回類型值。傳回的值取決於您的 Places SDK for Android 版本:

  • Places SDK for Android (新推出):傳回由地點類型 (New) 上顯示的表格 A 和表格 B 所定義的字串,包括 3.3.0 版中新增的所有地點類型。
  • Places SDK for Android:傳回 Place.Types 定義的列舉,但其中不包含 3.3.0 版中新增的新類型。

如要瞭解兩個 SDK 版本之間的主要差異,請參閱「選擇 SDK 版本」。

存取地點評論

Places SDK for Android (新版) 新增 Review 類別,其中包含地點的評論。Place 物件最多可包含五則評論。

Review 類別也可以包含作者資訊和作者作者資訊。如果您在應用程式中顯示評論,則必須一併顯示任何作者資訊或作者資訊。詳情請參閱「顯示評論」一文。

如要在 Place 物件中填入評論,您必須:

  1. 設定 Google Cloud 專案時啟用新的 SDK。
  2. 在活動或片段中初始化新的 SDK
  3. 在 Place Details 要求的欄位清單中加入 Place.Field.REVIEWS
  4. 呼叫 PlacesClient.fetchPlace()。 「PlacesClient.findCurrentPlace()」不支援評論欄位。
  5. 使用 Place.getReviews() 方法存取 Place 物件中的評論資料欄位。

存取地點名稱語言代碼

現有的 Place.getName() 方法會傳回包含地點名稱的文字字串。如要在 Place 物件中填入地點名稱,您必須在 Place Details 要求的欄位清單中加入 Place.Field.NAME

Place 物件現在包含名稱字串的語言代碼。如要在 Place 物件中填入語言代碼,您必須:

  1. 設定 Google Cloud 專案時啟用新的 SDK。
  2. 在活動或片段中初始化新的 SDK
  3. 在要求的欄位清單中加入 Place.Field.NAME。這個值會將回應設為在 Place 物件中納入地點名稱和語言代碼。
  4. 呼叫 PlacesClient.fetchPlace()PlacesClient.findCurrentPlace() 不支援語言代碼欄位。
  5. 使用 Place.getNameLanguageCode() 方法存取 Place 物件中的語言代碼欄位。

在 3.3.0 版中設定區碼

Places SDK for Android (新版) 會將區碼要求參數新增至 Place Details。區碼是用來設定回應的格式,指定為 雙字元 CLDR 代碼值。這個參數也會對搜尋結果產生偏誤。 沒有預設值。您必須啟用新的 SDK 才能設定區碼。

如果回應中地址欄位的國家/地區名稱與區碼相符,系統就會省略地址中的國家/地區代碼。

多數 CLDR 代碼與 ISO 3166-1 代碼相同,只有少數例外。舉例來說,英國的 ccTLD 是「uk」(.co.uk),而 ISO 3166-1 代碼卻是「gb」(正式的國名為「大不列顛暨北愛爾蘭聯合王國」)。這個參數可根據適用法律影響結果。

透過 ID 取得地點

地點 ID 是用來識別特定地點的文字 ID,在 Places SDK for Android 中,您可以呼叫 Place.getId() 來擷取地點 ID。Place Autocomplete 服務也會針對與所提供搜尋查詢和篩選器相符的每個地點,傳回地點 ID。您可以儲存地點 ID,日後再用於擷取 Place 物件。

如要依據 ID 取得地點,請呼叫 PlacesClient.fetchPlace() 並傳遞 FetchPlaceRequest

API 會在 Task 中傳回 FetchPlaceResponseFetchPlaceResponse 包含與提供地點 ID 相符的 Place 物件。

以下程式碼範例說明如何呼叫 fetchPlace() 以取得指定地點的詳細資料。

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

      

取得營業狀態

PlacesClient.isOpen(IsOpenRequest request) 方法會傳回 IsOpenResponse 物件,根據呼叫中指定的時間,指出地點目前是否營業中。

這個方法使用 IsOpenRequest 類型的單一引數,其中包含:

  • Place 物件,或指定地點 ID 的字串。
  • 選用的時間值,用於指定 1970-01-01T00:00:00Z 開始的時間 (以毫秒為單位)。如果沒有指定時間,目前為預設值。

如要使用這個方法,Place 物件中必須有下列欄位:

  • Place.Field.BUSINESS_STATUS
  • Place.Field.CURRENT_OPENING_HOURS
  • Place.Field.OPENING_HOURS
  • Place.Field.UTC_OFFSET

如果 Place 物件中未提供這些欄位,或是您傳遞地點 ID,此方法會使用 PlacesClient.fetchPlace() 擷取這些欄位。如要進一步瞭解如何建立包含必要欄位的 Place 物件,請參閱 Place Details

以下範例可判斷地點是否正在營業。在這個範例中,您只將地點 ID 傳遞至 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());
// ...

      

下一個範例顯示呼叫 isOpen() 的位置,也就是您傳遞 Place 物件。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());
            // ...
        });
// ...

      

在應用程式中顯示歸因資訊

當應用程式顯示地點資訊 (包括地點評論) 時,應用程式也必須顯示任何作者資訊。詳情請參閱「歸因」一文。

進一步瞭解地點 ID

Places SDK for Android 中使用的地點 ID 與 Places API 中使用的 ID 相同。每個地點 ID 只能對應一個地點,但一個地點可以有多個地點 ID。在其他情況下,系統可能會導致地點取得新的地點 ID。舉例來說,如果商家搬遷至新地點,就可能發生這種情況。

透過指定地點 ID 要求地點時,您可以放心,回應中一律會收到相同的地點 (如果地點仍然存在)。不過請注意,回應中可能包含的地點 ID 與要求中的地點 ID 不同。

詳情請參閱地點 ID 總覽