變更位置資訊設定

如果您的應用程式必須要求位置資訊或接收權限更新,裝置就必須啟用適當的系統設定,如 GPS 或掃描 Wi-Fi。您的應用程式不會直接啟用裝置的 GPS 等服務,而是指定所需的準確度/耗電量和偏好的更新間隔,而且裝置會自動對系統設定進行適當變更。這些設定由 LocationRequest 資料物件定義。

本課程將說明如何使用設定用戶端來檢查已啟用的設定,並顯示「位置資訊設定」對話方塊,使用者只需在此輕觸一下即可更新設定。

設定定位服務

如要使用 Google Play 服務和整合式位置預測提供工具所提供的定位服務,請使用設定用戶端與應用程式連線,然後檢查目前的位置資訊設定,並提示使用者在需要時啟用必要的設定。

如果應用程式的功能會用到定位服務,必須要求位置存取權 (視這些功能的用途而定)。

建立位置要求

如要儲存整合式位置預測提供工具的要求參數,請建立 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.create()?.apply {
        interval = 10000
        fastestInterval = 5000
        priority = LocationRequest.PRIORITY_HIGH_ACCURACY
    }
}

Java

protected void createLocationRequest() {
    LocationRequest locationRequest = LocationRequest.create();
    locationRequest.setInterval(10000);
    locationRequest.setFastestInterval(5000);
    locationRequest.setPriority(LocationRequest.PRIORITY_HIGH_ACCURACY);
}

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

提示使用者變更位置資訊設定

如要判斷位置資訊設定是否適合地區要求,請將 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.
            }
        }
    }
});

在下一堂課接收位置更新通知中,您會瞭解如何接收定期位置更新通知。