適當使用位置資訊對應用程式的使用者很有幫助。舉例來說,如果應用程式要在使用者走路或開車時協助規劃路線,或是想追蹤資產的位置,則需要定期取得裝置的位置資訊。除了地理位置 (經緯度) 外,您可能還想為使用者提供進一步資訊,例如裝置的方位 (行進的水平方向)、高度或速度。應用程式可以透過整合式位置預測提供工具擷取 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()
中擷取偏好設定。如要進一步瞭解如何儲存偏好設定,請參閱「儲存鍵/值組」。
其他資源
如需瞭解更多資訊,不妨參考以下資源:
範例
- 範例應用程式,示範如何在 Android 中接收位置更新資訊。