要求位置更新通知

應用程式適當使用位置資訊對使用者有益。舉例來說,如果應用程式協助使用者在走路或開車時規劃路線,或追蹤裝置位置,則必須定期取得裝置定位。除了地理位置 (經緯度) 外,開發人員也可為使用者提供其他資訊,例如方位 (水平方向)、高度,或裝置的速度。應用程式可以從整合式位置預測提供工具取得的 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 活動類別參考資料。

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

其他資源

如要進一步瞭解,請使用下列資源:

範例