Permission Group là cơ chế nhóm quyền trong Android, kết hợp các quyền nguy hiểm có liên quan về chức năng vào một danh mục logic. Theo Android Permissions Overview, 2024, nhóm quyền đơn giản hóa giao diện người dùng: 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 mà không cần hộp thoại bổ sung. Điều này giảm số lượng yêu cầu và cải thiện UX.
Những điểm chính
Permission Group là cơ chế hệ thống Android nhóm nhiều quyền nguy hiểm vào một nhóm dựa trên mục đích chức năng của chúng. Mỗi nhóm có một định danh chuỗi, ví dụ android.permission-group.CAMERA hoặc android.permission-group.LOCATION. Tất cả quyền trong một nhóm có liên quan logic và cung cấp quyền truy cập vào các chức năng liên quan của thiết bị.
Nhóm quyền xuất hiện trong Android 6.0 Marshmallow cùng với mô hình quyền runtime. Mục đích chính của chúng là đơn giản hóa tương tác với người dùng: thay vì một loạt hộp thoại cho từng quyền riêng lẻ, hệ thống hiển thị một hộp thoại cho mỗi nhóm. 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 coi là tự động được phê duyệt. Theo Android UX Research (2015), điều này đã giảm số lần từ chối khi khởi chạy lần đầu xuống 20 phần trăm.
Điều quan trọng là nhà phát triển không thể tạo Permission Group của riêng mình. Các nhóm được xác định trước ở cấp hệ điều hành và được mô tả trong tệp permissions.xml trên mỗi thiết bị. Ứng dụng chỉ khai báo uses-permission, và hệ thống tự động ánh xạ quyền vào nhóm của nó dựa trên protectionLevel và phân loại trong AOSP.
Việc ánh xạ quyền vào nhóm diễn ra thông qua thuộc tính permissionGroup trong định nghĩa quyền hệ thống. Ví dụ, CAMERA được khai báo với permissionGroup="android.permission-group.CAMERA", ACCESS_FINE_LOCATION với permissionGroup="android.permission-group.LOCATION". Ánh xạ này được mã hóa cứng trong mã Android Open Source Project và giống nhau trên tất cả các thiết bị được chứng nhận.
Cơ chế nhóm hoạt động theo nguyên tắc “một hộp thoại cho mỗi nhóm”. Khi một ứng dụng lần đầu tiên yêu cầu bất kỳ quyền nguy hiểm nào, hệ thống sẽ kiểm tra Permission Group của nó. Nếu chưa có quyền nào từ nhóm này được cấp — một hộp thoại sẽ hiển thị. Sau khi đồng ý, hệ thống đánh dấu toàn bộ nhóm là đã được cấp, và các yêu cầu tiếp theo cho các quyền khác từ cùng nhóm được đáp ứng mà không cần giao diện người dùng.
Thuật toán đơn giản hóa trông như sau:
Cơ chế này chỉ áp dụng cho quyền nguy hiểm. Quyền bình thường không có nhóm và không tham gia vào logic này. Quyền đặc quyền và quyền chữ ký cũng không được nhóm — chúng có hệ thống kiểm soát truy cập riêng.
Các nhóm không hoạt động “theo chiều ngược”: thu hồi một quyền từ một nhóm qua cài đặt chỉ thu hồi quyền đó mà không ảnh hưởng đến các quyền khác. Ngoài ra, nếu người dùng từ chối hộp thoại cho một nhóm, điều này không chặn các nhóm khác — mỗi quyền mới từ một nhóm khác sẽ hiển thị hộp thoại riêng của nó. Permission Group chỉ ảnh hưởng đến UX yêu cầu, không ảnh hưởng đến mô hình bảo mật.
Android định nghĩa các Permission Group hệ thống sau cho quyền nguy hiểm. Mỗi nhóm bao gồm một hoặc nhiều quyền được thống nhất bởi một mục đích chức năng chung.
| Định danh nhóm | Quyền trong nhóm | Mô tả |
|---|---|---|
| CAMERA | CAMERA | Truy cập camera thiết bị |
| LOCATION | ACCESS_FINE_LOCATION, ACCESS_COARSE_LOCATION | Vị trí địa lý (chính xác và gần đúng) |
| MICROPHONE | RECORD_AUDIO | Ghi âm qua micro |
| PHONE | READ_PHONE_STATE, CALL_PHONE, READ_CALL_LOG, WRITE_CALL_LOG, ADD_VOICEMAIL, USE_SIP | Chức năng điện thoại |
| CONTACTS | READ_CONTACTS, WRITE_CONTACTS, GET_ACCOUNTS | Truy cập danh bạ và tài khoản |
| SMS | READ_SMS, SEND_SMS, RECEIVE_SMS, RECEIVE_WAP_PUSH, RECEIVE_MMS | Gửi và nhận SMS |
| STORAGE | READ_EXTERNAL_STORAGE, WRITE_EXTERNAL_STORAGE | Đọc và ghi bộ nhớ ngoài |
| CALENDAR | READ_CALENDAR, WRITE_CALENDAR | Truy cập lịch |
| SENSORS | BODY_SENSORS | Cảm biến cơ thể (nhịp tim và các cảm biến khác) |
| ACTIVITY_RECOGNITION | ACTIVITY_RECOGNITION | Nhận dạng hoạt động thể chất |
Trên Android 13 (API 33), một nhóm mới NEARBY_DEVICES đã xuất hiện, kết hợp BLUETOOTH_SCAN, BLUETOOTH_CONNECT và BLUETOOTH_ADVERTISE. Ngoài ra, nhóm STORAGE đã được thay thế một phần bằng quyền phương tiện READ_MEDIA_IMAGES, READ_MEDIA_VIDEO và READ_MEDIA_AUDIO, không phải là một phần của STORAGE mà là quyền nguy hiểm độc lập không có nhóm.
Nhà phát triển có thể khai báo quyền riêng với Permission Group tùy chỉnh thông qua thuộc tính permissionGroup trong tệp kê khai. Tuy nhiên, điều này chỉ hoạt động cho quyền tùy chỉnh của cùng một ứng dụng và không ảnh hưởng đến hộp thoại giao diện hệ thống. Trong thực tế, Permission Group tùy chỉnh hiếm khi được sử dụng — để tương tác giữa các ứng dụng trong cùng một stack.
Tác động của Permission Group đến trải nghiệm người dùng là đáng kể. Nhờ việc nhóm, người dùng không thấy 8 hộp thoại riêng biệt cho các quyền khác nhau, mà chỉ thấy một vài hộp thoại nhóm. Điều này giảm tải nhận thức và giảm khả năng người dùng từ chối một quyền quan trọng mà không hiểu mục đích của nó.
Nghiên cứu UX cho thấy hộp thoại nhóm được người dùng cảm nhận là minh bạch hơn. Khi một ứng dụng yêu cầu “quyền truy cập camera”, người dùng hiểu ngữ cảnh. Nếu mỗi quyền được yêu cầu riêng lẻ — CAMERA, CAMERA2, FLASHLIGHT — nó sẽ tạo ấn tượng về sự dư thừa. Permission Group trừu tượng hóa sự chi tiết này.
Thực hành tốt nhất là yêu cầu quyền chỉ từ một nhóm tại một thời điểm. Nếu một ứng dụng cần cả camera và vị trí, đừng yêu cầu chúng trong một lần gọi requestPermissions. Đầu tiên yêu cầu một nhóm sau khi giải thích lý do cần nó, sau đó yêu cầu nhóm thứ hai. Điều này mang lại cho người dùng quyền kiểm soát và sự hiểu biết tuần tự về từng chức năng.
Permission Group và ProtectionLevel là hai chiều khác nhau của hệ thống quyền Android. ProtectionLevel xác định cách một quyền được cấp (normal, dangerous, signature, privileged), trong khi Permission Group là một danh mục để hiển thị trên giao diện người dùng. Chúng độc lập, nhưng trong thực tế, sự kết hợp dangerous + permission group là phổ biến nhất.
Các quyền cùng ProtectionLevel có thể thuộc các nhóm khác nhau. Ví dụ, ACCESS_FINE_LOCATION và CAMERA đều có protectionLevel dangerous nhưng thuộc các nhóm khác nhau — LOCATION và CAMERA. Và ngược lại, các quyền cùng tên luôn thuộc cùng một nhóm: ACCESS_FINE_LOCATION và ACCESS_COARSE_LOCATION đều trong LOCATION.
Các cấp bảo vệ cao hơn — signature và privileged — không sử dụng Permission Group cho giao diện người dùng. Việc cấp chúng được kiểm soát ở cấp hệ thống: signature được cấp cho ứng dụng được ký bằng cùng chứng chỉ với hệ thống, và privileged cho ứng dụng trong hình ảnh hệ thống. Nhóm cho các quyền như vậy tồn tại nhưng không ảnh hưởng đến hộp thoại UX vì các hộp thoại này đơn giản là không xuất hiện.
Nhà phát triển có thể xác định theo chương trình Permission Group của bất kỳ quyền nào thông qua PackageManager. Phương thức getPermissionInfo trả về PermissionInfo với trường group chứa định danh chuỗi của nhóm. Điều này hữu ích cho ghi nhật ký, phân tích và màn hình quyền giao diện tùy chỉnh.
fun getPermissionGroupName(
permission: String
): String? {
return try {
val pm = packageManager
val info = pm.getPermissionInfo(
permission,
PackageManager.GET_META_DATA
)
info.group
} catch (e: NameNotFoundException) {
null
}
}
fun getPermissionsByGroup(
group: String
): List<String> {
val pm = packageManager
val perms = pm.queryPermissionsByGroup(
group,
PackageManager.GET_META_DATA
)
return perms.map { it.name }
}
Kiến thức về Permission Group giúp xây dựng kiến trúc yêu cầu. Bạn có thể tạo một lớp trừu tượng gọi là PermissionGroupProvider trả về danh sách quyền cho một nhóm cụ thể. Điều này đơn giản hóa việc kiểm thử: trong kiểm thử đơn vị, nhà cung cấp trả về dữ liệu giả mà không gọi PackageManager. Trong kiểm thử công cụ, nó trả về nhóm thực từ hệ thống.
Tích hợp PermissionGroupProvider qua Dagger Hilt hoặc Koin cho phép quản lý tập trung việc ánh xạ quyền sang nhóm. Trong nhà cung cấp, bạn có thể lưu kết quả của PackageManager.queryPermissionsByGroup vào bộ nhớ đệm để tránh các cuộc gọi hệ thống lặp lại cho mỗi yêu cầu. Điều này đặc biệt quan trọng đối với màn hình cài đặt nơi hiển thị danh sách đầy đủ các quyền và trạng thái của chúng.
Khi thu thập phân tích về các lần từ chối, việc ghi nhật ký không chỉ tên quyền mà còn cả Permission Group của nó là hữu ích. Điều này giúp xác định lĩnh vực chức năng nào gây ra nhiều từ chối nhất. Ví dụ, nhóm LOCATION theo truyền thống có tỷ lệ từ chối cao nhất — khoảng 40 phần trăm, theo thống kê của Google Play Console.
Phân tích theo nhóm giúp đưa ra quyết định sản phẩm: nếu nhóm CONTACTS có tỷ lệ từ chối cao, có thể cần xem xét lại thời điểm yêu cầu hoặc thêm hộp thoại giải thích lý do. Cách tiếp cận dựa trên nhóm để phân tích cung cấp bức tranh toàn diện hơn so với phân tích từng quyền riêng lẻ, vì số lần từ chối trên toàn bộ nhóm phản ánh thái độ chung của người dùng đối với một lĩnh vực chức năng.
Các câu hỏi thường gặp
Permission Group là cơ chế kết hợp các quyền nguy hiểm có liên quan về chức năng vào một danh mục. 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 mà không cần hộp thoại bổ sung.
Android tiêu chuẩn có khoảng 10 nhóm chính: CAMERA, LOCATION, MICROPHONE, PHONE, CONTACTS, SMS, STORAGE, CALENDAR, SENSORS và ACTIVITY_RECOGNITION. Android 13+ đã thêm NEARBY_DEVICES.
Có, thông qua thuộc tính permissionGroup trong AndroidManifest.xml cho quyền tùy chỉnh. Nhưng điều này chỉ hoạt động cho quyền trong ứng dụng và không ảnh hưởng đến hộp thoại giao diện hệ thống. Trong thực tế, hiếm khi được sử dụng.
Thu hồi một quyền từ một nhóm không thu hồi các quyền khác. Người dùng có thể vô hiệu hóa ACCESS_FINE_LOCATION, nhưng ACCESS_COARSE_LOCATION vẫn hoạt động. Nhóm chỉ ảnh hưởng đến việc cấp, không ảnh hưởng đến việc thu hồi.
Sử dụng PackageManager.getPermissionInfo và đọc trường group. Phương thức trả về định danh chuỗi của nhóm, ví dụ android.permission-group.CAMERA. Nếu quyền không có nhóm, trường sẽ là null.
Tổng kết
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.
Đọc thêm