สิทธิ์และคำขอขณะทำงาน
ประกาศและขอสิทธิ์ที่มีความเสี่ยงขณะทำงานโดยใช้ ActivityResultContracts แสดงกล่องโต้ตอบอธิบายเหตุผล และจัดการกรณีถูกปฏิเสธถาวร
สิทธิ์และคำขอขณะทำงาน เป็นบทเรียน Android Academy ฟรีบน CoddyKit นี่คือบทเรียนที่ 7 จากทั้งหมด 7 บทเรียน คุณสามารถอ่านบทเรียนทั้งหมดด้านล่างฟรี — จากนั้นลองปฏิบัติด้วยตัวคุณเองในเบราว์เซอร์พร้อมตัวแก้ไขโค้ดในตัวและติวเตอร์ AI ตลอด 24/7 บทเรียนนี้เป็นส่วนหนึ่งของเส้นทางการเรียน Android Academy และความก้าวหน้าของคุณจะซิงค์ข้ามเว็บและแอป CoddyKit คอร์ส Android Academy มีบทเรียนทั้งหมด 7 บทเรียน
ภาพรวมสิทธิ์ของ Android
แอป Android ต้องประกาศว่าจำเป็นต้องใช้ฟีเจอร์ใดของอุปกรณ์ สิทธิ์ช่วยปกป้องความเป็นส่วนตัวของผู้ใช้:
- สิทธิ์ปกติ — ความเสี่ยงต่ำ ระบบอนุมัติให้อัตโนมัติ (INTERNET, VIBRATE)
- สิทธิ์ที่มีความเสี่ยง — เข้าถึงข้อมูลที่ละเอียดอ่อน ต้องขอขณะทำงาน (CAMERA, LOCATION, READ_CONTACTS)
- สิทธิ์ลายเซ็น — ใช้ได้เฉพาะกับแอปที่ลงนามด้วยใบรับรองเดียวกัน
การประกาศใน Manifest
ต้องประกาศสิทธิ์ทั้งหมดใน AndroidManifest.xml ก่อน:
<!-- AndroidManifest.xml -->
<manifest ...>
<!-- Normal: granted automatically -->
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.VIBRATE" />
<!-- Dangerous: must request at runtime -->
<uses-permission android:name="android.permission.CAMERA" />
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
<uses-permission android:name="android.permission.READ_CONTACTS" />
<application ...>
...
</application>
</manifest>การตรวจสอบว่าได้รับสิทธิ์แล้วหรือไม่
ก่อนใช้ฟีเจอร์ที่มีความเสี่ยง ให้ตรวจสอบเสมอว่าได้รับสิทธิ์นั้นแล้วหรือยัง:
import androidx.core.content.ContextCompat
import android.content.pm.PackageManager
fun isCameraPermissionGranted(): Boolean {
return ContextCompat.checkSelfPermission(
this, // Context
android.Manifest.permission.CAMERA
) == PackageManager.PERMISSION_GRANTED
}การขอสิทธิ์ด้วย ActivityResultLauncher
ใช้ ActivityResultContracts.RequestPermission() ซึ่งเป็นวิธีสมัยใหม่ (ไม่ใช้ onRequestPermissionsResult ที่เลิกใช้แล้ว):
class CameraActivity : AppCompatActivity() {
private val requestCameraPermission = registerForActivityResult(
ActivityResultContracts.RequestPermission()
) { isGranted ->
if (isGranted) {
openCamera()
} else {
showPermissionDeniedMessage()
}
}
fun onTakePhotoClick(view: View) {
if (isCameraPermissionGranted()) {
openCamera()
} else {
requestCameraPermission.launch(android.Manifest.permission.CAMERA)
}
}
}การขอสิทธิ์หลายรายการพร้อมกัน
ขอสิทธิ์หลายรายการด้วย RequestMultiplePermissions:
private val requestMultiple = registerForActivityResult(
ActivityResultContracts.RequestMultiplePermissions()
) { permissions ->
val cameraGranted = permissions[android.Manifest.permission.CAMERA] ?: false
val locationGranted = permissions[android.Manifest.permission.ACCESS_FINE_LOCATION] ?: false
if (cameraGranted && locationGranted) {
startFeature()
} else {
showWhichPermissionsDenied(cameraGranted, locationGranted)
}
}
fun requestPermissions() {
requestMultiple.launch(arrayOf(
android.Manifest.permission.CAMERA,
android.Manifest.permission.ACCESS_FINE_LOCATION
))
}เหตุผลประกอบ: ควรอธิบายเมื่อใด
shouldShowRequestPermissionRationale() จะคืนค่าเป็น true เมื่อผู้ใช้เคยปฏิเสธสิทธิ์มาก่อน ให้แสดงคำอธิบายก่อนขอสิทธิ์อีกครั้ง:
fun requestCameraWithRationale() {
when {
isCameraPermissionGranted() -> {
openCamera()
}
shouldShowRequestPermissionRationale(android.Manifest.permission.CAMERA) -> {
// Explain why we need it, then request
AlertDialog.Builder(this)
.setTitle("Camera needed")
.setMessage("We use the camera to take profile photos.")
.setPositiveButton("OK") { _, _ ->
requestCameraPermission.launch(android.Manifest.permission.CAMERA)
}
.show()
}
else -> {
requestCameraPermission.launch(android.Manifest.permission.CAMERA)
}
}
}ถูกปฏิเสธถาวร — ส่งไปที่การตั้งค่า
หากผู้ใช้แตะ "ไม่ต้องถามอีก" shouldShowRequestPermissionRationale จะคืนค่าเป็น false และคุณจะขอสิทธิ์อีกไม่ได้ ให้ผู้ใช้ไปที่การตั้งค่าแอป:
fun openAppSettings() {
val intent = Intent(Settings.ACTION_APPLICATION_DETAILS_SETTINGS).apply {
data = Uri.fromParts("package", packageName, null)
}
startActivity(intent)
}สิทธิ์เข้าถึงตำแหน่ง
การเข้าถึงตำแหน่งมีสองระดับ — เลือกระดับที่เหมาะกับกรณีการใช้งานของคุณ:
ACCESS_COARSE_LOCATION— ความแม่นยำระดับเมือง (WiFi/เสาสัญญาณโทรศัพท์)ACCESS_FINE_LOCATION— ความแม่นยำระดับ GPSACCESS_BACKGROUND_LOCATION— ต้องขอแยกต่างหากบน Android 10 ขึ้นไป เพื่อเข้าถึงตำแหน่งขณะทำงานเบื้องหลัง
ตัวอย่างการขอสิทธิ์กล้องแบบสมบูรณ์
ลำดับการทำงานที่สมบูรณ์ ซึ่งรวมการตรวจสอบ → เหตุผลประกอบ → การขอสิทธิ์:
class PhotoActivity : AppCompatActivity() {
private val cameraLauncher = registerForActivityResult(
ActivityResultContracts.RequestPermission()
) { granted ->
if (granted) openCamera() else showDenied()
}
private fun handleCameraClick() {
val permission = android.Manifest.permission.CAMERA
when {
ContextCompat.checkSelfPermission(this, permission) ==
PackageManager.PERMISSION_GRANTED -> openCamera()
shouldShowRequestPermissionRationale(permission) ->
showRationaleDialog()
else -> cameraLauncher.launch(permission)
}
}
private fun showDenied() {
Snackbar.make(binding.root, "Camera permission required", Snackbar.LENGTH_LONG)
.setAction("Settings") { openAppSettings() }.show()
}
}แนวทางปฏิบัติที่ดีที่สุดสำหรับสิทธิ์
กฎสำคัญเพื่อให้การขอสิทธิ์เป็นไปอย่างราบรื่น:
- ขอสิทธิ์เมื่อจำเป็นเท่านั้น (ไม่ใช่ทันทีที่เปิดแอป)
- ขอเฉพาะสิทธิ์ขั้นต่ำที่จำเป็น
- จัดการกรณีที่ผู้ใช้ปฏิเสธอย่างเหมาะสมเสมอ
- อย่าถามซ้ำหลังจากผู้ใช้เลือก "ไม่ต้องถามอีก"
- อธิบายเหตุผล ก่อน แสดงกล่องโต้ตอบของระบบ ไม่ใช่หลังจากถูกปฏิเสธ
สิทธิ์สื่อแบบละเอียดบน Android 13 ขึ้นไป
ตั้งแต่ Android 13 (API 33) เป็นต้นมา READ_EXTERNAL_STORAGE ถูกแยกเป็นสิทธิ์แบบละเอียด:
READ_MEDIA_IMAGESREAD_MEDIA_VIDEOREAD_MEDIA_AUDIO
ตรวจสอบ Build.VERSION.SDK_INT เสมอ และขอสิทธิ์ที่ถูกต้องตามรุ่นของระบบปฏิบัติการ
ตรวจสอบความเข้าใจ
คุณควรแสดงกล่องโต้ตอบเพื่ออธิบายเหตุผลก่อนขอสิทธิ์ที่มีความเสี่ยงเมื่อใด
สรุป: สิทธิ์
การจัดการสิทธิ์ขณะทำงานอย่างถูกต้อง:
- ประกาศใน
AndroidManifest.xml - ตรวจสอบด้วย
ContextCompat.checkSelfPermission() - ขอสิทธิ์ผ่าน
registerForActivityResult(RequestPermission()) - แสดงเหตุผลประกอบเมื่อ
shouldShowRequestPermissionRationale()เป็น true - หากถูกปฏิเสธถาวร ให้แนะนำผู้ใช้ไปที่ Settings
- อย่าขอสิทธิ์ก่อนที่ผู้ใช้จะต้องใช้งาน
ถัดไป: บันทึกข้อมูลไว้ในเครื่องด้วย DataStore
คำถามที่พบบ่อย
บทเรียน “สิทธิ์และคำขอขณะทำงาน” ฟรีหรือไม่
ใช่ — ข้อความเต็มของ “สิทธิ์และคำขอขณะทำงาน” ฟรีให้อ่านที่นี่บนเว็บ เพื่อปฏิบัติแบบโต้ตอบ (ตัวแก้ไขโค้ดในตัวและติวเตอร์ AI ตลอด 24/7) และปลดล็อคส่วนที่เหลือของคอร์ส Android Academy ให้อัปเกรดเป็น CoddyKit PRO คอร์ส Android Academy มีบทเรียนทั้งหมด 7 บทเรียน
คุณจะเรียนรู้อะไรในบทเรียน “สิทธิ์และคำขอขณะทำงาน”
ประกาศและขอสิทธิ์ที่มีความเสี่ยงขณะทำงานโดยใช้ ActivityResultContracts แสดงกล่องโต้ตอบอธิบายเหตุผล และจัดการกรณีถูกปฏิเสธถาวร คุณปฏิบัติ Android Academy ด้วยโค้ดที่ใช้งานได้จริงที่คุณเรียกใช้โดยตรงในเบราว์เซอร์ และติวเตอร์ AI ตลอด 24/7 ตอบคำถามของคุณขณะที่คุณไปผ่านบทเรียน
คุณต้องมีประสบการณ์ก่อนที่จะเริ่มเรียน Android Academy หรือไม่
ไม่จำเป็นต้องมีประสบการณ์มาก่อน Android Academy บน CoddyKit ออกแบบมาสำหรับผู้เริ่มต้นไปจนถึงผู้เรียนขั้นสูง คุณสามารถเริ่มต้นที่นี่หรือเริ่มจากตัวแรกและเรียนด้วยความเร็วของคุณเอง นี่คือบทเรียนที่ 7 จากทั้งหมด 7 บทเรียน
บทเรียน “สิทธิ์และคำขอขณะทำงาน” ใช้เวลานานแค่ไหน
บทเรียน CoddyKit ส่วนใหญ่ใช้เวลาประมาณ 5–10 นาที แต่ละบทเรียนจึงสั้นและเป็นแบบโต้ตอบ คุณสามารถก้าวหน้าอย่างต่อเนื่องและกลับมาเรียนต่อจากตรงที่เพิ่งหยุดบนเว็บและแอปได้เลย
ฉันเขียนและรันโค้ดในบทเรียน Android Academy นี้ได้ไหม
ได้ บทเรียน Android Academy ทุกบทมีตัวแก้ไขโค้ดในตัว คุณจึงเขียนและรันโค้ดจริงได้เลยในเบราว์เซอร์ และได้รับข้อเสนอแนะจาก AI ในทันที — ไม่ต้องติดตั้งในเครื่องของคุณ
บทเรียนทั้งหมดในหลักสูตรนี้
- โครงสร้างโครงการและไฟล์ Manifest
- Activity และวงจรชีวิต
- เค้าโครงและมุมมอง
- การจัดการข้อมูลที่ผู้ใช้ป้อน
- อินเทนต์และการนำทาง
- Fragment
- สิทธิ์และคำขอขณะทำงาน