このガイドでは、Places 互換性ライブラリと Places SDK for Android の新しいスタンドアロン バージョンとの違いについて説明します。 このガイドでは、Places SDK for Android の新しいスタンドアロン バージョンに移行せずに、プレイス互換性ライブラリを使用している場合に、Places SDK for Android の新しいバージョンを使用するようにプロジェクトを更新する方法について説明します。
バージョン 2.6.0 以降の Places SDK for Android の機能やバグ修正にアクセスする唯一の方法は、Places SDK for Android を使用することです。互換性ライブラリから新しい Places SDK for Android にできるだけ早くアップデートすることをおすすめします。
変更内容
主な変更点は次のとおりです。
- 新しいバージョンの Places SDK for Android は、静的クライアント ライブラリとして配布されています。2019 年 1 月まで、Places SDK for Android は Google Play 開発者サービスを通じて提供されていました。以降、新しい Places SDK for Android への移行を容易にするため、Places 互換ライブラリが提供されていました。
- まったく新しいメソッドがあります。
- Place Details を返すメソッドでフィールド マスクがサポートされるようになりました。フィールド マスクを使用すると、返す場所データの種類を指定できます。
- エラーの報告に使用するステータス コードが改善されました。
- オートコンプリートがセッション トークンをサポートするようになりました。
- Place Picker は利用できなくなりました。
プレイス互換性ライブラリについて
スタンドアロンの Places SDK for Android のバージョン 1.0 がリリースされた 2019 年 1 月、Google は、非推奨になった Google Play 開発者サービスの Places SDK for Android(com.google.android.gms:play-services-places
)からの移行をサポートする互換性ライブラリを提供しています。
デベロッパーがスタンドアロン SDK で新しい名前を使用するようにコードを移行するまで、Google Play 開発者サービス バージョンを対象とする API 呼び出しは、新しいスタンドアロン バージョンにリダイレクトおよび翻訳するために、この互換性ライブラリが一時的に提供されました。バージョン 1.0 からバージョン 2.6.0 にリリースされた Places SDK for Android のバージョンごとに、同等の機能を提供するプレイスの互換性ライブラリのバージョンがリリースされています。
プレイス互換性ライブラリのサポート終了とサポート終了
Places SDK for Android の互換性ライブラリの全バージョンは、2022 年 3 月 31 日をもって非推奨となりました。バージョン 2.6.0 は、プレイス互換性ライブラリの最後のバージョンです。バージョン 2.6.0 以降の Places SDK for Android の機能やバグ修正にアクセスする唯一の方法は、Places SDK for Android を使用することです。
バージョン 2.6.0 以降のリリースの新機能と重要なバグの修正を利用するには、Places SDK for Android に移行することをおすすめします。現在、互換性ライブラリを使用している場合は、下記の Places SDK for Android をインストールするの手順に沿って、Places SDK for Android に移行してください。
クライアント ライブラリをインストールする
新しいバージョンの Places SDK for Android は、静的クライアント ライブラリとして配布されています。
Maven を使用して、Places SDK for Android を Android Studio プロジェクトに追加します。
現在プレイス互換性ライブラリを使用している場合:
dependencies
セクションの次の行を置き換えます。implementation 'com.google.android.libraries.places:places-compat:X.Y.Z'
この行を使用して、Places SDK for Android に切り替えます。
implementation 'com.google.android.libraries.places:places:3.1.0'
現在、Places Service for Android の Play 開発者サービス バージョンを使用している場合:
dependencies
セクションの次の行を置き換えます。implementation 'com.google.android.gms:play-services-places:X.Y.Z'
この行を使用して、Places SDK for Android に切り替えます。
implementation 'com.google.android.libraries.places:places:3.1.0'
Gradle プロジェクトを同期します。
アプリケーション プロジェクトの
minSdkVersion
を 16 以上に設定します。「Powered by Google」のアセットを更新するには:
@drawable/powered_by_google_light // OLD @drawable/places_powered_by_google_light // NEW @drawable/powered_by_google_dark // OLD @drawable/places_powered_by_google_dark // NEW
アプリを作成します。Places SDK for Android への変換が原因でビルドエラーが表示される場合は、以下のセクションで解決方法を確認してください。
新しい Places SDK クライアントを初期化する
次の例のように、新しい Places SDK クライアントを初期化します。
// Add an import statement for the client library.
import com.google.android.libraries.places.api.Places;
...
// Initialize Places.
Places.initialize(getApplicationContext(), apiKey);
// Create a new Places client instance.
PlacesClient placesClient = Places.createClient(this);
ステータス コード
QPS 制限エラーのステータス コードが変更されました。QPS 制限エラーが PlaceStatusCodes.OVER_QUERY_LIMIT
を介して返されるようになりました。QPD の上限がなくなりました。
次のステータス コードが追加されました。
REQUEST_DENIED
: リクエストが拒否されました。これには次の理由が考えられます。- API キーが指定されていません。
- 無効な API キーが指定された。
- Places API が Cloud Console で有効になっていません。
- API キーが提供されましたが、キーの制限が正しくありません。
INVALID_REQUEST
- 引数がないか、無効なため、リクエストが無効です。NOT_FOUND
- 指定されたリクエストに対する結果が見つかりませんでした。
新しいメソッド
新しいバージョンの Places SDK for Android には、一貫性を保つように設計されたまったく新しいメソッドが導入されています。新しいメソッドはすべて、次のとおりです。
- エンドポイントは
get
動詞を使用しなくなりました。 - リクエスト オブジェクトとレスポンス オブジェクトは、対応するクライアント メソッドと同じ名前を共有します。
- リクエスト オブジェクトにビルダーが追加されました。必須パラメータはリクエスト ビルダー パラメータとして渡されます。
- バッファは使用されなくなりました。
このセクションでは、新しいメソッドの概要と仕組みを説明します。
ID で場所を取得する
fetchPlace()
を使用して、特定の場所の詳細を取得します。fetchPlace()
は getPlaceById()
と同様に機能します。
場所を取得する手順は次のとおりです。
fetchPlace()
を呼び出して、場所 ID を指定するFetchPlaceRequest
オブジェクトと、返す場所データを指定するフィールドのリストを渡します。// Define a Place ID. String placeId = "INSERT_PLACE_ID_HERE"; // Specify the fields to return. List<Place.Field> placeFields = Arrays.asList(Place.Field.ID, Place.Field.NAME); // Construct a request object, passing the place ID and fields array. FetchPlaceRequest request = FetchPlaceRequest.builder(placeId, placeFields) .build();
addOnSuccessListener()
を呼び出してFetchPlaceResponse
を処理します。Place
の結果が 1 つ返されます。// Add a listener to handle the response. placesClient.fetchPlace(request).addOnSuccessListener((response) -> { Place place = response.getPlace(); Log.i(TAG, "Place found: " + place.getName()); }).addOnFailureListener((exception) -> { if (exception instanceof ApiException) { ApiException apiException = (ApiException) exception; int statusCode = apiException.getStatusCode(); // Handle error with given status code. Log.e(TAG, "Place not found: " + exception.getMessage()); } });
場所の写真を取得する
場所の写真を取得するには、fetchPhoto()
を使用します。fetchPhoto()
は場所の写真を返します。写真をリクエストするためのパターンが簡素化されました。Place
オブジェクトから直接 PhotoMetadata
をリクエストできるようになりました。別個のリクエストは不要になりました。写真の最大幅または高さは 1,600 ピクセルです。fetchPhoto()
は getPhoto()
と同じように機能します。
場所の写真を取得する手順は次のとおりです。
fetchPlace()
への通話を設定します。リクエストには必ずPHOTO_METADATAS
フィールドを含めてください。List<Place.Field> fields = Arrays.asList(Place.Field.PHOTO_METADATAS);
Place オブジェクトを取得します(この例では
fetchPlace()
ですが、findCurrentPlace()
も使用できます)。FetchPlaceRequest placeRequest = FetchPlaceRequest.builder(placeId, fields).build();
OnSuccessListener
を追加してFetchPlaceResponse
の結果Place
から写真メタデータを取得し、得られた写真メタデータを使用してビットマップと帰属テキストを取得します。placesClient.fetchPlace(placeRequest).addOnSuccessListener((response) -> { Place place = response.getPlace(); // Get the photo metadata. PhotoMetadata photoMetadata = place.getPhotoMetadatas().get(0); // Get the attribution text. String attributions = photoMetadata.getAttributions(); // Create a FetchPhotoRequest. FetchPhotoRequest photoRequest = FetchPhotoRequest.builder(photoMetadata) .setMaxWidth(500) // Optional. .setMaxHeight(300) // Optional. .build(); placesClient.fetchPhoto(photoRequest).addOnSuccessListener((fetchPhotoResponse) -> { Bitmap bitmap = fetchPhotoResponse.getBitmap(); imageView.setImageBitmap(bitmap); }).addOnFailureListener((exception) -> { if (exception instanceof ApiException) { ApiException apiException = (ApiException) exception; int statusCode = apiException.getStatusCode(); // Handle error with given status code. Log.e(TAG, "Place not found: " + exception.getMessage()); } }); });
ユーザーの現在地から場所を見つける
findCurrentPlace()
を使用して、ユーザーのデバイスの現在地を特定します。findCurrentPlace()
は、ユーザーのデバイスが近くにある可能性が高い場所を示す PlaceLikelihood
のリストを返します。findCurrentPlace()
は getCurrentPlace()
と同じように機能します。
ユーザーのデバイスの現在地を取得する手順は次のとおりです。
アプリが
ACCESS_FINE_LOCATION
権限とACCESS_WIFI_STATE
権限をリクエストしていることを確認します。ユーザーがデバイスの位置情報にアクセスする権限を付与する。詳しくは、アプリの権限をリクエストするをご覧ください。返す場所データ型のリストを含む
FindCurrentPlaceRequest
を作成します。// Use fields to define the data types to return. List<Place.Field> placeFields = Arrays.asList(Place.Field.NAME); // Use the builder to create a FindCurrentPlaceRequest. FindCurrentPlaceRequest request = FindCurrentPlaceRequest.builder(placeFields).build();
findCurrentPlace を呼び出してレスポンスを処理し、最初にユーザーがデバイスの位置情報を使用する権限が付与されていることを確認します。
// Call findCurrentPlace and handle the response (first check that the user has granted permission). if (ContextCompat.checkSelfPermission(this, ACCESS_FINE_LOCATION) == PackageManager.PERMISSION_GRANTED) { placesClient.findCurrentPlace(request).addOnSuccessListener(((response) -> { for (PlaceLikelihood placeLikelihood : response.getPlaceLikelihoods()) { Log.i(TAG, String.format("Place '%s' has likelihood: %f", placeLikelihood.getPlace().getName(), placeLikelihood.getLikelihood())); textView.append(String.format("Place '%s' has likelihood: %f\n", placeLikelihood.getPlace().getName(), placeLikelihood.getLikelihood())); } })).addOnFailureListener((exception) -> { if (exception instanceof ApiException) { ApiException apiException = (ApiException) exception; Log.e(TAG, "Place not found: " + apiException.getStatusCode()); } }); } else { // A local method to request required permissions; // See https://developer.android.com/training/permissions/requesting getLocationPermission(); }
オートコンプリート候補の検索
findAutocompletePredictions()
を使用して、ユーザーの検索クエリに応じて場所の予測を返します。
findAutocompletePredictions()
は getAutocompletePredictions()
と同じように機能します。
次の例では、findAutocompletePredictions()
を呼び出しています。
// Create a new token for the autocomplete session. Pass this to FindAutocompletePredictionsRequest,
// and once again when the user makes a selection (for example when calling fetchPlace()).
AutocompleteSessionToken token = AutocompleteSessionToken.newInstance();
// Create a RectangularBounds object.
RectangularBounds bounds = RectangularBounds.newInstance(
new LatLng(-33.880490, 151.184363),
new LatLng(-33.858754, 151.229596));
// Use the builder to create a FindAutocompletePredictionsRequest.
FindAutocompletePredictionsRequest request = FindAutocompletePredictionsRequest.builder()
// Call either setLocationBias() OR setLocationRestriction().
.setLocationBias(bounds)
//.setLocationRestriction(bounds)
.setCountry("au")
.setTypesFilter(Arrays.asList(PlaceTypes.ADDRESS))
.setSessionToken(token)
.setQuery(query)
.build();
placesClient.findAutocompletePredictions(request).addOnSuccessListener((response) -> {
for (AutocompletePrediction prediction : response.getAutocompletePredictions()) {
Log.i(TAG, prediction.getPlaceId());
Log.i(TAG, prediction.getPrimaryText(null).toString());
}
}).addOnFailureListener((exception) -> {
if (exception instanceof ApiException) {
ApiException apiException = (ApiException) exception;
Log.e(TAG, "Place not found: " + apiException.getStatusCode());
}
});
セッション トークン
セッション トークンは、請求対象のユーザー検索のクエリ フェーズと選択フェーズを個別のセッションにグループ化します。すべてのオートコンプリート セッションでセッション トークンを使用することをおすすめします。セッションは、ユーザーが検索語句を入力し始めたときに開始され、場所を選択したときに終了します。各セッションには複数のクエリがあり、その後に場所が 1 つずつ表示されます。セッションが終了すると、トークンは無効になります。アプリはセッションごとに新しいトークンを生成する必要があります。
フィールド マスク
Place Details を返すメソッドでは、リクエストごとに返される場所データの種類を指定する必要があります。これにより、実際に使用するデータのみをリクエストし、料金を支払うことができます。
返すデータ型を指定するには、次の例に示すように、FetchPlaceRequest
に Place.Field
の配列を渡します。
// Include address, ID, and phone number.
List<Place.Field> placeFields = Arrays.asList(Place.Field.ADDRESS,
Place.Field.ID,
Place.Field.PHONE_NUMBER);
以下のフィールドのうち 1 つ以上を使用できます。
Place.Field.ADDRESS
Place.Field.ID
Place.Field.LAT_LNG
Place.Field.NAME
Place.Field.OPENING_HOURS
Place.Field.PHONE_NUMBER
Place.Field.PHOTO_METADATAS
Place.Field.PLUS_CODE
Place.Field.PRICE_LEVEL
Place.Field.RATING
Place.Field.TYPES
Place.Field.USER_RATINGS_TOTAL
Place.Field.VIEWPORT
Place.Field.WEBSITE_URI
詳しくは、Places Data SKU をご覧ください。
Place Picker と Autocomplete の更新
このセクションでは、Places ウィジェット(Place Picker と Autocomplete)の変更点について説明します。
プログラマティック オートコンプリート
オートコンプリートに変更が加えられました。
PlaceAutocomplete
の名前がAutocomplete
に変更されました。PlaceAutocomplete.getPlace
の名前がAutocomplete.getPlaceFromIntent
に変更されました。PlaceAutocomplete.getStatus
の名前がAutocomplete.getStatusFromIntent
に変更されました。
PlaceAutocomplete.RESULT_ERROR
の名前がAutocompleteActivity.RESULT_ERROR
に変更されました(オートコンプリート フラグメントのエラー処理は変更されていません)。
Place Picker
Place Picker は 2019 年 1 月 29 日に非推奨となりました。2019 年 7 月 29 日にオフになり、ご利用いただけなくなりました。使用するとエラー メッセージが表示されます。新しい SDK は、Place Picker をサポートしていません。
Autocomplete ウィジェット
オートコンプリート ウィジェットが更新されました。
- すべてのクラスから
Place
プレフィックスを削除しました。 - セッション トークンのサポートを追加しました。ウィジェットはバックグラウンドで自動的にトークンを管理します。
- フィールド マスクのサポートが追加されました。フィールド マスクを使用すると、ユーザーが選択した後に返す場所データのタイプを選択できます。
以下のセクションでは、オートコンプリート ウィジェットをプロジェクトに追加する方法を説明します。
AutocompleteFragment
を埋め込む
オートコンプリート フラグメントを追加する手順は次のとおりです。
次の例に示すように、アクティビティの XML レイアウトにフラグメントを追加します。
<fragment android:id="@+id/autocomplete_fragment" android:layout_width="match_parent" android:layout_height="wrap_content" android:name= "com.google.android.libraries.places.widget.AutocompleteSupportFragment" />
Autocomplete ウィジェットをアクティビティに追加する手順は次のとおりです。
Places
を初期化し、アプリケーション コンテキストと API キーを渡します。AutocompleteSupportFragment
を初期化します。setPlaceFields()
を呼び出して、取得する場所データのタイプを指定します。- 結果を処理するとともに、発生する可能性のあるエラーを処理する
PlaceSelectionListener
を追加します。
次の例は、アクティビティにオートコンプリート ウィジェットを追加する方法を示しています。
/** * Initialize Places. For simplicity, the API key is hard-coded. In a production * environment we recommend using a secure mechanism to manage API keys. */ if (!Places.isInitialized()) { Places.initialize(getApplicationContext(), "YOUR_API_KEY"); } // Initialize the AutocompleteSupportFragment. AutocompleteSupportFragment autocompleteFragment = (AutocompleteSupportFragment) getSupportFragmentManager().findFragmentById(R.id.autocomplete_fragment); autocompleteFragment.setPlaceFields(Arrays.asList(Place.Field.ID, Place.Field.NAME)); autocompleteFragment.setOnPlaceSelectedListener(new PlaceSelectionListener() { @Override public void onPlaceSelected(Place place) { // TODO: Get info about the selected place. Log.i(TAG, "Place: " + place.getName() + ", " + place.getId()); } @Override public void onError(Status status) { // TODO: Handle the error. Log.i(TAG, "An error occurred: " + status); } });
インテントを使用してオートコンプリート アクティビティを起動する
Places
を初期化し、アプリのコンテキストと API キーを渡すAutocomplete.IntentBuilder
を使用してインテントを作成し、目的のPlaceAutocomplete
モード(全画面表示またはオーバーレイ)を渡します。インテントはstartActivityForResult
を呼び出して、インテントを識別するリクエスト コードを渡す必要があります。onActivityResult
コールバックをオーバーライドして、選択された場所を受け取ります。
次の例は、インテントを使用してオートコンプリートを起動し、結果を処理する方法を示しています。
/**
* Initialize Places. For simplicity, the API key is hard-coded. In a production
* environment we recommend using a secure mechanism to manage API keys.
*/
if (!Places.isInitialized()) {
Places.initialize(getApplicationContext(), "YOUR_API_KEY");
}
...
// Set the fields to specify which types of place data to return.
List<Place.Field> fields = Arrays.asList(Place.Field.ID, Place.Field.NAME);
// Start the autocomplete intent.
Intent intent = new Autocomplete.IntentBuilder(
AutocompleteActivityMode.FULLSCREEN, fields)
.build(this);
startActivityForResult(intent, AUTOCOMPLETE_REQUEST_CODE);
...
/**
* Override the activity's onActivityResult(), check the request code, and
* do something with the returned place data (in this example its place name and place ID).
*/
@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
if (requestCode == AUTOCOMPLETE_REQUEST_CODE) {
if (resultCode == RESULT_OK) {
Place place = Autocomplete.getPlaceFromIntent(data);
Log.i(TAG, "Place: " + place.getName() + ", " + place.getId());
} else if (resultCode == AutocompleteActivity.RESULT_ERROR) {
// TODO: Handle the error.
Status status = Autocomplete.getStatusFromIntent(data);
Log.i(TAG, status.getStatusMessage());
} else if (resultCode == RESULT_CANCELED) {
// The user canceled the operation.
}
}
}
Place Picker はご利用いただけなくなりました
Place Picker は 2019 年 1 月 29 日に非推奨となりました。2019 年 7 月 29 日にオフになり、ご利用いただけなくなりました。使用するとエラー メッセージが表示されます。新しい SDK は、Place Picker をサポートしていません。