Vị trí gần đúng

1. Giới thiệu

Trên Android 12 (API cấp 31) trở lên, người dùng có quyền kiểm soát độ chính xác của thông tin vị trí mà họ muốn cấp cho ứng dụng của mình. Trên các phiên bản Android trước đó, độ chính xác của thông tin vị trí được kiểm soát ngầm dựa trên quyền ACCESS_FINE_LOCATION hoặc quyền ACCESS_COARSE_LOCATION mà ứng dụng yêu cầu.

Lớp học lập trình này sẽ cung cấp hướng dẫn và các phương pháp hay nhất dành cho ứng dụng có phiên bản SDK mục tiêu là 31 trở lên để yêu cầu quyền truy cập thông tin vị trí.

Điều kiện tiên quyết

Kiến thức bạn sẽ học được

  • Cách yêu cầu quyền truy cập thông tin vị trí trên Android S
  • Cách triển khai quy trình yêu cầu thông tin vị trí tối ưu để người dùng có thể cấp cho ứng dụng của bạn quyền truy cập thông tin vị trí chính xác

Điều khoản

Vị trí chính xác: độ chi tiết về thông tin vị trí của quyền ACCESS_FINE_LOCATION.

Vị trí gần đúng: độ chi tiết về thông tin vị trí của quyền ACCESS_COARSE_LOCATION.

API được đề cập

2. Yêu cầu quyền ACCESS_FINE_LOCATION

Quy trình giao diện người dùng mới

Trước tiên, hãy xem giao diện người dùng mới để nắm được một số ý tưởng về những thay đổi liên quan đến độ chính xác của thông tin vị trí.

Hình 1a và Hình 1b dưới đây thể hiện hộp thoại quyền xuất hiện khi ứng dụng chưa được cấp quyền ACCESS_FINE_LOCATION hoặc quyền ACCESS_COARSE_LOCATION.

7acc5e2fe09d67ca.jpeg a5e9363364fcc9f9.jpeg

Hình 1a: Vị trí chính xác được chọn Hình 1b: Vị trí gần đúng được chọn

Hình 2a dưới đây thể hiện hộp thoại nâng cấp quyền xuất hiện khi ứng dụng đã được cấp quyền ACCESS_COARSE_LOCATION trong khi sử dụng. Hộp thoại này xuất hiện nếu người dùng chọn "While using the app" (Trong khi dùng ứng dụng) cho Vị trí gần đúng trên màn hình trước (thể hiện trong Hình 1b).

2624d89993700ea5.jpeg

Hình 2a

Hình 2b dưới đây thể hiện hộp thoại nâng cấp quyền xuất hiện khi ứng dụng đã được cấp quyền ACCESS_COARSE_LOCATION cho phiên hiện tại. Hộp thoại này xuất hiện nếu người dùng chọn "Only this time" (Chỉ lần này) trên màn hình trước (thể hiện trong Hình 1b).

a2dfb923b8f3548d.jpeg

Hình 2b

3. Triển khai mã

Khai báo quyền truy cập thông tin vị trí trong tệp kê khai của ứng dụng

Để yêu cầu ACCESS_FINE_LOCATION, hệ thống sẽ yêu cầu ứng dụng khai báo cả ACCESS_FINE_LOCATIONACCESS_COARSE_LOCATION trong tệp kê khai của ứng dụng. Nếu không, hệ thống sẽ bỏ qua yêu cầu này và không cấp quyền nào cho ứng dụng.

<manifest ... >
  <!-- Required when requesting precise location access on Android 12 (API level 31) and higher. -->
  <uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
  <uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />
</manifest>

Yêu cầu quyền ACCESS_FINE_LOCATION

MyActivity.kt (Kotlin)

when {
    ContextCompat.checkSelfPermission(
            CONTEXT,
            Manifest.permission.ACCESS_FINE_LOCATION
            ) == PackageManager.PERMISSION_GRANTED -> {
        // You can use the API that requires the permission.
        performAction(...)
    }
    shouldShowRequestPermissionRationale(...) -> {
        // In an educational UI, explain to the user why your app requires this
        // permission for a specific feature to behave as expected. In this UI,
        // include a "cancel" or "no thanks" button that allows the user to
        // continue using your app without granting the permission.
        showInContextUI(...)
    }
    else -> {
        // Ask for both the ACCESS_FINE_LOCATION and ACCESS_COARSE_LOCATION permissions.
        requestPermissions(CONTEXT,
                arrayOf(Manifest.permission.ACCESS_FINE_LOCATION,
                        Manifest.permission.ACCESS_COARSE_LOCATION),
                REQUEST_CODE)
    }
}

MyActivity.java (Java)

if (ContextCompat.checkSelfPermission(
        CONTEXT, Manifest.permission.ACCESS_FINE_LOCATION) ==
        PackageManager.PERMISSION_GRANTED) {
    // You can use the API that requires the permission.
    performAction(...);
} else if (shouldShowRequestPermissionRationale(...)) {
    // In an educational UI, explain to the user why your app requires this
    // permission for a specific feature to behave as expected. In this UI,
    // include a "cancel" or "no thanks" button that allows the user to
    // continue using your app without granting the permission.
    showInContextUI(...);
} else {
    // Ask for both the ACCESS_FINE_LOCATION and ACCESS_COARSE_LOCATION permissions.
    requestPermissions(CONTEXT,
            new String[] { Manifest.permission.ACCESS_FINE_LOCATION,
                           Manifest.permission.ACCESS_COARSE_LOCATION },
            REQUEST_CODE);
}

Xử lý phản hồi

MyActivity.kt (Kotlin)

override fun onRequestPermissionsResult(requestCode: Int,
        permissions: Array<String>, grantResults: IntArray) {
    when (requestCode) {
        REQUEST_CODE -> {
            // If the request is cancelled, the result arrays are empty.
            if (grantResults.isNotEmpty()) {
                if (grantResults[0] == PackageManager.PERMISSION_GRANTED) {
                    // ACCESS_FINE_LOCATION is granted
                } else if (grantResults[1] ==
                               PackageManager.PERMISSION_GRANTED) {
                    // ACCESS_COARSE_LOCATION is granted
                }
            } else {
                // Explain to the user that the feature is unavailable because
                // the feature requires a permission that the user has denied.
                // At the same time, respect the user's decision. Don't link to
                // system settings in an effort to convince the user to change
                // their decision.
            }
            return
        }

        // Add other 'when' lines to check for other
        // permissions this app might request.
        else -> {
            // Ignore all other requests.
        }
    }
}

MyActivity.java (Java)

@Override
public void onRequestPermissionsResult(int requestCode, String[] permissions,
        int[] grantResults) {
    switch (requestCode) {
        case PERMISSION_REQUEST_CODE:
            // If the request is cancelled, the result arrays are empty.
            if (grantResults.length > 0) {
                if (grantResults[0] == PackageManager.PERMISSION_GRANTED) {
                    // ACCESS_FINE_LOCATION is granted
                } else if (grantResults[1] ==
                               PackageManager.PERMISSION_GRANTED) {
                    // ACCESS_COARSE_LOCATION is granted
                }
            } else {
                // Explain to the user that the feature is unavailable because
                // the feature requires a permission that the user has denied.
                // At the same time, respect the user's decision. Don't link to
                // system settings in an effort to convince the user to change
                // their decision.
            }
            return;
        }
        // Other 'case' lines to check for other
        // permissions this app might request.
    }
}

4. Chỉ yêu cầu quyền ACCESS_COARSE_LOCATION

Hình 4 thể hiện hộp thoại quyền xuất hiện khi ứng dụng chỉ yêu cầu quyền ACCESS_COARSE_LOCATION.

9d20729f14673547.jpeg

Hình 4

Để chỉ làm việc với quyền truy cập thông tin vị trí gần đúng, ứng dụng cần khai báo và chỉ xử lý quyền truy cập thông tin gần đúng trong mỗi bước.

5. Cài đặt vị trí

Hình 5 dưới đây thể hiện các chế độ cài đặt mới về quyền truy cập thông tin vị trí. Người dùng sẽ thấy một nút chuyển bật/tắt mới để kiểm soát việc ứng dụng có thể truy cập thông tin vị trí chính xác hoặc gần đúng hay không.

a9553249c3e2b90c.jpeg

Hình 5

6. Đối với ứng dụng nhắm đến SDK phiên bản 30 trở xuống

Các tuỳ chọn mới về độ chính xác của vị trí (chính xác/gần đúng) không xuất hiện trên ứng dụng nhắm đến SDK phiên bản 30 trở xuống.

7. Xin chúc mừng!

Bạn đã tìm hiểu cách yêu cầu quyền truy cập thông tin vị trí trên Android 12 và khám phá thành công nhiều thành phần chính trong quyền truy cập thông tin vị trí!

Giờ đây, bạn có thể yêu cầu quyền truy cập thông tin vị trí cho nhiều trường hợp sử dụng để đáp ứng nhu cầu của ứng dụng.

Tìm hiểu thêm về thông tin vị trí: