更改位置设置

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

本课程展示如何使用 Settings Client 检查哪些设置已启用,并向用户呈现位置设置对话框,以便用户通过单次点击即可更新其设置。

配置位置服务

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

应用的功能使用位置服务时,必须根据这些功能的使用场景请求位置权限

设置位置请求

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

更新间隔
setIntervalMillis() - 此方法设置您的应用期望接收位置更新的速率,以毫秒为单位。请注意,为了优化电池使用,位置更新的速率可能略快或略慢于此速率,或者完全没有更新(例如,如果设备没有连接)。
最快更新间隔
setMinUpdateIntervalMillis() - 此方法设置您的应用可以处理位置更新的最快速率,以毫秒为单位。除非您的应用受益于比 setInterval() 中指定的速率更快地接收更新,否则您无需调用此方法。
优先级

setPriority() - 此方法设置请求的优先级,这为 Google Play 服务位置服务提供了强烈提示,指示应使用哪些位置源。支持以下值

  • PRIORITY_BALANCED_POWER_ACCURACY - 使用此设置请求精确到城市街区范围内的位置精度,精度约为 100 米。这被认为是粗略的精度级别,并且很可能消耗较少的电量。使用此设置时,位置服务很可能使用 WiFi 和蜂窝基站定位。但是请注意,位置提供程序的选择取决于许多其他因素,例如哪些来源可用。
  • PRIORITY_HIGH_ACCURACY - 使用此设置请求尽可能最精确的位置。使用此设置时,位置服务更有可能使用 GPS 来确定位置。
  • PRIORITY_LOW_POWER - 使用此设置请求城市级别的精度,精度约为 10 公里。这被认为是粗略的精度级别,并且很可能消耗较少的电量。
  • PRIORITY_PASSIVE - 如果您需要对功耗的影响可以忽略不计,但希望在可用时接收位置更新,请使用此设置。使用此设置时,您的应用不会触发任何位置更新,但会接收由其他应用触发的位置。

按照此代码示例所示创建位置请求并设置参数

Kotlin

  fun createLocationRequest() {
    val locationRequest = LocationRequest.Builder(Priority.PRIORITY_HIGH_ACCURACY, 10000)
        .setMinUpdateIntervalMillis(5000)
        .build()
}

Java

  protected void createLocationRequest() {
    LocationRequest locationRequest = new LocationRequest.Builder(Priority.PRIORITY_HIGH_ACCURACY, 10000)
            .setMinUpdateIntervalMillis(5000)
            .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。然后,检查传递给 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.
            }
        }
    }
});

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