要求接獲位置更新通知

適當使用位置資訊對應用程式的使用者很有幫助。舉例來說,如果應用程式要在使用者走路或開車時協助規劃路線,或是想追蹤資產的位置,則需要定期取得裝置的位置資訊。除了地理位置 (經緯度) 外,您可能還想為使用者提供進一步資訊,例如裝置的方位 (行進的水平方向)、高度或速度。應用程式可以透過整合式位置預測提供工具擷取 Location 物件,從中取得這些資訊和更多內容。作為回應,API 會根據 Wi-Fi 和 GPS (全球定位系統) 等當下可用的位置資訊提供者,以可用的最佳位置資訊定期更新應用程式。位置資訊的準確度取決於提供者、您要求的位置存取權,以及您在位置資訊要求中設定的選項。

本課程將說明如何使用整合式位置預測提供工具中的 requestLocationUpdates() 方法,要求對裝置的位置資訊進行定期更新。

取得最後已知位置

裝置的最後已知位置是個方便的起點,可確保應用程式在開始定期更新位置資訊前,已具備已知位置資訊。「取得最後已知位置」課程會說明如何呼叫 getLastLocation() 以取得最後已知位置。後續章節的程式碼片段假設應用程式已擷取最後已知位置,並將其儲存為全域變數 mCurrentLocation 中的 Location 物件。

提出位置資訊要求

應用程式必須先連上定位服務並提出位置資訊要求,才能要求位置更新通知。請參閱「變更位置資訊設定」課程瞭解操作說明。發出位置資訊要求後,即可透過呼叫 requestLocationUpdates(),開始定期更新。

視要求的形式而定,整合式位置預測提供工具會叫用 LocationCallback.onLocationResult() 回呼方法並傳遞 Location 物件清單,或發出包含擴充資料中位置資訊的 PendingIntent。您要求的位置存取權以及在位置資訊要求物件中設定的選項,會影響更新資訊的準確度與頻率。

本課程將說明如何使用 LocationCallback 回呼方法取得更新。請呼叫 requestLocationUpdates(),並向其傳送 LocationRequest 物件的例項及 LocationCallback。請定義 startLocationUpdates() 方法,如以下程式碼範例所示:

Kotlin

override fun onResume() {
    super.onResume()
    if (requestingLocationUpdates) startLocationUpdates()
}

private fun startLocationUpdates() {
    fusedLocationClient.requestLocationUpdates(locationRequest,
            locationCallback,
            Looper.getMainLooper())
}

Java

@Override
protected void onResume() {
    super.onResume();
    if (requestingLocationUpdates) {
        startLocationUpdates();
    }
}

private void startLocationUpdates() {
    fusedLocationClient.requestLocationUpdates(locationRequest,
            locationCallback,
            Looper.getMainLooper());
}

請注意,上述程式碼片段參照了布林值標記 requestingLocationUpdates,用來追蹤使用者是否開啟或關閉位置更新功能。如果使用者關閉此功能,您可以通知使用者應用程式要求存取位置資訊。如要進一步瞭解如何在活動例項間保留該布林值標記的值,請參閱「儲存活動狀態」一文。

定義位置更新通知的回呼

整合式位置預測提供工具會叫用 LocationCallback.onLocationResult() 回呼方法。傳入的引數會包含 Location 物件清單,其中含有位置的經緯度資料。以下程式碼片段說明如何實作 LocationCallback 介面並定義該方法,然後取得位置更新通知的時間戳記,並在應用程式使用者介面上顯示經緯度和時間戳記:

Kotlin

private lateinit var locationCallback: LocationCallback

// ...

override fun onCreate(savedInstanceState: Bundle?) {
    // ...

    locationCallback = object : LocationCallback() {
        override fun onLocationResult(locationResult: LocationResult?) {
            locationResult ?: return
            for (location in locationResult.locations){
                // Update UI with location data
                // ...
            }
        }
    }
}

Java

private LocationCallback locationCallback;

// ...

@Override
protected void onCreate(Bundle savedInstanceState) {
    // ...

    locationCallback = new LocationCallback() {
        @Override
        public void onLocationResult(LocationResult locationResult) {
            if (locationResult == null) {
                return;
            }
            for (Location location : locationResult.getLocations()) {
                // Update UI with location data
                // ...
            }
        }
    };
}

停止位置更新通知

請考量當活動不在焦點時 (例如使用者切換至其他應用程式,或是同一應用程式中的其他活動時),是否要停止位置更新通知。這麼做有利於降低耗電量,前提是應用程式即使在背景執行,也不需要收集資訊。本節說明如何在活動的 onPause() 方法中停止更新。

如要停止位置更新通知,請呼叫 removeLocationUpdates() 並向其傳遞 LocationCallback,如以下程式碼範例所示:

Kotlin

override fun onPause() {
    super.onPause()
    stopLocationUpdates()
}

private fun stopLocationUpdates() {
    fusedLocationClient.removeLocationUpdates(locationCallback)
}

Java

@Override
protected void onPause() {
    super.onPause();
    stopLocationUpdates();
}

private void stopLocationUpdates() {
    fusedLocationClient.removeLocationUpdates(locationCallback);
}

如要追蹤位置更新通知功能是否為啟用狀態,請使用布林值 requestingLocationUpdates。在活動的 onResume() 方法中,檢查位置更新通知功能是否為啟用狀態,如未啟用,請啟用這項功能:

Kotlin

override fun onResume() {
    super.onResume()
    if (requestingLocationUpdates) startLocationUpdates()
}

Java

@Override
protected void onResume() {
    super.onResume();
    if (requestingLocationUpdates) {
        startLocationUpdates();
    }
}

儲存活動狀態

變更裝置設定 (如變更螢幕方向或語言設定) 可能導致現有活動遭到刪除。因此,您的應用程式必須儲存重建活動所需的任何資訊。另一個做法是透過儲存在 Bundle 物件的例項狀態重建活動。

以下程式碼範例說明如何使用活動的 onSaveInstanceState() 回呼儲存例項狀態:

Kotlin

override fun onSaveInstanceState(outState: Bundle?) {
    outState?.putBoolean(REQUESTING_LOCATION_UPDATES_KEY, requestingLocationUpdates)
    super.onSaveInstanceState(outState)
}

Java

@Override
protected void onSaveInstanceState(Bundle outState) {
    outState.putBoolean(REQUESTING_LOCATION_UPDATES_KEY,
            requestingLocationUpdates);
    // ...
    super.onSaveInstanceState(outState);
}

請定義 updateValuesFromBundle() 方法,以從上一個活動例項中還原已儲存的值 (如有)。從活動的 onCreate() 方法呼叫上述方法,如以下程式碼範例所示:

Kotlin

override fun onCreate(savedInstanceState: Bundle?) {
    // ...
    updateValuesFromBundle(savedInstanceState)
}

private fun updateValuesFromBundle(savedInstanceState: Bundle?) {
    savedInstanceState ?: return

    // Update the value of requestingLocationUpdates from the Bundle.
    if (savedInstanceState.keySet().contains(REQUESTING_LOCATION_UPDATES_KEY)) {
        requestingLocationUpdates = savedInstanceState.getBoolean(
                REQUESTING_LOCATION_UPDATES_KEY)
    }

    // ...

    // Update UI to match restored state
    updateUI()
}

Java

@Override
public void onCreate(Bundle savedInstanceState) {
    // ...
    updateValuesFromBundle(savedInstanceState);
}

private void updateValuesFromBundle(Bundle savedInstanceState) {
    if (savedInstanceState == null) {
        return;
    }

    // Update the value of requestingLocationUpdates from the Bundle.
    if (savedInstanceState.keySet().contains(REQUESTING_LOCATION_UPDATES_KEY)) {
        requestingLocationUpdates = savedInstanceState.getBoolean(
                REQUESTING_LOCATION_UPDATES_KEY);
    }

    // ...

    // Update UI to match restored state
    updateUI();
}

如要進一步瞭解如何儲存例項狀態,請參閱 Android Activity 類別的參考資料。

注意:如要享有更永久的儲存空間,您可以將使用者的偏好設定儲存在應用程式的 SharedPreferences 中。請在活動的 onPause() 方法中設置共用偏好設定,並在 onResume() 中擷取偏好設定。如要進一步瞭解如何儲存偏好設定,請參閱「儲存鍵/值集」。

其他資源

如要進一步瞭解,請充分運用以下資源:

範例