位置情報の設定を変更する

アプリが位置情報をリクエストしたり権限の更新を受信したりする必要がある場合、デバイス側で該当のシステム設定(GPS や Wi-Fi スキャン)を有効にする必要があります。アプリでは、デバイスの GPS などのサービスを直接有効にするのではなく、必要なレベルの精度と消費電力、望ましい更新間隔を指定します。デバイスでは、それに基づいてシステム設定に対する適切な変更を自動的に行います。この設定は、LocationRequest データ オブジェクトによって定義されます。

このレッスンでは、SettingsClient を使用してどの設定が有効になっているかをチェックする方法と、[位置情報の設定] ダイアログを表示してユーザーが 1 回のタップで設定を更新できるようにする方法を示します。

位置情報サービスを設定する

Google Play 開発者サービスおよび融合された位置予測プロバイダによって提供される位置情報サービスを使用するには、SettingsClient でアプリを接続し、現在の位置情報設定をチェックして、必要な設定を有効にするようユーザーに促すプロンプトを表示します。

位置情報サービスを使用する機能を含むアプリは、その機能のユースケースに応じて、位置情報権限をリクエストする必要があります。

位置情報リクエストを設定する

融合された位置予測プロバイダへのリクエスト用のパラメータを格納するため、LocationRequest を作成します。これらのパラメータで、位置情報リクエストの精度レベルを指定します。位置情報リクエストのすべての利用可能なオプションについては、LocationRequest クラスのリファレンスをご覧ください。このレッスンでは、以下に示すように、更新間隔、最短更新間隔、優先度を設定します。

更新間隔
setInterval() - このメソッドは、アプリが位置情報の更新データを受信する頻度をミリ秒単位で設定します。電池使用量を最適化するため、位置情報はここでの設定と多少異なる間隔で更新される場合もあれば、まったく更新されない場合(デバイスが接続されていない場合など)もあります。
最短更新間隔
setFastestInterval() - このメソッドは、アプリが位置情報の更新を処理する最短の間隔をミリ秒単位で設定します。setInterval() で指定した間隔より短い間隔で更新データを受信するメリットがない限り、このメソッドを呼び出す必要はありません。
優先度

setPriority() - このメソッドは、リクエストの優先度を設定します。優先度は、Google Play 開発者サービスの位置情報サービスに、どの位置情報ソースを使用するかを判断するための大きなヒントを与えます。サポートされる値は次のとおりです。

  • PRIORITY_BALANCED_POWER_ACCURACY - 都市の区画内の位置情報精度(約 100 メートル)をリクエストするには、この設定を使用します。これはおおまかなレベルの精度と見なされ、消費電力が抑制される可能性があります。この設定では、位置情報サービスが Wi-Fi と基地局による位置決めを使用する可能性があります。ただし、どの位置情報プロバイダを選択するかは、他のさまざまな要素(利用可能なソースなど)によって変わります。
  • PRIORITY_HIGH_ACCURACY - 可能な限り最も高精度の位置情報をリクエストするには、この設定を使用します。この設定では、位置情報サービスが GPS を使用して位置情報を決定する可能性が高くなります。
  • PRIORITY_LOW_POWER - 都市レベルの精度(約 10 キロメートル)をリクエストするには、この設定を使用します。これはおおまかなレベルの精度と見なされ、消費電力が抑制される可能性があります。
  • PRIORITY_NO_POWER - 消費電力の増加を抑える必要があるが、位置情報の更新データが利用可能なときはそれを受信したい場合は、この設定を使用します。この設定では、アプリは位置情報の更新をトリガーせず、他のアプリがトリガーした位置情報の更新データを受信します。

位置情報リクエストを作成してパラメータを設定する方法を次のコードサンプルに示します。

Kotlin

fun createLocationRequest() {
  val locationRequest = LocationRequest.Builder()
      .setIntervalMillis(10000)
      .setFastestIntervalMillis(5000)
      .setPriority(LocationRequest.PRIORITY_HIGH_ACCURACY)
      .build()
}

Java

protected void createLocationRequest() {
  LocationRequest locationRequest = LocationRequest.Builder()
      .setIntervalMillis(10000)
      .setFastestIntervalMillis(5000)
      .setPriority(LocationRequest.PRIORITY_HIGH_ACCURACY)
      .build();
}

PRIORITY_HIGH_ACCURACY の優先度を、アプリ マニフェストで定義した ACCESS_FINE_LOCATION 権限設定および 5,000 ミリ秒(5 秒)の短い更新間隔と組み合わせると、融合された位置予測プロバイダから、数フィート以内の精度で位置情報の更新データが返されます。このアプローチは、位置情報をリアルタイムで表示する地図アプリに適しています。

パフォーマンス向上のヒント: アプリがネットワークにアクセスする場合や、アプリが位置情報の更新データを受信した後で時間のかかる別の処理を行う場合は、最短更新間隔を大きい値に変更します。この調整により、使用できない更新データをアプリが受信しないようにすることができます。時間のかかる処理が完了したら、最短更新間隔を小さい値に戻します。

現在の位置情報設定を取得する

Google Play 開発者サービスと位置情報サービス API に接続すると、ユーザーのデバイスの現在の位置情報設定を取得できます。そのためには、LocationSettingsRequest.Builder を作成して、1 つまたは複数の位置情報リクエストを追加します。前のステップで作成した位置情報リクエストを追加する方法を次のコード スニペットに示します。

Kotlin

val builder = LocationSettingsRequest.Builder()
        .addLocationRequest(locationRequest)

Java

LocationSettingsRequest.Builder builder = new LocationSettingsRequest.Builder()
     .addLocationRequest(locationRequest);

次に、現在の位置情報の設定が満たされているかどうかを確認します。

Kotlin

val builder = LocationSettingsRequest.Builder()

// ...

val client: SettingsClient = LocationServices.getSettingsClient(this)
val task: Task<LocationSettingsResponse> = client.checkLocationSettings(builder.build())

Java

LocationSettingsRequest.Builder builder = new LocationSettingsRequest.Builder();

// ...

SettingsClient client = LocationServices.getSettingsClient(this);
Task<LocationSettingsResponse> task = client.checkLocationSettings(builder.build());

アプリでは、Task の完了後、LocationSettingsResponse オブジェクトのステータス コードを確認することで、位置情報設定をチェックできます。特定の位置情報設定の現在の状態についてさらに詳細な情報を取得するには、LocationSettingsResponse オブジェクトの getLocationSettingsStates() メソッドを呼び出します。

位置情報設定を変更するようユーザーに促す

位置情報設定が位置情報リクエストに適合しているかどうかを判断するには、位置情報設定を検証する Task オブジェクトに OnFailureListener を追加します。次に、onFailure() メソッドに渡された Exception オブジェクトが、設定の変更が必要であることを示す ResolvableApiException クラスのインスタンスかどうかをチェックします。さらに、startResolutionForResult() を呼び出して、位置情報設定を変更する権限を付与するようユーザーに促すダイアログを表示します。

ユーザーの位置情報設定が位置情報サービスによる LocationRequest の作成を許可しているかどうかを判断する方法と、必要に応じて位置情報設定を変更する権限をユーザーにリクエストする方法を、次のコード スニペットに示します。

Kotlin

task.addOnSuccessListener { locationSettingsResponse ->
    // All location settings are satisfied. The client can initialize
    // location requests here.
    // ...
}

task.addOnFailureListener { exception ->
    if (exception is ResolvableApiException){
        // Location settings are not satisfied, but this can be fixed
        // by showing the user a dialog.
        try {
            // Show the dialog by calling startResolutionForResult(),
            // and check the result in onActivityResult().
            exception.startResolutionForResult(this@MainActivity,
                    REQUEST_CHECK_SETTINGS)
        } catch (sendEx: IntentSender.SendIntentException) {
            // Ignore the error.
        }
    }
}

Java

task.addOnSuccessListener(this, new OnSuccessListener<LocationSettingsResponse>() {
    @Override
    public void onSuccess(LocationSettingsResponse locationSettingsResponse) {
        // All location settings are satisfied. The client can initialize
        // location requests here.
        // ...
    }
});

task.addOnFailureListener(this, new OnFailureListener() {
    @Override
    public void onFailure(@NonNull Exception e) {
        if (e instanceof ResolvableApiException) {
            // Location settings are not satisfied, but this can be fixed
            // by showing the user a dialog.
            try {
                // Show the dialog by calling startResolutionForResult(),
                // and check the result in onActivityResult().
                ResolvableApiException resolvable = (ResolvableApiException) e;
                resolvable.startResolutionForResult(MainActivity.this,
                        REQUEST_CHECK_SETTINGS);
            } catch (IntentSender.SendIntentException sendEx) {
                // Ignore the error.
            }
        }
    }
});

次のレッスンの現在地の更新情報を受け取るでは、位置情報の更新データを定期的に受信する方法を示します。