1. Chào mừng
Giới thiệu
Quyền cho ứng dụng được dùng để cấp quyền truy cập vào dữ liệu và chức năng ngoài phạm vi môi trường hộp cát của ứng dụng. Các quyền này có thể cải thiện chức năng của ứng dụng bằng cách cho phép ứng dụng truy cập vào Internet, thông tin vị trí thiết bị, máy ảnh, v.v.
Để ứng dụng có được những khả năng này, bạn cần phải yêu cầu người dùng cấp quyền. Lớp học lập trình này sẽ hướng dẫn bạn các bước cần thiết để thêm quyền khi bắt đầu chạy và kiểm tra xem những quyền này đã được cấp hay chưa.
Bạn cần có
- Phiên bản Android Studio mới nhất.
Kiến thức bạn cần có
- Kotlin, như dạy trong Chương trình đào tạo về Kotlin
- Các kỹ năng phát triển ứng dụng Android cơ bản, như dạy trong Phát triển ứng dụng Android bằng Kotlin
Kiến thức bạn sẽ học được
- Cách thêm quyền vào tệp kê khai Android.
- Cách yêu cầu cấp quyền.
- Cách xử lý khi quyền được chấp nhận và bị từ chối.
- Cách kiểm tra xem một quyền nào đó đã được cấp hay chưa.
Sản phẩm bạn sẽ tạo ra
Bạn sẽ tạo một ứng dụng yêu cầu quyền sử dụng máy ảnh. Bạn sẽ triển khai phần cấp quyền cho ứng dụng, nhưng không triển khai phần máy ảnh.
2. Tạo một dự án Android Studio
- Bắt đầu một dự án Android Studio mới.
- Chọn Empty Activity (Hoạt động trống).
- Đặt tên cho dự án là Permissions Codelab và dùng ngôn ngữ Kotlin.
3. Thiết lập đoạn mã
- Thêm phiên bản mới nhất của các phần phụ thuộc sau đây vào tệp
build.gradle
ở cấp ứng dụng. Những phần phụ thuộc này cho phép bạn sử dụng thư việnActivity
. Chúng ta sẽ đề cập đến thư viện này ở các phần sau trong lớp học lập trình này.
implementation "androidx.activity:activity-ktx:1.2.2"
implementation "androidx.fragment:fragment-ktx:1.3.2"
- Đặt tuỳ chọn bản dựng
viewBinding
thành true trong khối lệnh android để bật tính năng ViewBinding.
android {
...
buildFeatures {
viewBinding true
}
}
- Sau đó, nhấn nút lệnh hình cái búa màu xanh lục để tạo ứng dụng. Thao tác này sẽ tạo một lớp liên kết có tên
ActivityMainBinding
mà sau này bạn sẽ sử dụng choViewBinding
.
- Chuyển đến tệp
activity_main.xml
rồi thay mã bằng đoạn mã sau.
<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:id="@+id/main_layout"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".MainActivity">
<Button
android:id="@+id/button"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Request Permissions"
android:onClick="onClickRequestPermission"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
</androidx.constraintlayout.widget.ConstraintLayout>
- Thêm các chuỗi này vào tệp
strings.xml
.
<string name="app_name">Permissions Codelab</string>
<string name="permission_required">Camera access is required to display the camera preview.</string>
<string name="ok">OK</string>
<string name="permission_granted">Permission is granted. You can use the camera now.</string>
- Trong
MainActivity.kt
, phía trên phương thứconCreate()
, hãy định nghĩa các biến cho bố cục vàViewBinding
.
private lateinit var layout: View
private lateinit var binding: ActivityMainBinding
- Thay thế mã trong phương thức
onCreate()
bằng đoạn mã dưới đây. Mã này sẽ khởi tạo mối liên kết, tạo mộtval
thể hiện khung nhìn này và thiết lập khung nhìn này thành gốc liên kết, đồng thời đặt bố cục thànhmainLayout
của mối liên kết.
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
binding = ActivityMainBinding.inflate(layoutInflater)
val view = binding.root
layout = binding.mainLayout
setContentView(view)
}
- Ở cuối tệp, trong lớp
MainActivity
, hãy thêm một hàm mở rộng để hiển thị thanh thông báo nhanh xuyên suốt lớp học lập trình này.
fun View.showSnackbar(
view: View,
msg: String,
length: Int,
actionMessage: CharSequence?,
action: (View) -> Unit
) {
val snackbar = Snackbar.make(view, msg, length)
if (actionMessage != null) {
snackbar.setAction(actionMessage) {
action(this)
}.show()
} else {
snackbar.show()
}
}
4. Thêm quyền vào tệp kê khai
Việc cần làm đầu tiên là khai báo rằng bạn sẽ dùng quyền trong Android manifest
bằng cách sử dụng thẻ <uses-permission>
.
Đôi khi quyền mà bạn đang đề nghị cấp cũng sẽ có các yêu cầu khác. Trong trường hợp này, bạn không thể dùng ứng dụng máy ảnh trừ phi thiết bị có máy ảnh. Do đó, bạn cần thêm thẻ <uses-feature>
vào tệp kê khai.
- Trong tệp
AndroidManifest.xml
, hãy thêm quyền cho máy ảnh ở phía trên thẻ<application>
.
<uses-permission android:name="android.permission.CAMERA" />
5. Tạo trình chạy quyền
Trong tệp MainActivity.kt
, hãy tạo một val
có tên là requestPermissionLauncher
rồi sao chép đoạn mã này vào đó. Chúng ta sẽ phân tích chi tiết về đoạn mã này ở những dòng bên dưới.
private val requestPermissionLauncher =
registerForActivityResult(
ActivityResultContracts.RequestPermission()
) { isGranted: Boolean ->
if (isGranted) {
Log.i("Permission: ", "Granted")
} else {
Log.i("Permission: ", "Denied")
}
}
- Đặt
requestPermissionLauncher
bằng vớiregisterForActivityResult
rồi truyền vàoActivityResultContracts.RequestPermission()
.
private val requestPermissionLauncher =
registerForActivityResult(
ActivityResultContracts.RequestPermission())
- Thêm lệnh gọi lại (callback) để kiểm tra xem một quyền đã được cấp phép hay chưa. Trong trường hợp này, chúng ta sẽ ghi kết quả vào nhật ký.
{ isGranted: Boolean ->
if (isGranted) {
Log.i("Permission: ", "Granted")
} else {
Log.i("Permission: ", "Denied")
}
}
6. Yêu cầu cấp quyền
- Tạo một hàm có tên là
onClickRequestPermission(view: View)
rồi sao chép đoạn mã này vào hàm đó. Chúng ta sẽ phân tích những gì đang xảy ra bên trong đoạn mã này ở những dòng tiếp theo.
fun onClickRequestPermission(view: View) {
when {
ContextCompat.checkSelfPermission(
this,
Manifest.permission.CAMERA
) == PackageManager.PERMISSION_GRANTED -> {
layout.showSnackbar(
view,
getString(R.string.permission_granted),
Snackbar.LENGTH_INDEFINITE,
null
) {}
}
ActivityCompat.shouldShowRequestPermissionRationale(
this,
Manifest.permission.CAMERA
) -> {
layout.showSnackbar(
view,
getString(R.string.permission_required),
Snackbar.LENGTH_INDEFINITE,
getString(R.string.ok)
) {
requestPermissionLauncher.launch(
Manifest.permission.CAMERA
)
}
}
else -> {
requestPermissionLauncher.launch(
Manifest.permission.CAMERA
)
}
}
}
- Tạo câu lệnh
when
để xử lý ba trường hợp: quyền đã được cấp, ứng dụng thấy cần hiển thị lý do yêu cầu cấp quyền và chưa yêu cầu cấp quyền.
when {
ContextCompat.checkSelfPermission(
this,
Manifest.permission.CAMERA
) == PackageManager.PERMISSION_GRANTED -> {
}
ActivityCompat.shouldShowRequestPermissionRationale(
this,
Manifest.permission.CAMERA
) -> {
}
else -> {
}
}
- Trong trường hợp quyền đã được cấp, đoạn mã sẽ hiện một thông báo trên thanh thông báo nhanh.
ContextCompat.checkSelfPermission(
this,
Manifest.permission.CAMERA
) == PackageManager.PERMISSION_GRANTED -> {
layout.showSnackbar(
view,
getString(R.string.permission_granted),
Snackbar.LENGTH_INDEFINITE,
null
) {}
}
- Nếu
shouldShowRequestPermissionRationale()
trả về giá trị true, đoạn mã sẽ hiện một giao diện người dùng mô tả chi tiết hơn về lý do cần cấp quyền cho tính năng đó, đồng thời hướng dẫn người dùng chấp nhận/từ chối cấp quyền trên giao diện người dùng.
ActivityCompat.shouldShowRequestPermissionRationale(
this,
Manifest.permission.CAMERA
) -> {
layout.showSnackbar(
view,
getString(R.string.permission_required),
Snackbar.LENGTH_INDEFINITE,
getString(R.string.ok)
) {
requestPermissionLauncher.launch(
Manifest.permission.CAMERA
)
}
}
- Trường hợp còn lại, đoạn mã sẽ yêu cầu cấp quyền đó.
else -> {
requestPermissionLauncher.launch(
Manifest.permission.CAMERA
)
}
7. Tóm tắt
Vậy là xong! Lớp học lập trình này cho bạn biết cách thêm quyền khi bắt đầu chạy và có thể dùng cho các quyền liên quan đến vị trí, mạng, nội dung đa phương tiện và nhiều quyền khác!
Bạn có thể xem đoạn mã hoàn chỉnh và đọc thêm trong tài liệu này.