このガイドでは、プレイス互換性ライブラリと、新しいスタンドアロン バージョンの Places SDK for Android の変更点について説明します。新しいスタンドアロン バージョンの Places SDK for Android に移行せずに、Places 互換性ライブラリを使用していた場合は、このガイドで、新しいバージョンの 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 への移行を容易にするために、プレイス互換性ライブラリが提供されています。
- まったく新しいメソッドが追加されています。
- 場所の詳細を返すメソッドでフィールド マスクがサポートされるようになりました。フィールド マスクを使用すると、返す場所データの種類を指定できます。
- エラーの報告に使用されるステータス コードが改善されました。
- オートコンプリートでセッション トークンがサポートされるようになりました。
- Place Picker はご利用いただけなくなりました。
プレイス互換性ライブラリについて
2019 年 1 月にスタンドアロンの Places SDK for Android バージョン 1.0 がリリースされた際、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 は、Places 互換ライブラリの最終バージョンです。バージョン 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 を使用して、Android Studio プロジェクトに Android 向け Places SDK を追加します。
現在プレイス互換性ライブラリを使用している場合:
dependencies
セクションの次の行を置き換えます。implementation 'com.google.android.libraries.places:places-compat:X.Y.Z'
この行を Places SDK for Android に切り替えます。
implementation 'com.google.android.libraries.places:places:3.3.0'
現在、Google Play 開発者サービス バージョンの Places SDK for Android を使用している場合:
dependencies
セクションの次の行を置き換えます。implementation 'com.google.android.gms:play-services-places:X.Y.Z'
この行を Places SDK for Android に切り替えます。
implementation 'com.google.android.libraries.places:places:3.3.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 キーが指定されました。
- Cloud コンソールで Places API が有効になっていません。
- 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.DISPLAY_NAME); // Construct a request object, passing the place ID and fields array. FetchPlaceRequest request = FetchPlaceRequest.builder(placeId, placeFields) .build();
addOnSuccessListener()
を呼び出してFetchPlaceResponse
を処理します。単一のPlace
結果が返されます。// 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.DISPLAY_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 つの場所が選択される場合もあります。セッションが終了すると、トークンは無効になります。アプリはセッションごとに新しいトークンを生成する必要があります。
フィールド マスク
プレイス詳細を返すメソッドでは、各リクエストで返すプレイスデータの種類を指定する必要があります。これにより、実際に使用するデータのみをリクエスト(および支払い)できます。
返すデータ型を指定するには、次の例に示すように、FetchPlaceRequest
に Place.Field
の配列を渡します。
// Include address, ID, and phone number.
List<Place.Field> placeFields = Arrays.asList(Place.Field.FORMATTED_ADDRESS,
Place.Field.ID,
Place.Field.INTERNATIONAL_PHONE_NUMBER);
フィールド マスクで使用できるフィールドの一覧については、場所データのフィールド(新規) をご覧ください。
詳しくは、Places Data SKU をご覧ください。
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
接頭辞が削除されました。 - セッション トークンのサポートを追加しました。ウィジェットは、バックグラウンドでトークンを自動的に管理します。
- フィールドマスクのサポートを追加しました。これにより、ユーザーが選択した後に返す場所データの種類を選択できます。
以降のセクションでは、Autocomplete ウィジェットをプロジェクトに追加する方法について説明します。
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" />
オートコンプリート ウィジェットをアクティビティに追加する手順は次のとおりです。
- アプリケーション コンテキストと API キーを渡して
Places
を初期化します。 AutocompleteSupportFragment
を初期化します。setPlaceFields()
を呼び出して、取得する場所データの種類を指定します。PlaceSelectionListener
を追加して結果を処理し、発生する可能性のあるエラーを処理します。
次の例は、アクティビティに Autocomplete ウィジェットを追加する方法を示しています。
/** * 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.DISPLAY_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); } });
- アプリケーション コンテキストと API キーを渡して
インテントを使用して、オートコンプリート アクティビティを起動する
- アプリ コンテキストと API キーを渡して
Places
を初期化する 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.DISPLAY_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 をサポートしていません。