更改位置信息设置

如果您的应用需要请求位置信息或接收权限更新,设备就需要启用适当的系统设置,例如 GPS 或 WLAN 扫描。您的应用不应直接启用服务(例如设备的 GPS),而应指定所需的准确度/耗电量以及更新间隔,然后设备就会自动对系统设置进行相应的更改。这些设置通过 LocationRequest 数据对象定义。

本课介绍如何使用 Settings Client 检查启用了哪些设置,以及如何向用户提供“位置信息设置”对话框,让用户只需点按一下就可以更新自己的设置。

配置位置信息服务

为使用 Google Play 服务提供的位置信息服务和一体化位置信息提供程序提供的位置信息服务,请使用 Settings Client 连接您的应用,然后检查当前的位置信息设置,并视需要提示用户启用所需的设置。

如果应用的功能需要使用位置信息服务,应用必须根据这些功能的应用场景请求位置权限

设置位置信息请求

如需保存向一体化位置信息提供程序发送的请求的参数,请创建 LocationRequest。这些参数用于确定位置信息请求的准确度。如需详细了解所有可用的位置信息请求选项,请参阅 LocationRequest 类参考。本课将介绍如何设置更新间隔、最快更新间隔和优先级,具体如下所述:

更新间隔
setInterval() - 此方法以毫秒为单位,设置应用接收位置信息更新的频率。请注意,为了优化电池电量的使用,位置信息的更新频率可能会高于或低于此频率,此外也可能完全不更新位置信息(例如,当设备没有网络连接时)。
最快更新间隔
setFastestInterval() - 此方法以毫秒为单位,设置应用处理位置信息更新的最快频率。除非以快于 setInterval() 中指定的频率接收更新时对应用有益,否则您无需调用此方法。
优先级

setPriority() - 此方法用于设置请求的优先级,此优先级可以明确地提示 Google Play 服务提供的位置信息服务应该使用哪些位置信息来源。支持使用以下值:

  • PRIORITY_BALANCED_POWER_ACCURACY - 使用此设置可以请求城市街区级别的定位精确度,即大约 100 米。这是一个粗略的准确度,消耗的电量可能会比较少。使用此设置时,位置信息服务可能会使用 WLAN 和手机基站来进行定位。但请注意,位置信息提供程序的选择还取决于许多其他因素,例如有哪些信息来源可用。
  • 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,并添加一个或多个位置信息请求。以下代码段展示了如何添加在上一步中创建的位置信息请求:

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() 方法。

提示用户更改位置信息设置

如需确定位置信息设置是否适合位置信息请求,请将 OnFailureListener 添加至验证位置信息设置的 Task 对象。然后,检查传递到 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.
            }
        }
    }
});

下一节课接收位置信息更新将介绍如何接收定期位置信息更新。