Dangerous Permission trong Android: khái niệm, danh sách quyền và yêu cầu runtime

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

Dangerous Permission là một loại quyền trong Android yêu cầu sự đồng ý rõ ràng của người dùng thông qua hộp thoại runtime trong khi ứng dụng đang chạy. Theo Hướng dẫn nhà phát triển Android, 2024, quyền nguy hiểm có ProtectionLevel dangerous và cấp quyền truy cập vào dữ liệu nhạy cảm: camera, micrô, vị trí và danh bạ. Nếu không có sự đồng ý rõ ràng của người dùng, ứng dụng không thể sử dụng các tính năng này.

Những điểm chính

  • Dangerous Permission — quyền Android có ProtectionLevel dangerous yêu cầu yêu cầu runtime.
  • Yêu cầu được thực hiện qua ActivityCompat.requestPermissions với xử lý trong onRequestPermissionsResult.
  • Người dùng có thể thu hồi quyền nguy hiểm bất kỳ lúc nào qua Cài đặt của ứng dụng.
  • Trước khi yêu cầu, cần kiểm tra trạng thái qua ContextCompat.checkSelfPermission.
  • Danh sách bao gồm CAMERA, RECORD_AUDIO, ACCESS_FINE_LOCATION, READ_CONTACTS và các quyền khác.

Dangerous Permission trong Android là gì

Dangerous Permission là một loại quyền hệ thống Android cấp quyền truy cập vào dữ liệu nhạy cảm của người dùng. Không giống như quyền thông thường, quyền nguy hiểm không được cấp tự động khi cài đặt — ứng dụng phải yêu cầu chúng một cách rõ ràng trong thời gian chạy thông qua cơ chế runtime được giới thiệu trong Android 6.0 Marshmallow (API 23).

Sự cần thiết của yêu cầu rõ ràng xuất phát từ bản chất của dữ liệu mà các quyền này bảo vệ: vị trí người dùng, danh bạ cá nhân, nội dung camera và micrô, lịch sử cuộc gọi và SMS. Android coi dữ liệu này là nhạy cảm và yêu cầu người dùng cấp quyền truy cập một cách có ý thức. Theo Android Privacy Sandbox (2024), trung bình người dùng từ chối khoảng 30 phần trăm yêu cầu runtime.

Một tính năng chính của Dangerous Permission là khả năng thu hồi bất kỳ lúc nào. Người dùng có thể vào Cài đặt — Ứng dụng — Quyền và tắt bất kỳ quyền nguy hiểm nào. Ứng dụng phải sẵn sàng cho việc quyền đã được cấp trước đó có thể bị thu hồi bất kỳ lúc nào mà không cần khởi động lại.

ProtectionLevel dangerous

Mức bảo vệ dangerous được đặt trong định nghĩa quyền hệ thống ở cấp độ OS. Khi ứng dụng khai báo uses-permission với protectionLevel này, hệ thống đánh dấu quyền là yêu cầu runtime. Không giống như normal, quyền dangerous luôn được hiển thị trong giao diện quản lý quyền của hệ thống và có thể bị thu hồi.

Permission Group và Dangerous

Tất cả quyền nguy hiểm được nhóm thành Permission Groups theo loại chức năng. Ví dụ: CAMERA và CAMERA2 nằm trong nhóm CAMERA, ACCESS_FINE_LOCATION và ACCESS_COARSE_LOCATION nằm trong nhóm LOCATION. Nếu người dùng đã cấp một quyền từ một nhóm, các quyền còn lại trong cùng nhóm sẽ được cấp tự động mà không cần hộp thoại bổ sung.

Yêu cầu runtime hoạt động như thế nào

Yêu cầu runtime là cơ chế mà ứng dụng gọi API hệ thống để hiển thị hộp thoại yêu cầu quyền. Người dùng thấy cửa sổ phương thức với tên quyền và các nút Cho phép và Từ chối. Sau phản hồi, hệ thống gọi callback onRequestPermissionsResult với kết quả.

Chu trình đầy đủ bao gồm ba bước: kiểm tra trạng thái qua checkSelfPermission, gọi requestPermissions nếu quyền chưa được cấp và xử lý kết quả trong onRequestPermissionsResult. Kiểm tra trạng thái là bắt buộc vì người dùng có thể đã thu hồi quyền bất kỳ lúc nào qua cài đặt và gọi hàm mà không kiểm tra sẽ dẫn đến SecurityException.

kotlin
fun checkAndRequestCameraPermission() {
    when {
        ContextCompat.checkSelfPermission(
            this,
            Manifest.permission.CAMERA
        ) == PackageManager.PERMISSION_GRANTED -> {
            openCamera()
        }
        else -> {
            ActivityCompat.requestPermissions(
                this,
                arrayOf(Manifest.permission.CAMERA),
                REQUEST_CAMERA_CODE
            )
        }
    }
}

Xử lý kết quả diễn ra trong ActivityResultLauncher hoặc onRequestPermissionsResult. Cách tiếp cận hiện đại được khuyến nghị là sử dụng ActivityResultContracts.RequestPermission, cung cấp API sạch hơn mà không cần mã yêu cầu rõ ràng. Hợp đồng này trả về Boolean — quyền đã được cấp hay chưa.

Các phương pháp hay nhất khi yêu cầu

Yêu cầu quyền nguy hiểm một cách nghiêm ngặt trong bối cảnh sử dụng tính năng, không phải khi khởi động ứng dụng. Nếu người dùng đã nhấn nút camera — hãy yêu cầu CAMERA. Nếu họ mở bản đồ — hãy yêu cầu LOCATION. Yêu cầu theo ngữ cảnh mang lại số lần cấp quyền gấp đôi so với yêu cầu tất cả quyền khi khởi chạy lần đầu. Cũng nên không yêu cầu nhiều hơn một quyền cùng lúc để người dùng hiểu tính năng nào cần truy cập.

Danh sách quyền nguy hiểm trong Android

Android định nghĩa một số nhóm quyền nguy hiểm, mỗi nhóm chứa một hoặc nhiều hằng số. Danh sách đầy đủ nhất có sẵn trong lớp Manifest.permission. Dưới đây là các nhóm và quyền chính được sử dụng trong phát triển.

Nhóm quyềnQuyềnAPI truy cập
CAMERACAMERACamera API, CameraX
LOCATIONACCESS_FINE_LOCATION, ACCESS_COARSE_LOCATIONFusedLocationProvider, Geofence
MICROPHONERECORD_AUDIOMediaRecorder, AudioRecord
PHONEREAD_PHONE_STATE, CALL_PHONE, READ_CALL_LOGTelephonyManager
CONTACTSREAD_CONTACTS, WRITE_CONTACTS, GET_ACCOUNTSContactsContract
SMSREAD_SMS, SEND_SMS, RECEIVE_SMSSmsManager
STORAGEREAD_EXTERNAL_STORAGE, WRITE_EXTERNAL_STORAGEMediaStore, File API
CALENDARREAD_CALENDAR, WRITE_CALENDARCalendarContract

Quyền mới trong Android 12+

Bắt đầu từ Android 12, Google đã thắt chặt yêu cầu đối với một số quyền. Ví dụ: BLUETOOTH_CONNECT và BLUETOOTH_SCAN đã trở nên nguy hiểm và yêu cầu yêu cầu runtime. Quyền BODY_SENSORS_BACKGROUND cũng được thêm vào để truy cập nền vào cảm biến. Các nhà phát triển cần cập nhật targetSdkVersion và kiểm tra yêu cầu trên các phiên bản OS hiện tại.

Quyền cho Android 13+

Android 13 (API 33) đã giới thiệu các quyền mới cho thông báo (POST_NOTIFICATIONS) và tệp phương tiện (READ_MEDIA_IMAGES, READ_MEDIA_VIDEO, READ_MEDIA_AUDIO), thay thế READ_EXTERNAL_STORAGE chung. Giờ đây, quyền truy cập vào ảnh, video và âm thanh được yêu cầu riêng biệt thông qua các quyền chuyên dụng mà không có hộp thoại đơn lẻ.

Dangerous vs Normal Permission

Quyền Dangerous và Normal khác nhau cơ bản về cách cấp, khả năng thu hồi và UX. Normal được cấp tự động khi cài đặt, Dangerous yêu cầu hộp thoại runtime rõ ràng. Normal không thể thu hồi qua cài đặt, Dangerous có thể bị vô hiệu hóa bất kỳ lúc nào. Sự bất đối xứng này tạo ra các mẫu phát triển khác nhau.

Từ góc độ mã, quyền nguy hiểm đòi hỏi nhiều công việc hơn: checkSelfPermission, requestPermissions, xử lý từ chối. Đối với quyền thông thường, một dòng trong AndroidManifest.xml là đủ. Tuy nhiên, Dangerous Permission trao quyền kiểm soát cho người dùng, điều này tăng sự tin cậy, đặc biệt đối với các tính năng nhạy cảm như camera hoặc vị trí.

Việc lựa chọn giữa các loại không phụ thuộc vào nhà phát triển — nó được xác định bởi hệ thống. Nhà phát triển chỉ khai báo uses-permission và hệ thống xác định loại dựa trên protectionLevel. Tuy nhiên, chiến lược yêu cầu quyền nguy hiểm ảnh hưởng đến trải nghiệm người dùng: hộp thoại thường xuyên hoặc không phù hợp làm giảm xếp hạng ứng dụng.

Cách yêu cầu quyền trong Kotlin

Cách hiện đại để yêu cầu quyền trong Kotlin là sử dụng ActivityResultContracts.RequestMultiplePermissions hoặc RequestPermission. Các hợp đồng này là một phần của thư viện androidx.activity và cung cấp API sạch dựa trên lambda, không cần ghi đè onRequestPermissionsResult.

kotlin
class CameraActivity : AppCompatActivity() {
    private val requestPermissionLauncher =
        registerForActivityResult(
            ActivityResultContracts.RequestPermission()
        ) { isGranted: Boolean ->
            if (isGranted) {
                openCamera()
            } else {
                showPermissionDeniedMessage()
            }
        }

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

Yêu cầu nhiều quyền cùng lúc

Khi ứng dụng cần nhiều quyền nguy hiểm cùng lúc, hãy sử dụng RequestMultiplePermissions. Hợp đồng trả về Map<String, Boolean> trong đó khóa là tên quyền và giá trị là kết quả. Điều này hữu ích khi khởi chạy lần đầu khi bạn cần yêu cầu CAMERA và RECORD_AUDIO để ghi video.

Xử lý từ chối lần đầu

Nếu người dùng từ chối yêu cầu, phương thức shouldShowRequestPermissionRationale trả về true. Điều này báo hiệu cần hiển thị giải thích lý do cần quyền. Thực hành tốt nhất là hiển thị hộp thoại tùy chỉnh với giải thích và nút Thử lại. Nếu người dùng từ chối yêu cầu lần nữa với hộp kiểm Never Ask Again được chọn, shouldShowRequestPermissionRationale sẽ trả về false và bạn cần chuyển hướng đến Cài đặt.

Xử lý từ chối và Never Ask Again

Never Ask Again là cờ mà người dùng có thể đặt khi từ chối hộp thoại runtime lần thứ hai. Sau đó, hộp thoại tiêu chuẩn không còn được hiển thị cho quyền đó nữa. Cách duy nhất để cấp quyền truy cập là chuyển hướng người dùng đến cài đặt ứng dụng hệ thống.

Nhà phát triển cần phân biệt hai kịch bản từ chối: thứ nhất, khi shouldShowRequestPermissionRationale trả về true (người dùng từ chối nhưng hộp thoại vẫn có thể hiển thị) và thứ hai, khi phương thức trả về false (Never Ask Again đang hoạt động hoặc quyền bị chặn bởi chính sách). Trong trường hợp thứ hai, bạn nên hiển thị nút Mở Cài đặt.

kotlin
fun handlePermissionDenied(permission: String) {
    if (ActivityCompat.shouldShowRequestPermissionRationale(
            this, permission
    )) {
        showRationaleDialog(permission)
    } else {
        showSettingsRedirectDialog(permission)
    }
}

private fun showSettingsRedirectDialog(permission: String) {
    AlertDialog.Builder(this)
        .setTitle("Truy cập bị từ chối")
        .setMessage(
            "Quyền bị chặn. Mở Cài đặt."
        )
        .setPositiveButton("Cài đặt") { _, _ ->
            val intent = Intent(
                Settings.ACTION_APPLICATION_DETAILS_SETTINGS,
                Uri.fromParts(
                    "package", packageName, null
                )
            )
            startActivity(intent)
        }
        .show()
}

Điều quan trọng là không yêu cầu lại quyền nếu shouldShowRequestPermissionRationale đã trả về false. Việc gọi lại requestPermissions trong trường hợp này sẽ không hiển thị hộp thoại — kết quả sẽ trả về ngay lập tức với DENIED mà không có giải thích. Người dùng sẽ gặp phải hành vi không rõ ràng, ảnh hưởng tiêu cực đến trải nghiệm sử dụng ứng dụng.

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

Những quyền nào được coi là nguy hiểm trong Android?

Quyền nguy hiểm bao gồm các quyền có ProtectionLevel dangerous: CAMERA, RECORD_AUDIO, ACCESS_FINE_LOCATION, READ_CONTACTS, READ_SMS, READ_CALENDAR và các quyền khác. Danh sách đầy đủ có sẵn trong lớp Manifest.permission.

Làm thế nào để kiểm tra quyền nguy hiểm đã được cấp chưa?

Sử dụng ContextCompat.checkSelfPermission, truyền context và tên quyền. Phương thức trả về PERMISSION_GRANTED hoặc PERMISSION_DENIED. Việc kiểm tra nên được thực hiện trước mỗi lần gọi API yêu cầu quyền nguy hiểm.

Permission Group cho quyền nguy hiểm là gì?

Permission Group nhóm các quyền nguy hiểm liên quan lại với nhau. Nếu người dùng cấp một quyền từ một nhóm, các quyền còn lại được cấp tự động. Ví dụ: LOCATION bao gồm ACCESS_FINE_LOCATION và ACCESS_COARSE_LOCATION.

Làm thế nào để xử lý Never Ask Again?

Kiểm tra shouldShowRequestPermissionRationale sau khi từ chối. Nếu phương thức trả về false và quyền vẫn chưa được cấp — Never Ask Again đang hoạt động. Chuyển hướng người dùng đến Cài đặt qua Intent với ACTION_APPLICATION_DETAILS_SETTINGS.

Có cần quyền nguy hiểm trên Android 13+ không?

Có, chúng vẫn bắt buộc. Trên Android 13+, một số quyền đã thay đổi: POST_NOTIFICATIONS trở thành quyền runtime riêng biệt và READ_EXTERNAL_STORAGE được thay thế bằng READ_MEDIA_IMAGES để truy cập chi tiết vào tệp phương tiện.

Tổng kết

  • Dangerous Permission — quyền Android có ProtectionLevel dangerous yêu cầu yêu cầu runtime rõ ràng từ người dùng.
  • Cơ chế bao gồm ba bước: checkSelfPermission, requestPermissions và onRequestPermissionsResult.
  • Người dùng có thể thu hồi quyền nguy hiểm bất kỳ lúc nào qua cài đặt hệ thống.
  • Các nhóm chính: CAMERA, LOCATION, MICROPHONE, PHONE, CONTACTS, SMS, STORAGE, CALENDAR.
  • ActivityResultContracts.RequestPermission là API hiện đại để yêu cầu trong Kotlin mà không cần mã yêu cầu.
  • ShouldShowRequestPermissionRationale giúp phân biệt lần từ chối đầu tiên và Never Ask Again.
  • Trên Android 13+, các quyền mới đã xuất hiện: POST_NOTIFICATIONS và READ_MEDIA_IMAGES thay thế STORAGE.

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