Mọi ứng dụng Android đều chạy trong một hộp cát bị giới hạn về khả năng truy cập. Nếu ứng dụng của bạn cần sử dụng tài nguyên hoặc thông tin bên ngoài hộp cát, thì bạn có thể khai báo một quyền và thiết lập yêu cầu cấp quyền truy cập này. Các bước này là một phần trong quy trình sử dụng quyền. Show
Nếu bạn khai báo bất kỳ quyền nguy hiểm nào và nếu ứng dụng được cài đặt trên thiết bị chạy Android 6.0 (API cấp 23) trở lên, bạn phải yêu cầu các quyền nguy hiểm đó trong thời gian chạy bằng cách làm theo các bước trong hướng dẫn này. Nếu bạn không khai báo bất kỳ quyền nguy hiểm nào hoặc nếu ứng dụng được cài đặt trên thiết bị chạy Android 5.1 (API cấp 22) trở xuống, thì các quyền đó sẽ tự động được cấp và bạn không cần hoàn thành bất kỳ bước nào còn lại trên trang này. Nguyên tắc cơ bảnNguyên tắc cơ bản để yêu cầu cấp quyền trong thời gian chạy bao gồm:
Quy trình yêu cầu cấp quyềnTrước khi bạn khai báo và yêu cầu cấp quyền khi bắt đầu chạy trong ứng dụng, hãy đánh giá xem liệu ứng dụng có cần làm như vậy hay không. Bạn có thể thực hiện nhiều trường hợp sử dụng trong ứng dụng của mình, chẳng hạn như chụp ảnh, tạm dừng phát lại nội dung nghe nhìn và hiển thị quảng cáo phù hợp mà không cần khai báo bất kỳ quyền nào. Nếu bạn kết luận rằng ứng dụng cần khai báo và yêu cầu cấp quyền khi bắt đầu chạy, thì hoàn tất các bước sau:
Hình 1 minh hoạ quy trình làm việc và tập hợp các quyết định liên quan đến quy trình này: HÌnh 1. Sơ đồ cho thấy quy trình khai báo và yêu cầu cấp quyền khi bắt đầu chạy trên Android.Xác định xem liệu ứng dụng của bạn đã được cấp quyền hay chưaĐể kiểm tra xem người dùng đã cấp cho ứng dụng một quyền cụ thể hay chưa, chuyển quyền đó vào phương thức ContextCompat.checkSelfPermission(). Phương thức này trả về PERMISSION_GRANTED hoặc PERMISSION_DENIED, tuỳ thuộc vào việc ứng dụng của bạn có quyền hay không. Giải thích vì sao ứng dụng của bạn cần quyền truy cậpHộp thoại cấp quyền được hệ thống hiển thị khi bạn gọi requestPermissions() cho biết ứng dụng muốn có quyền gì, nhưng không cho biết lý do vì sao. Trong một số trường hợp, người dùng có thể thấy khó hiểu. Nên giải thích cho người dùng tại sao ứng dụng muốn có quyền trước khi bạn gọi requestPermissions(). Nghiên cứu cho thấy rằng người dùng cảm thấy thoải mái hơn với các yêu cầu cấp quyền nếu họ biết tại sao ứng dụng cần các yêu cầu đó. Một nghiên cứu về người dùng cho thấy:
...việc người dùng sẵn sàng cấp quyền nhất định cho một ứng dụng di động nhất định chịu ảnh hưởng rất lớn bởi mục đích liên quan đến quyền đó. Ví dụ: việc người dùng sẵn sàng cấp quyền truy cập vào thông tin vị trí của họ là khác nhau tuỳ thuộc vào việc liệu yêu cầu có cần để hỗ trợ chức năng cốt lõi của ứng dụng hay không hoặc liệu yêu cầu đó là để chia sẻ thông tin này với một mạng quảng cáo hay một công ty phân tích.1 Sau khi cộng tác với nhiều người khác để nghiên cứu về chủ đề này, Giáo sư Jason Hong đến từ CMU đã kết luận rằng: nói chung,
...khi mọi người biết lý do ứng dụng sử dụng những thông tin nhạy cảm như vị trí của họ — ví dụ: để quảng cáo nhắm mục tiêu — thì họ sẽ cảm thấy thoải mái hơn so với khi chỉ được thông báo một ứng dụng đang sử dụng thông tin vị trí của họ.1 Do đó, nếu bạn chỉ sử dụng một phần các lệnh gọi API thuộc một nhóm quyền, thì việc này sẽ giúp bạn liệt kê rõ ràng những quyền bạn đang sử dụng và lý do tại sao. Ví dụ:
Trong một số tình huống nhất định, việc cho người dùng biết về quyền truy cập dữ liệu nhạy cảm theo thời gian thực cũng là một lợi thế. Ví dụ: nếu đang truy cập vào camera hoặc micrô, bạn nên cho người dùng biết bằng biểu tượng thông báo ở một nơi nào đó trong ứng dụng hoặc trong khay thông báo (nếu ứng dụng đang chạy ở chế độ nền), để bạn không có vẻ như đang lén lút thu thập dữ liệu. Cuối cùng, nếu cần một quyền để khiến điều gì đó trong ứng dụng hoạt động, nhưng người dùng lại không rõ lý do, hãy tìm cách cho người dùng biết tại sao bạn cần các quyền truy cập thông tin nhạy cảm nhất. Nếu phương thức ContextCompat.checkSelfPermission() trả về PERMISSION_DENIED, gọi shouldShowRequestPermissionRationale(). Nếu phương thức này trả về true, hiển thị giao diện hướng dẫn người dùng cho người dùng. Trong giao diện người dùng này, mô tả lý do tính năng, mà người dùng muốn bật, cần có một quyền cụ thể. Ngoài ra, nếu ứng dụng của bạn yêu cầu một quyền liên quan đến vị trí, micrô hoặc camera, hãy cân nhắc giải thích lý do ứng dụng của bạn cần quyền truy cập vào thông tin này. Yêu cầu cấp quyềnHãy yêu cầu cấp quyền sau khi người dùng xem giao diện người dùng hướng dẫn hoặc giá trị trả về của shouldShowRequestPermissionRationale() cho biết bạn không cần hiển thị giao diện người dùng hướng dẫn lần này. Người dùng sẽ thấy hộp thoại cấp quyền của hệ thống, trong đó họ có thể chọn có cấp một quyền cụ thể cho ứng dụng của bạn hay không. Thường thì bạn tự quản lý mã yêu cầu trong yêu cầu cấp quyền và đưa mã yêu cầu này vào logic gọi lại quyền của mình. Một tuỳ chọn khác là sử dụng hợp đồng RequestPermission, nằm trong thư viện AndroidX, trong đó bạn cho phép hệ thống quản lý mã yêu cầu cấp quyền cho bạn. Vì việc sử dụng hợp đồng RequestPermission đơn giản hoá logic, do vậy bạn nên sử dụng hợp đồng này mỗi khi có thể. Cho phép hệ thống quản lý mã yêu cầu cấp quyềnĐể cho phép hệ thống quản lý mã yêu cầu dược liên kết với yêu cầu cấp quyền, thêm các phần phụ thuộc có trong những thư viện sau vào tệp build.gradle của mô-đun: Sau đó, bạn có thể sử dụng một trong các lớp sau: Các bước sau đây cho biết cách sử dụng hợp đồng RequestPermission. Quy trình gần giống với quy trình cho hợp đồng RequestMultiplePermissions.
Đoạn mã sau đây cho thấy cách xử lý phản hồi cấp quyền:
Đoạn mã này minh hoạ quy trình đề xuất để kiểm tra một quyền và yêu cầu người dùng cấp quyền khi cần:
Tự quản lý mã yêu cầu cấp quyềnThay vì cho phép hệ thống quản lý mã yêu cầu cấp quyền, bạn có thể tự quản lý mã yêu cầu cấp quyền này. Để thực hiện việc này, đưa mã yêu cầu vào lệnh gọi requestPermissions(). Lưu ý: Ứng dụng của bạn không thể tuỳ chỉnh hộp thoại được xuất hiện khi bạn gọi requestPermissions(). Văn bản trong hộp thoại cấp quyền của hệ thống tham chiếu đến một nhóm quyền nhưng nhóm quyền này được thiết kế để giúp bạn dễ sử dụng hệ thống. Ứng dụng của bạn không nên dựa vào các quyền nằm trong hoặc ngoài một nhóm quyền cụ thể.Đoạn mã sau đây minh hoạ cách yêu cầu cấp quyền bằng mã yêu cầu:
Sau khi người dùng phản hồi với hộp thoại cấp quyền hệ thống, thì hệ thống sẽ gọi chế độ triển khai onRequestPermissionsResult() của ứng dụng. Hệ thống sẽ chuyển phản hồi người dùng tới hộp thoại cấp quyền, cũng như mã yêu cầu mà bạn đã xác định, như được cho thấy trong đoạn mã sau:
Yêu cầu cấp nhiều quyềnKhi bạn yêu cầu cấp quyền về vị trí, làm theo các phương pháp hay nhất cũng như đối với mọi quyền bắt đầu khi chạy khác. Một khác biệt quan trọng khi nói đến cấp quyền về vị trí là hệ thống bao gồm nhiều quyền liên quan đến vị trí. Quyền bạn yêu cầu và cách bạn yêu cầu quyền đó tuỳ thuộc vào các yêu cầu về vị trí đối với trường hợp sử dụng của ứng dụng. Vị trí nền trướcNếu ứng dụng của bạn chứa một tính năng chỉ chia sẻ hoặc nhận thông tin vị trí một lần hoặc trong một khoảng thời gian xác định, thì tính năng đó sẽ yêu cầu quyền truy cập thông tin vị trí ở chế độ nền trước. Sau đây là một số ví dụ:
Hệ thống sẽ coi ứng dụng của bạn đang sử dụng thông tin vị trí ở chế độ nền trước nếu một tính năng của ứng dụng truy cập vào vị trí hiện tại của thiết bị ở một trong các tình huống sau:
Bạn khai báo nhu cầu về thông tin vị trí ở chế độ nền trước khi ứng dụng yêu cầu cấp quyền ACCESS_COARSE_LOCATION hoặc quyền ACCESS_FINE_LOCATION, như được hiển thị trong đoạn mã sau: <manifest ... > <!-- Always include this permission --> <uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" /> <!-- Include only if your app benefits from precise location access. --> <uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" /> </manifest>Quyền truy cập thông tin vị trí ở chế độ nềnỨng dụng sẽ yêu cầu quyền truy cập thông tin vị trí ở chế độ nền nếu một tính năng trong ứng dụng đó liên tục chia sẻ vị trí với người dùng khác hoặc sử dụng API Khoanh vùng địa lý. Sau đây là một số ví dụ:
Hệ thống sẽ coi ứng dụng của bạn đang sử dụng thông tin vị trí ở chế độ nền nếu ứng dụng truy cập vào thông tin vị trí hiện tại của thiết bị trong bất kỳ tình huống nào trừ những tình huống được mô tả trong phần thông tin vị trí ở chế độ nền trước. Độ chính xác của vị trí ở chế độ nền giống như độ chính xác của vị trí ở chế độ nền trước, tuỳ thuộc vào quyền truy cập thông tin vị trí mà ứng dụng của bạn khai báo. Trên Android 10 (API cấp 29) trở lên, bạn phải khai báo ACCESS_BACKGROUND_LOCATIONquyền trong tệp kê khai của ứng dụng để yêu cầu quyền truy cập thông tin vị trí ở chế độ nền trong thời gian chạy. Trên các phiên bản Android cũ, khi ứng dụng nhận được quyền truy cập thông tin vị trí ở chế độ nền trước, ứng dụng đó cũng tự động nhận được quyền truy cập thông tin vị trí ở chế độ nền. <manifest ... > <!-- Required only when requesting background location access on Android 10 (API level 29) and higher. --> <uses-permission android:name="android.permission.ACCESS_BACKGROUND_LOCATION" /> </manifest> Lưu ý: Cửa hàng Google Play có chính sách về vị trí liên quan đến vị trí của thiết bị, chỉ cấp quyền truy cập thông tin vị trí ở chế độ nền cho các ứng dụng cần quyền này để thực hiện chức năng cốt lõi và đáp ứng các yêu cầu liên quan của chính sách.Xử lý việc từ chối cấp quyềnNếu người dùng từ chối yêu cầu cấp quyền, ứng dụng của bạn sẽ giúp người dùng hiểu hệ quả của việc từ chối cấp quyền. Cụ thể, ứng dụng của bạn phải thông báo cho người dùng về những tính năng sẽ không hoạt động do không có quyền. Khi bạn làm như vậy, lưu ý các phương pháp hay nhất sau:
Đồng thời, ứng dụng của bạn nên tôn trọng quyết định từ chối cấp quyền của người dùng. Kể từ Android 11 (API cấp 30), nếu người dùng nhiều lần nhấn vào Từ chối với một quyền cụ thể trong suốt thời gian ứng dụng của bạn được cài đặt trên thiết bị, thì người dùng sẽ không xem hộp thoại cấp quyền của hệ thống nếu ứng dụng của bạn yêu cầu cấp lại quyền đó. Hành động của người dùng ngụ ý "không hỏi lại". Trên các phiên bản trước, người dùng sẽ thấy hộp thoại cấp quyền của hệ thống mỗi khi ứng dụng của bạn yêu cầu cấp quyền, trừ khi trước đó người dùng đã chọn hộp đánh dấu hoặc tuỳ chọn "không hỏi lại". Nếu người dùng từ chối yêu cầu cấp quyền nhiều lần, thì hành động này được coi là từ chối vĩnh viễn. Đặc biệt quan trọng là chỉ nên nhắc người dùng cấp quyền khi họ cần truy cập vào một tính năng cụ thể, nếu không, bạn có thể vô tình mất khả năng yêu cầu cấp quyền lần nữa. Trong một số trường hợp nhất định, quyền có thể tự động bị từ chối mà không cần người dùng thực hiện bất kỳ hành động nào. (Tương tự, một quyền cũng có thể được cấp tự động.) Bạn không nên giả định bất kỳ điều gì về hành vi tự động. Mỗi khi ứng dụng cần truy cập chức năng yêu cầu cấp quyền, bạn nên kiểm tra để biết ứng dụng vẫn được cấp quyền đó. Để cung cấp trải nghiệm người dùng tốt nhất khi yêu cầu cấp quyền cho ứng dụng, bạn cũng nên xem Các phương pháp hay nhất về cấp quyền cho ứng dụng. Cấp quyền một lầnFigure 2. Hộp thoại hệ thống xuất hiện khi ứng dụng yêu cầu cấp quyền một lần.Kể từ Android 11 (API cấp 30), bất cứ khi nào ứng dụng yêu cầu cấp quyền liên quan đến vị trí, micrô hoặc máy ảnh, hộp thoại cấp quyền, mà người dùng nhìn thấy, chứa tuỳ chọn có tên là Chỉ lần này, như được minh hoạ trong Hình 2. Nếu người dùng chọn tuỳ chọn này trong hộp thoại, thì ứng dụng của bạn sẽ tạm thời được cấp quyền một lần. Sau đó, ứng dụng có thể truy cập vào dữ liệu liên quan trong một khoảng thời gian nhất định, tuỳ thuộc vào hành vi của ứng dụng và hành động của người dùng:
Quá trình xử lý của ứng dụng chấm dứt khi quyền bị thu hồiNếu người dùng thu hồi quyền một lần, chẳng hạn như trong phần cài đặt hệ thống, thì ứng dụng của bạn không thể truy cập vào dữ liệu, bất kể bạn đã khởi chạy dịch vụ trên nền trước hay chưa. Cũng như đối với bất kỳ quyền nào, nếu người dùng thu hồi quyền một lần của ứng dụng, thì quy trình của ứng dụng sẽ chấm dứt. Lần tiếp theo khi người dùng mở ứng dụng của bạn và một tính năng trong ứng dụng yêu cầu quyền truy cập vào thông tin vị trí, micrô hoặc máy ảnh, thì người dùng sẽ nhận được lời nhắc cấp quyền một lần nữa. Lưu ý: Nếu ứng dụng đã làm theo các phương pháp hay nhất khi yêu cầu cấp quyền khi bắt đầu chạy, thì bạn không cần thêm hay thay đổi bất kỳ logic nào trong ứng dụng để hỗ trợ quyền một lần.Đặt lại quyền không dùng đếnAndroid cung cấp một số cách để đặt lại quyền không dùng đến khi bắt đầu chạy về trạng thái mặc định, bị từ chối: Trên Android 13 (API cấp 33) trở lên, bạn có thể xoá quyền truy cập của ứng dụng vào các quyền khi bắt đầu chạy mà ứng dụng không còn yêu cầu. Khi bạn cập nhật ứng dụng, hãy thực hiện bước này để người dùng có thể dễ hiểu lý do ứng dụng tiếp tục yêu cầu các quyền cụ thể. Kiến thức này giúp người dùng tin tưởng ứng dụng của bạn. Để xoá quyền truy cập vào một quyền khi bắt đầu chạy, hãy chuyển tên của quyền đó vào revokeSelfPermissionOnKill(). Để xoá quyền truy cập vào một nhóm các quyền khi bắt đầu chạy, hãy chuyển một tập hợp tên quyền vào revokeSelfPermissionsOnKill(). Quy trình xoá quyền diễn ra không đồng bộ và loại bỏ tất cả các quy trình liên kết với UID của ứng dụng. Lưu ý: Để các chế độ cài đặt hệ thống cho thấy rằng ứng dụng của bạn không truy cập vào dữ liệu trong một nhóm quyền cụ thể, bạn phải xoá quyền truy cập vào tất cả các quyền trong nhóm quyền đó. Trong trường hợp này, bạn nên gọi revokeSelfPermissionsOnKill() và chuyển vào nhiều quyền trong nhóm quyền này.Để hệ thống xoá quyền truy cập của ứng dụng vào các quyền, mọi quy trình liên kết với ứng dụng đều phải bị loại bỏ. Khi bạn gọi API, hệ thống sẽ xác định thời điểm an toàn để loại bỏ các quy trình này. Thông thường, hệ thống sẽ chờ cho đến khi ứng dụng dành một khoảng thời gian dài để chạy trong nền thay vì trong nền trước. Để thông báo cho người dùng rằng ứng dụng của bạn không còn yêu cầu truy cập vào các quyền cụ thể khi bắt đầu chạy, hãy hiển thị một hộp thoại vào lần tới người dùng chạy ứng dụng. Hộp thoại này có thể bao gồm danh sách các quyền. Tự động đặt lại quyền cho các ứng dụng không dùng đếnNếu ứng dụng của bạn nhắm mục tiêu vào Android 11 (API cấp 30) trở lên và không được dùng trong vài tháng, thì hệ thống sẽ bảo vệ dữ liệu người dùng bằng cách tự động đặt lại các quyền nhạy cảm khi bắt đầu chạy mà người dùng đã cấp cho ứng dụng. Hãy tìm hiểu thêm trong hướng dẫn về trạng thái ngủ đông của ứng dụng. Yêu cầu để trở thành trình xử lý mặc định nếu cầnMột số ứng dụng phụ thuộc vào quyền truy cập đến thông tin người dùng nhạy cảm liên quan đến nhật ký cuộc gọi và tin nhắn SMS. Nếu muốn yêu cầu cấp quyền cụ thể với nhật ký cuộc gọi và tin nhắn SMS cũng như xuất bản ứng dụng lên Cửa hàng Play, thì bạn phải nhắc người dùng đặt ứng dụng làm trình xử lý mặc định cho một hàm hệ thống cốt lõi trước khi yêu cầu quyền khi bắt đầu chạy này. Để biết thêm thông tin về trình xử lý mặc định, bao gồm cả hướng dẫn về hiển thị lời nhắc trình xử lý mặc định cho người dùng, xem hướng dẫn về các quyền chỉ được sử dụng trong trình xử lý mặc định. Cấp tất cả quyền khi bắt đầu chạy cho mục đích kiểm thửĐể tự động cấp tất cả các quyền khi bắt đầu chạy khi bạn cài đặt một ứng dụng trên trình mô phỏng hoặc thiết bị kiểm thử, sử dụng tuỳ chọn -g cho lệnh adb shell install như minh hoạ trong đoạn mã sau đây: adb shell install -g PATH_TO_APK_FILETài nguyên khácĐể biết thêm thông tin về cấp quyền, đọc những bài viết sau:
Để tìm hiểu thêm về yêu cầu cấp quyền, hãy tải các ứng dụng mẫu sau xuống:
|