更改位置设置

如果您的应用程序需要请求位置或接收权限更新,则设备需要启用适当的系统设置,例如 GPS 或 Wi-Fi 扫描。您的应用程序不会直接启用诸如设备 GPS 之类的服务,而是指定所需的精度/功耗水平和所需的更新间隔,设备会自动对系统设置进行相应的更改。这些设置由 LocationRequest 数据对象定义。

本课程将向您展示如何使用 Settings Client 检查已启用的设置,并显示位置设置对话框,以便用户只需单击一下即可更新其设置。

配置位置服务

为了使用 Google Play 服务和融合位置提供程序提供的位置服务,请使用 Settings Client 连接您的应用程序,然后检查当前位置设置,并在需要时提示用户启用必需的设置。

其功能使用位置服务的应用程序必须根据这些功能的用例请求位置权限

设置位置请求

要存储对融合位置提供程序的请求的参数,请创建一个 LocationRequest。这些参数决定位置请求的精度级别。有关所有可用位置请求选项的详细信息,请参阅 LocationRequest 类参考。本课程设置更新间隔、最快更新间隔和优先级,如下所述

更新间隔
setInterval() - 此方法设置您的应用程序希望接收位置更新的速率(以毫秒为单位)。请注意,位置更新可能比此速率略快或略慢,以优化电池使用情况,或者根本没有更新(例如,如果设备没有连接)。
最快更新间隔
setFastestInterval() - 此方法设置您的应用程序可以处理位置更新的最快速率(以毫秒为单位)。除非您的应用程序从比 setInterval() 中指定的速率更快的速率接收更新中获益,否则您无需调用此方法。
优先级

setPriority() - 此方法设置请求的优先级,这会向 Google Play 服务位置服务提供一个关于要使用哪些位置源的强烈提示。支持以下值

  • PRIORITY_BALANCED_POWER_ACCURACY - 使用此设置将位置精度请求到一个街区内,即大约 100 米的精度。这被认为是粗略的精度级别,并且很可能会消耗更少的电量。使用此设置,位置服务很可能会使用 WiFi 和蜂窝塔定位。但是,请注意,位置提供程序的选择取决于许多其他因素,例如哪些源可用。
  • 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 权限设置,以及 5000 毫秒(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() 方法。

提示用户更改位置设置

要确定位置设置是否适合位置请求,请向验证位置设置的 Task 对象添加一个 OnFailureListener。然后,检查传递给 Exception 对象传递给 onFailure() 方法的方法是否为 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.
            }
        }
    }
});

下一课 接收位置更新 将向您展示如何接收定期位置更新。