Giống như trên điện thoại, việc truy cập vào phần cứng nhạy cảm như camera và micrô trên kính âm thanh và kính hiển thị đòi hỏi người dùng phải đồng ý rõ ràng. Đây được coi là các quyền dành riêng cho kính và ứng dụng của bạn phải yêu cầu các quyền này trong thời gian chạy, ngay cả khi ứng dụng đã có các quyền tương ứng trên điện thoại.
Khai báo các quyền trong tệp kê khai của ứng dụng
Trước khi yêu cầu cấp quyền, bạn phải khai báo các quyền đó trong tệp kê khai của ứng dụng bằng phần tử <uses-permission>. Khai báo này vẫn giữ nguyên cho dù quyền đó là cho một tính năng dành riêng cho điện thoại hay kính, nhưng bạn vẫn phải yêu cầu quyền đó một cách rõ ràng đối với phần cứng hoặc chức năng dành riêng cho kính.
<manifest ...>
<!-- Only declare permissions that your app actually needs. In this example,
we declare permissions for the camera. -->
<uses-permission android:name="android.permission.CAMERA"/>
<application ...>
...
</application>
</manifest>
Trước khi yêu cầu cấp quyền cho kính
Xem các nguyên tắc và quy trình cấp quyền để đảm bảo bạn mang đến trải nghiệm tốt nhất cho người dùng, chẳng hạn như kiểm tra xem người dùng đã cấp quyền khi bắt đầu chạy hay chưa mà ứng dụng của bạn yêu cầu và liệu ứng dụng của bạn có cho biết lý do hay không cho người dùng trước khi yêu cầu các quyền dành riêng cho kính.
Các trường hợp cấp quyền
Có một số trường hợp bạn có thể gặp phải khi yêu cầu quyền nguy hiểm khi chạy trên kính âm thanh và kính hiển thị:
- Yêu cầu quyền khi bắt đầu chạy từ một hoạt động được chiếu
- Yêu cầu quyền khi bắt đầu chạy từ một hoạt động trên điện thoại
Hãy xem các phần sau trong hướng dẫn này để biết thông tin chi tiết về từng trường hợp.
Yêu cầu và xử lý quyền khi bắt đầu chạy từ một hoạt động được chiếu
Để yêu cầu cấp quyền cho kính phát âm thanh và kính có màn hình, trước tiên, hãy sử dụng ActivityResultLauncher với phương thức ProjectedPermissionsResultContract để đăng ký trình chạy quyền. Khi người dùng đã thực hiện hành động đối với yêu cầu cấp quyền, lệnh gọi lại sẽ nhận được một bản đồ tên quyền theo trạng thái được cấp của chúng.
// Register the permissions launcher using the ProjectedPermissionsResultContract. private val requestPermissionLauncher: ActivityResultLauncher<List<ProjectedPermissionsRequestParams>> = registerForActivityResult(ProjectedPermissionsResultContract()) { results -> if (results[Manifest.permission.CAMERA] == true) { isPermissionDenied = false initializeGlassesFeatures() } else { // Handle permission denial. isPermissionDenied = true } }
Các điểm chính về mã
- Bạn cần chỉ định những quyền mà ứng dụng của bạn yêu cầu, chẳng hạn như
Manifest.permission.CAMERAhoặcManifest.permission.RECORD_AUDIO. - Ứng dụng của bạn phải xử lý cả kết quả được cấp và bị từ chối một cách thoả đáng trong lệnh gọi lại của trình chạy.
Để kích hoạt quy trình yêu cầu cấp quyền, hãy truyền một danh sách ProjectedPermissionsRequestParams đến phương thức launch của trình chạy quyền đã đăng ký. Đối tượng ProjectedPermissionsRequestParams sẽ kết hợp các quyền tệp kê khai được yêu cầu với một chuỗi rationale tuỳ chỉnh. Chuỗi rationale phải giải thích rõ ràng và ngắn gọn lý do ứng dụng cần quyền truy cập vào các tính năng phần cứng của kính (chẳng hạn như camera hoặc micrô).
private fun requestHardwarePermissions() { val params = ProjectedPermissionsRequestParams( permissions = listOf(Manifest.permission.CAMERA), rationale = "Camera access is required to overlay digital content on your physical environment." ) requestPermissionLauncher.launch(listOf(params)) }
Các điểm chính về mã
- Việc gọi
launchtrên trình chạy sẽ kích hoạt luồng người dùng yêu cầu cấp quyền.
Tìm hiểu quy trình yêu cầu cấp quyền cho người dùng
Khi bạn khởi chạy một yêu cầu cấp quyền bằng phương thức ProjectedPermissionsResultContract, hệ thống sẽ bắt đầu một quy trình phối hợp cho người dùng trên cả kính và điện thoại.
Trong luồng người dùng cấp quyền, đây là những điều mà ứng dụng của bạn và người dùng có thể mong đợi:
Trên kính: Một hoạt động xuất hiện trên thiết bị được chiếu (kính), hướng dẫn người dùng nhìn vào điện thoại để tiếp tục.
Trên điện thoại: Đồng thời, một hoạt động sẽ khởi chạy trên thiết bị lưu trữ (điện thoại). Màn hình này hiển thị chuỗi lý do mà bạn cung cấp và cho phép người dùng chọn tiếp tục hoặc huỷ.
Trên điện thoại: Nếu người dùng chấp nhận lý do, thì một hộp thoại cấp quyền hệ thống Android đã sửa đổi sẽ xuất hiện trên điện thoại để cho người dùng biết rằng họ đang cấp quyền cho kính (không phải điện thoại) và người dùng có thể chính thức cấp hoặc từ chối quyền.
Nhận kết quả: Sau khi người dùng đưa ra lựa chọn cuối cùng, các hoạt động trên cả điện thoại và kính sẽ bị loại bỏ. Sau đó, lệnh gọi lại
ActivityResultLaunchercủa bạn sẽ được gọi bằng một bản đồ chứa trạng thái được cấp cho từng quyền được yêu cầu.
Yêu cầu quyền khi bắt đầu chạy trong một hoạt động trên điện thoại
Nếu ứng dụng của bạn đang chạy trong một hoạt động trên điện thoại nhưng cần có quyền truy cập vào kính âm thanh hoặc kính hiển thị (ví dụ: để cho phép người dùng chuyển luồng video sang camera của kính để có góc nhìn từ người thứ nhất), hãy yêu cầu cấp quyền bằng phương thức Activity#requestPermissions(permissions, requestCode,
deviceId) dành riêng cho thiết bị.
Để nhắm đến kính âm thanh và kính có màn hình, hãy lấy mã thiết bị thích hợp bằng cách gọi getDeviceId trên một ngữ cảnh thiết bị được chiếu. Truyền mã nhận dạng này khi yêu cầu quyền từ hoạt động trên điện thoại, như minh hoạ trong ví dụ sau:
// Request the projected permission from phone activity requestPermissions( arrayOf(Manifest.permission.CAMERA), // REQUEST_CODE_GLASSES_CAMERA is a developer-defined constant REQUEST_CODE_GLASSES_CAMERA, projectedDeviceId )
Xử lý kết quả về quyền
Sau khi người dùng phản hồi hộp thoại cấp quyền trên điện thoại, quyết định của họ sẽ được gửi đến ứng dụng của bạn bằng cách gọi lệnh gọi lại onRequestPermissionsResult.
Để xử lý phản hồi, hãy ghi đè onRequestPermissionsResult trong phiên bản Activity đã bắt đầu yêu cầu cấp quyền.
Đoạn mã sau đây cho biết cách xử lý lệnh gọi lại và xác minh xem người dùng có cấp các quyền được yêu cầu hay không:
private companion object { // REQUEST_CODE_GLASSES_CAMERA is a developer-defined constant. const val REQUEST_CODE_GLASSES_CAMERA = 1001 } @RequiresApi(Build.VERSION_CODES.VANILLA_ICE_CREAM) override fun onRequestPermissionsResult( requestCode: Int, permissions: Array<out String>, grantResults: IntArray, deviceId: Int ) { super.onRequestPermissionsResult(requestCode, permissions, grantResults, deviceId) // Handle the result of the permission request if (requestCode == REQUEST_CODE_GLASSES_CAMERA && deviceId == projectedDeviceId) { if (grantResults.isNotEmpty() && grantResults[0] == PackageManager.PERMISSION_GRANTED) { // Proceed with glasses camera features } else { // Handle glasses permission denied } } }
Các điểm chính về mã
- Sử dụng phương thức nạp chồng
deviceIdvới lệnh gọi lạionRequestPermissionsResultđể đảm bảo trạng thái quyền được ánh xạ chính xác với ngữ cảnh cụ thể, chẳng hạn như kính âm thanh hoặc kính có màn hình thay vì điện thoại chủ. - Ứng dụng của bạn phải xử lý cả kết quả được cấp và bị từ chối một cách thoả đáng.