Runtime Permission: có những loại nào và nguyên lý hoạt động trong Android

Tác giả: IT Sectr Đã đăng: 2026-05-20 Thời gian đọc: 8 phút

Runtime Permission là cơ chế yêu cầu quyền trong quá trình thực thi ứng dụng, được giới thiệu trong Android 6.0 (API 23). Không giống như cấp quyền khi cài đặt, runtime permissions cho phép người dùng cấp hoặc thu hồi quyền truy cập vào dữ liệu nhạy cảm (máy ảnh, vị trí địa lý, danh bạ) bất kỳ lúc nào. Theo Android Developers (2026), hơn 85% ứng dụng trên Google Play sử dụng ít nhất một runtime permission.

Các điểm chính

  • Runtime Permission là cơ chế Android yêu cầu sự đồng ý rõ ràng của người dùng để truy cập dữ liệu nhạy cảm.
  • Quyền nguy hiểm là nhóm quyền yêu cầu yêu cầu runtime (máy ảnh, micrô, vị trí địa lý, danh bạ).
  • Quyền thông thường được hệ thống tự động phê duyệt và không yêu cầu runtime (INTERNET, ACCESS_NETWORK_STATE).
  • Quyền một lần là quyền cho một phiên, được giới thiệu trong Android 11, tự động thu hồi khi đóng ứng dụng.
  • shouldShowRequestPermissionRationale là cờ cho biết có cần hiển thị giải thích cho người dùng trước khi yêu cầu hay không.

Runtime Permission là gì?

Runtime Permission là mô hình bảo mật Android trong đó ứng dụng yêu cầu truy cập vào dữ liệu nhạy cảm tại thời điểm chức năng đó thực sự cần thiết cho người dùng. Trước Android 6.0, tất cả các quyền được cấp khi cài đặt ứng dụng và người dùng không thể thu hồi chúng nếu không gỡ cài đặt hoàn toàn ứng dụng.

Sự phát triển của mô hình quyền Android

Trước Android 6.0, người dùng thấy danh sách tất cả các quyền khi cài đặt và có thể chấp nhận tất cả hoặc từ chối cài đặt. Một nghiên cứu năm 2015 cho thấy 87% người dùng không đọc danh sách quyền khi cài đặt. Android 6.0 đã giới thiệu runtime permissions, chia quyền thành thông thường (tự động) và nguy hiểm (cần yêu cầu). Android 11 đã thêm quyền một lần — tự động thu hồi khi đóng ứng dụng. Android 13 đã giới thiệu Trình chọn ảnh và thông báo đẩy như các runtime permissions riêng biệt.

iOS sử dụng mô hình tương tự từ iOS 10, nơi quyền truy cập máy ảnh, micrô và vị trí địa lý được yêu cầu khi sử dụng lần đầu. Tuy nhiên, iOS không có khái niệm “quyền thông thường” — mỗi quyền được yêu cầu một cách rõ ràng và việc từ chối vẫn tồn tại cho đến khi nhà phát triển yêu cầu lại thông qua cài đặt hệ thống.

Runtime Permission hoạt động như thế nào trong Android?

Runtime Permission hoạt động thông qua hộp thoại hệ thống được gọi bởi phương thức requestPermissions() (AndroidX — ActivityResultLauncher). Hệ thống hiển thị hộp thoại tiêu chuẩn với lời giải thích và người dùng chọn “Cho phép” hoặc “Từ chối”. Sau phản hồi, một callback được kích hoạt nơi ứng dụng xử lý quyết định của người dùng.

Yêu cầu quyền qua ActivityResultLauncher

kotlin
private lateinit var requestPermissionLauncher: ActivityResultLauncher<String>

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

    requestPermissionLauncher =
        registerForActivityResult(ActivityResultContracts.RequestPermission()) { isGranted ->
            if (isGranted) {
                startCamera()
            } else {
                showPermissionDeniedDialog()
            }
        }
}

private fun checkCameraPermission() {
    when {
        ContextCompat.checkSelfPermission(this, Manifest.permission.CAMERA)
                == PackageManager.PERMISSION_GRANTED -> {
            startCamera()
        }
        ActivityCompat.shouldShowRequestPermissionRationale(this, Manifest.permission.CAMERA) -> {
            showRationaleDialog { requestPermissionLauncher.launch(Manifest.permission.CAMERA) }
        }
        else -> {
            requestPermissionLauncher.launch(Manifest.permission.CAMERA)
        }
    }
}

Phương thức shouldShowRequestPermissionRationale trả về true nếu người dùng đã từ chối yêu cầu một lần. Trong trường hợp này, nên hiển thị hộp thoại giải thích lý do ứng dụng cần quyền và chỉ sau đó mới yêu cầu lại. Điều này tăng khả năng đồng ý của người dùng lên 30–40% (dữ liệu Google I/O 2024).

Các loại quyền trong Android

Android phân loại tất cả các quyền thành nhiều cấp độ bảo vệ: thông thường, nguy hiểm, chữ ký và đặc biệt. Quyền thông thường được cấp tự động khi cài đặt. Quyền nguy hiểm yêu cầu yêu cầu runtime. Quyền chữ ký chỉ khả dụng cho các ứng dụng được ký bằng cùng một chứng chỉ.

Các nhóm quyền nguy hiểm

NhómQuyềnCấp API
CAMERACAMERAAPI 23+
LOCATIONACCESS_FINE_LOCATION, ACCESS_COARSE_LOCATION, ACCESS_BACKGROUND_LOCATIONAPI 23+ (nền — API 29+)
STORAGEREAD_EXTERNAL_STORAGE, WRITE_EXTERNAL_STORAGE, READ_MEDIA_IMAGES (API 33+)API 23+ (thay đổi trong API 33)
PHONEREAD_PHONE_STATE, CALL_PHONE, READ_CALL_LOGAPI 23+
MICROPHONERECORD_AUDIOAPI 23+
CONTACTSREAD_CONTACTS, WRITE_CONTACTS, GET_ACCOUNTSAPI 23+
NOTIFICATIONSPOST_NOTIFICATIONSAPI 33+

Quyền đặc biệt (SYSTEM_ALERT_WINDOW, WRITE_SETTINGS, MANAGE_EXTERNAL_STORAGE) yêu cầu điều hướng bổ sung đến cài đặt hệ thống qua Settings.ACTION_MANAGE_OVERLAY_PERMISSION. Các quyền này không thể được yêu cầu qua hộp thoại hệ thống tiêu chuẩn và yêu cầu hành động rõ ràng của người dùng trên màn hình cài đặt.

Yêu cầu quyền trong Android 12+

Android 12 đã giới thiệu những thay đổi đáng kể trong mô hình runtime permissions. Quyền một lần cho phép cấp quyền truy cập máy ảnh, micrô hoặc vị trí địa lý chỉ cho một phiên. Khi người dùng đóng ứng dụng, quyền sẽ tự động bị thu hồi. Chỉ báo quyền riêng tư là các chỉ báo màu xanh lá cây trên thanh trạng thái hiển thị khi ứng dụng đang sử dụng máy ảnh hoặc micrô.

Xử lý quyền một lần

kotlin
// Android 12+ — xử lý quyền vị trí một lần
private fun checkLocationPermission() {
    val permissionLauncher =
        registerForActivityResult(ActivityResultContracts.RequestMultiplePermissions()) { permissions ->

        val fineLocationGranted = permissions[Manifest.permission.ACCESS_FINE_LOCATION]
        val coarseLocationGranted = permissions[Manifest.permission.ACCESS_COARSE_LOCATION]

        if (fineLocationGranted == true) {
            showUserLocation()
        } else {
            showLocationDisabledDialog()
        }
    }

    permissionLauncher.launch(
        arrayOf(
            Manifest.permission.ACCESS_FINE_LOCATION,
            Manifest.permission.ACCESS_COARSE_LOCATION
        )
    )
}

// Kiểm tra xem quyền đã bị hệ thống thu hồi chưa (Android 12+)
class PermissionReceiver : BroadcastReceiver() {
    override fun onReceive(context: Context, intent: Intent) {
        if (intent.action == Intent.ACTION_PERMISSION_REVOCATION) {
            handleRevokedPermission(intent.getStringExtra(Intent.EXTRA_REVOKED_PERMISSION))
        }
    }
}

Android 13 đã thêm quyền POST_NOTIFICATIONS vào nhóm nguy hiểm, yêu cầu yêu cầu rõ ràng để gửi thông báo đẩy. Android 14 đã đưa ra các hạn chế đối với vị trí địa lý nền: ứng dụng phải nhận được sự chấp thuận rõ ràng của người dùng mỗi khi yêu cầu vị trí nền. Trình chọn ảnh (API 33+) đã thay thế nhu cầu sử dụng READ_EXTERNAL_STORAGE để chọn ảnh.

Xử lý từ chối của người dùng

Từ chối của người dùng đối với yêu cầu quyền là tình huống bình thường cần được xử lý đúng cách. Có hai loại từ chối: một lần (người dùng nhấn “Từ chối”) và vĩnh viễn (người dùng chọn “Không hỏi lại”). Trong trường hợp thứ hai, hộp thoại hệ thống sẽ không xuất hiện nữa và ứng dụng phải chuyển hướng người dùng đến cài đặt hệ thống.

Chiến lược xử lý từ chối

Sau lần từ chối đầu tiên, ứng dụng nên hiển thị hộp thoại giải thích lý do — lời giải thích riêng về lý do cần quyền. Nếu người dùng từ chối lại, ứng dụng nên chuyển hướng đến màn hình cài đặt ứng dụng qua Settings.ACTION_APPLICATION_DETAILS_SETTINGS. Material 3 khuyến nghị sử dụng PermissionRequestBottomSheet để có UX tự nhiên hơn.

Điều quan trọng là không chặn hoàn toàn chức năng của ứng dụng khi bị từ chối. Ví dụ: nếu người dùng từ chối vị trí địa lý, ứng dụng nên cung cấp tùy chọn nhập địa chỉ thủ công. Đối với máy ảnh, cho phép tải ảnh lên từ thư viện. Google khuyến nghị luôn cung cấp cơ chế dự phòng cho tất cả các runtime permissions.

Khuyến nghị bảo mật

Runtime permissions không chỉ là cơ chế kỹ thuật mà còn là yếu tố tạo dựng niềm tin của người dùng vào ứng dụng. Yêu cầu quyền vào thời điểm không phù hợp (ví dụ: khi khởi chạy lần đầu) làm giảm đáng kể khả năng đồng ý. Google Play Store phân tích tần suất và bối cảnh của các yêu cầu quyền: các ứng dụng có yêu cầu quá mức nhận được thứ hạng tìm kiếm thấp hơn.

Quy tắc yêu cầu quyền

Bối cảnh — yêu cầu quyền ngay trước khi thực hiện hành động cần quyền đó. Tối thiểu — chỉ yêu cầu những quyền thực sự cần thiết cho chức năng hoạt động. Minh bạch — giải thích cho người dùng lý do cần quyền trước hộp thoại hệ thống. Thu hồi — đăng ký ACTION_PERMISSION_REVOCATION để xử lý chính xác việc thu hồi quyền trong thời gian chạy.

Để kiểm tra runtime permissions, sử dụng lệnh adb: adb shell pm revoke <package> android.permission.CAMERA cho phép mô phỏng thu hồi quyền mà không cần cài đặt lại ứng dụng. EspressoUiAutomator hỗ trợ kiểm tra hộp thoại quyền thông qua GrantPermissionRule. Việc tích hợp các công cụ này vào quy trình CI/CD là bắt buộc đối với các ứng dụng có runtime permissions.

Kiểm toán quyền trong Google Play Console

Google Play Console cung cấp phần kiểm toán quyền, nơi nhà phát triển có thể thấy tần suất quyền được yêu cầu, phần trăm người dùng cấp quyền truy cập và quyền nào đã bị thu hồi. Phân tích dữ liệu này giúp xác định các yêu cầu không hiệu quả và tối ưu hóa UX. Ví dụ: nếu dưới 40% người dùng cấp quyền vị trí địa lý, hãy xem xét lại thời điểm yêu cầu và thêm lời giải thích thuyết phục hơn.

Việc sử dụng Android Vitals để giám sát ANR (Ứng dụng không phản hồi) liên quan đến quyền cũng rất quan trọng. Nếu yêu cầu quyền được thực thi trên luồng chính hoặc hộp thoại hệ thống chặn giao diện người dùng, điều này có thể gây ra ANR trên các thiết bị chậm. Di chuyển việc kiểm tra và yêu cầu quyền sang một luồng riêng hoặc sử dụng coroutines Kotlin để xử lý bất đồng bộ nhằm tránh chặn giao diện người dùng.

Các câu hỏi thường gặp

Làm thế nào để phân biệt từ chối một lần với từ chối vĩnh viễn?

shouldShowRequestPermissionRationale trả về false khi từ chối vĩnh viễn (khi người dùng chọn “Không hỏi lại”). Phương thức trả về true khi từ chối một lần, cho phép hiển thị hộp thoại giải thích lý do. Nếu phương thức trả về false, lựa chọn duy nhất là chuyển hướng người dùng đến cài đặt hệ thống.

Có thể yêu cầu nhiều quyền cùng một lúc không?

Có, ActivityResultContracts.RequestMultiplePermissions cho phép yêu cầu một mảng quyền trong một lần gọi. Hệ thống sẽ hiển thị tuần tự các hộp thoại cho từng quyền. Nên nhóm các quyền liên quan đến logic (ví dụ: CAMERARECORD_AUDIO để quay video), nhưng không yêu cầu quá 2–3 quyền cùng một lúc.

Runtime permissions hoạt động như thế nào trên Android TV và Wear OS?

Android TV sử dụng cùng mô hình runtime permissions với hộp thoại hiển thị trên màn hình TV. Wear OS phiên bản 3+ hỗ trợ runtime permissions, nhưng hộp thoại hiển thị trên đồng hồ. Đối với Android Auto, tất cả các quyền được yêu cầu trên điện thoại và hệ thống xe hơi nhận các quyền đã được phê duyệt thông qua kết nối cầu nối.

Những thay đổi về quyền nào được mong đợi trong Android 16?

Theo thông tin sơ bộ, Android 16 giới thiệu “hết hạn quyền” cho các quyền một lần với tính năng tự động thu hồi sau 24 giờ. Các yêu cầu chặt chẽ hơn đối với vị trí nền và danh sách mở rộng các quyền nguy hiểm cho các danh mục mới (cảm biến môi trường, quét Wi-Fi) cũng được mong đợi. Chi tiết chính xác sẽ xuất hiện vào Quý 3 năm 2027.

Runtime permission trên Android khác gì so với iOS?

iOS không hỗ trợ “quyền thông thường” — mỗi quyền được yêu cầu rõ ràng thông qua hộp thoại hệ thống. Người dùng có thể thu hồi quyền bất kỳ lúc nào thông qua cài đặt. Sự khác biệt chính là iOS không kiểm tra trạng thái quyền trước thông qua tương đương của checkSelfPermission: hệ thống tự động hiển thị hộp thoại khi lần đầu truy cập vào API được bảo vệ.

Tổng kết

  • Runtime Permission là cơ chế yêu cầu dữ liệu nhạy cảm tại thời điểm sử dụng thực tế, được giới thiệu trong Android 6.0.
  • Quyền nguy hiểm yêu cầu hộp thoại hệ thống rõ ràng; quyền thông thường được tự động phê duyệt.
  • Quyền một lần (Android 12+) bị thu hồi khi đóng ứng dụng, tăng cường quyền riêng tư của người dùng.
  • shouldShowRequestPermissionRationale xác định xem có từ chối trước đó hay không và giúp chọn chiến lược yêu cầu.
  • Android 13 đã thêm POST_NOTIFICATIONS như một runtime permission; Android 14 thắt chặt yêu cầu vị trí địa lý nền.
  • Trình chọn ảnh (API 33+) thay thế nhu cầu về READ_EXTERNAL_STORAGE để chọn ảnh.
  • Luôn cung cấp phương án dự phòng khi người dùng từ chối — cách thay thế để nhập dữ liệu hoặc chọn thủ công.

Chúng tôi sẽ phát triển ứng dụng di động chìa khóa trao tay

IT Sectr tạo các ứng dụng iOS và Android cho các công ty khởi nghiệp và doanh nghiệp từ năm 2017. Chúng tôi sẽ tư vấn và đề xuất giải pháp tốt nhất cho bạn.

Thảo luận dự án

Đọc thêm