Yêu cầu thông tin cập nhật về vị trí

Việc sử dụng thông tin vị trí một cách thích hợp có thể có lợi cho người dùng ứng dụng. Ví dụ: nếu có tính năng giúp người dùng tìm đường khi đang đi bộ hoặc lái xe hay theo dõi vị trí của tài sản, thì ứng dụng cần định kỳ nhận được thông tin vị trí của thiết bị. Cũng như vị trí địa lý (vĩ độ và kinh độ), bạn có thể cung cấp cho người dùng thêm thông tin như góc phương tiện (chiều đi ngang), cao độ hoặc vận tốc của thiết bị. Thông tin này và nhiều thông tin khác sẽ có trong đối tượng Location mà ứng dụng của bạn có thể truy xuất từ trình cung cấp vị trí kết hợp. Để hồi đáp, API sẽ cập nhật định kỳ thông tin vị trí chính xác nhất hiện có cho ứng dụng của bạn, dựa trên các trình cung cấp vị trí hiện có chẳng hạn như Wi-Fi và GPS (Hệ thống định vị toàn cầu). Độ chính xác của thông tin vị trí phụ thuộc vào nhà cung cấp, quyền truy cập thông tin vị trí bạn đã yêu cầu và tuỳ chọn bạn đặt trong yêu cầu truy cập thông tin vị trí.

Bài học này sẽ hướng dẫn bạn cách yêu cầu nhận thông tin cập nhật thường xuyên về vị trí của một thiết bị bằng phương thức requestLocationUpdates() trong trình cung cấp vị trí kết hợp.

Lấy thông tin vị trí đã biết gần đây nhất

Thông tin vị trí đã biết gần đây nhất của thiết bị là cơ sở hữu ích để bắt đầu, đảm bảo rằng ứng dụng có được thông tin vị trí đã biết trước khi bắt đầu quy trình cập nhật thông tin vị trí định kỳ. Bài học về Cách lấy thông tin vị trí đã biết gần đây nhất cho bạn biết cách lấy thông tin vị trí đã biết gần đây nhất bằng cách gọi getLastLocation(). Các đoạn mã trong những phần sau giả định rằng ứng dụng của bạn đã truy xuất thông tin vị trí đã biết gần đây nhất và lưu trữ dưới dạng đối tượng Location trong biến toàn cục mCurrentLocation.

Đưa ra yêu cầu truy cập thông tin vị trí

Trước khi yêu cầu thông tin cập nhật về vị trí, ứng dụng của bạn phải kết nối với các dịch vụ vị trí và đưa ra yêu cầu truy cập thông tin vị trí. Bài học về Cách thay đổi chế độ cài đặt thông tin vị trí sẽ hướng dẫn bạn cách thực hiện. Sau khi đưa ra yêu cầu truy cập thông tin vị trí, bạn có thể bắt đầu quy trình cập nhật định kỳ bằng cách gọi requestLocationUpdates().

Tuỳ thuộc vào hình thức yêu cầu, trình cung cấp vị trí kết hợp sẽ gọi phương thức gọi lại LocationCallback.onLocationResult() và truyền cho phương thức đó danh sách các đối tượng Location, hoặc đưa ra PendingIntent chứa thông tin vị trí trong dữ liệu mở rộng. Độ chính xác và tần suất của thông tin cập nhật sẽ chịu ảnh hưởng của các quyền truy cập thông tin vị trí mà bạn đã yêu cầu và tuỳ chọn bạn đặt trong đối tượng yêu cầu truy cập thông tin vị trí.

Bài học này sẽ hướng dẫn bạn cách nhận thông tin cập nhật bằng phương thức gọi lại LocationCallback. Gọi requestLocationUpdates(), truyền vào đó thực thể của đối tượng LocationRequestLocationCallback. Định nghĩa một phương thức startLocationUpdates() như trong đoạn mã mẫu sau:

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());
}

Lưu ý: Đoạn mã ở trên đề cập đến cờ boolean (requestingLocationUpdates) dùng để theo dõi xem người dùng bật hay tắt thông tin cập nhật về vị trí. Nếu người dùng tắt, bạn có thể cho họ biết ứng dụng cần truy cập thông tin vị trí của họ. Để biết thêm thông tin về việc giữ lại giá trị của cờ boolean trên các thực thể của hoạt động, xem phần Lưu trạng thái của hoạt động.

Định nghĩa lệnh gọi lại thông tin cập nhật về vị trí

Trình cung cấp vị trí kết hợp này gọi phương thức gọi lại LocationCallback.onLocationResult(). Đối số đến chứa danh sách đối tượng Location có vĩ độ và kinh độ của vị trí. Đoạn mã sau đây cho biết cách triển khai giao diện LocationCallback và định nghĩa phương thức, sau đó lấy dấu thời gian của thông tin cập nhật về vị trí và hiển thị vĩ độ, kinh độ và dấu thời gian trên giao diện người dùng của ứng dụng:

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
                // ...
            }
        }
    };
}

Dừng yêu cầu cập nhật vị trí

Hãy cân nhắc xem bạn có muốn dừng yêu cầu cập nhật về vị trí khi không hoạt động không còn là tiêu điểm nữa, chẳng hạn như khi người dùng chuyển sang một ứng dụng khác hoặc chuyển sang một hoạt động khác trong cùng một ứng dụng. Phương thức này có thể hữu ích trong việc giảm mức sử dụng pin, miễn là ứng dụng không cần thu thập thông tin ngay cả khi đang chạy trong nền. Phần này cho bạn biết cách dừng thông tin cập nhật trong phương thức onPause() của hoạt động.

Để dừng yêu cầu cập nhật vị trí, hãy gọi removeLocationUpdates(), truyền vào đó LocationCallback, như trong đoạn mã mẫu sau:

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);
}

Sử dụng boolean requestingLocationUpdates để theo dõi xem yêu cầu cập nhật vị trí có đang bật hay không. Trong phương thức onResume() của hoạt động, hãy kiểm tra xem yêu cầu cập nhật vị trí có đang hoạt động hay không và kích hoạt nếu yêu cầu không hoạt động:

Kotlin

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

Java

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

Lưu trạng thái của hoạt động

Việc thay đổi cấu hình của thiết bị, chẳng hạn như thay đổi hướng hoặc ngôn ngữ của màn hình, có thể khiến hoạt động hiện tại bị huỷ. Do đó, ứng dụng của bạn phải lưu trữ mọi thông tin cần thiết để tạo lại hoạt động. Bạn có thể thực hiện việc này thông qua trạng thái của một thực thể được lưu trữ trong đối tượng Bundle.

Mã mẫu sau đây cho biết cách sử dụng lệnh gọi lại onSaveInstanceState() của hoạt động để lưu trạng thái của thực thể:

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);
}

Định nghĩa phương thức updateValuesFromBundle() để khôi phục các giá trị đã lưu từ thực thể trước của hoạt động (nếu có). Gọi phương thức từ phương thức onCreate() của hoạt động, như minh hoạ trong đoạn mã mẫu sau đây:

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();
}

Để biết thêm thông tin về cách lưu trạng thái của thực thể, hãy xem tài liệu tham khảo về lớp Hoạt động trên Android.

Lưu ý: Để có lưu trữ một cách bền lâu hơn, bạn có thể lưu trữ lựa chọn ưu tiên của người dùng trong SharedPreferences của ứng dụng. Đặt lựa chọn ưu tiên dùng chung trong phương thức onPause() của hoạt động và truy xuất lựa chọn ưu tiên đó trong onResume(). Để biết thêm thông tin về cách lưu lựa chọn ưu tiên, hãy đọc bài viết Cách lưu tập hợp khoá-giá trị.

Tài nguyên khác

Để tìm hiểu thêm, hãy sử dụng các tài nguyên sau đây:

Mẫu

  • Ứng dụng mẫu minh hoạ cách nhận thông tin cập nhật về vị trí trong Android.