การขอสิทธิ์ตำแหน่งอย่างถูกต้อง
ตำแหน่งเบื้องหน้าและตำแหน่งที่แม่นยำ
การขอสิทธิ์ตำแหน่งอย่างถูกต้อง เป็นบทเรียน Android Academy ฟรีบน CoddyKit นี่คือบทเรียนที่ 4 จากทั้งหมด 4 บทเรียน คุณสามารถอ่านบทเรียนทั้งหมดด้านล่างฟรี — จากนั้นลองปฏิบัติด้วยตัวคุณเองในเบราว์เซอร์พร้อมตัวแก้ไขโค้ดในตัวและติวเตอร์ AI ตลอด 24/7 บทเรียนนี้เป็นส่วนหนึ่งของเส้นทางการเรียน Android Academy และความก้าวหน้าของคุณจะซิงค์ข้ามเว็บและแอป CoddyKit คอร์ส Android Academy มีบทเรียนทั้งหมด 4 บทเรียน
สิทธิ์เป็นสิ่งที่ขาดไม่ได้
ตำแหน่งเป็นหนึ่งในสิทธิ์ที่ละเอียดอ่อนที่สุดของ Android การประกาศไว้ใน manifest ยังไม่เพียงพอ ใน Android รุ่นใหม่ คุณต้อง ขอจากผู้ใช้ขณะทำงาน และจัดการทุกคำตอบอย่างเหมาะสม
บทเรียนนี้ครอบคลุมระดับของสิทธิ์ การขอสิทธิ์ใน Compose การจัดการกรณีถูกปฏิเสธ รวมถึงกฎใหม่เรื่อง ตำแหน่งแม่นยำเทียบกับโดยประมาณ และ การทำงานเบื้องหลัง
สิทธิ์เข้าถึงตำแหน่งสามระดับ
Android แบ่งการเข้าถึงตำแหน่งเป็นระดับต่าง ๆ:
ACCESS_COARSE_LOCATION— ตำแหน่งโดยประมาณ (ระดับย่านเมือง)ACCESS_FINE_LOCATION— ตำแหน่งแม่นยำ (ระดับ GPS)ACCESS_BACKGROUND_LOCATION— เข้าถึงตำแหน่งขณะที่แอปไม่ได้อยู่เบื้องหน้า
ขอเฉพาะสิทธิ์ที่จำเป็นจริง ๆ เท่านั้น การเข้าถึงเบื้องหลังจะถูกตรวจสอบอย่างเข้มงวดเป็นพิเศษใน Play Store
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
<!-- only if truly needed: -->
<uses-permission android:name="android.permission.ACCESS_BACKGROUND_LOCATION" />การขอสิทธิ์ใน Compose
API ผลลัพธ์ของกิจกรรมจะให้ตัวเปิดสำหรับกล่องโต้ตอบขอสิทธิ์ ใน Compose ให้ใช้ rememberLauncherForActivityResult ร่วมกับสัญญา RequestMultiplePermissions
import androidx.activity.compose.rememberLauncherForActivityResult
import androidx.activity.result.contract.ActivityResultContracts
val launcher = rememberLauncherForActivityResult(
ActivityResultContracts.RequestMultiplePermissions()
) { result ->
val fine = result[Manifest.permission.ACCESS_FINE_LOCATION] == true
val coarse = result[Manifest.permission.ACCESS_COARSE_LOCATION] == true
// react to the user's choice
}การเริ่มคำขอ
เรียกกล่องโต้ตอบด้วยการเรียก launch() พร้อมอาร์เรย์ของสิทธิ์ โดยทั่วไปควรทำเพื่อตอบสนองต่อการแตะปุ่ม ไม่ใช่เปิดโดยอัตโนมัติเมื่อโหลดหน้าจอ
Button(onClick = {
launcher.launch(
arrayOf(
Manifest.permission.ACCESS_FINE_LOCATION,
Manifest.permission.ACCESS_COARSE_LOCATION
)
)
}) {
Text("Enable location")
}ตรวจสอบว่าได้รับสิทธิ์แล้วหรือไม่
อย่าขอซ้ำหากได้รับสิทธิ์แล้ว ให้ตรวจสอบด้วย ContextCompat.checkSelfPermission ก่อนเริ่มคำขอ
import androidx.core.content.ContextCompat
import android.content.pm.PackageManager
fun hasFineLocation(context: Context): Boolean {
return ContextCompat.checkSelfPermission(
context,
Manifest.permission.ACCESS_FINE_LOCATION
) == PackageManager.PERMISSION_GRANTED
}ตำแหน่งแม่นยำเทียบกับโดยประมาณ
ตั้งแต่ Android 12 (API 31) ผู้ใช้สามารถอนุญาตตำแหน่งแบบ โดยประมาณ ได้ แม้ว่าคุณจะขอตำแหน่งแบบแม่นยำ ดังนั้นคุณต้องขอ ทั้งสองสิทธิ์ พร้อมกัน และยอมรับว่าผู้ใช้อาจลดระดับสิทธิ์ของคุณเหลือแบบโดยประมาณ
ออกแบบฟีเจอร์ให้ทำงานได้อย่างเหมาะสมกับตำแหน่งโดยประมาณเมื่อเป็นไปได้
// Request both — the system shows a Precise/Approximate toggle
launcher.launch(
arrayOf(
Manifest.permission.ACCESS_FINE_LOCATION,
Manifest.permission.ACCESS_COARSE_LOCATION
)
)
// If only COARSE comes back granted, you got approximate location.การแสดงคำอธิบายเหตุผล
หากผู้ใช้ปฏิเสธหนึ่งครั้ง Android จะให้คุณตรวจสอบ shouldShowRequestPermissionRationale เมื่อค่าเป็นจริง ให้แสดงคำอธิบายที่เป็นมิตรว่า เหตุใดจึงต้องใช้ตำแหน่ง ก่อนขออีกครั้ง
import androidx.core.app.ActivityCompat
val shouldExplain = ActivityCompat.shouldShowRequestPermissionRationale(
activity,
Manifest.permission.ACCESS_FINE_LOCATION
)
if (shouldExplain) {
// show a dialog: "We use your location to find nearby stores"
}การจัดการการปฏิเสธถาวร
หากผู้ใช้เลือก ไม่ต้องถามอีก (หรือปฏิเสธสองครั้ง) ระบบจะไม่แสดงกล่องโต้ตอบอีกต่อไป วิธีเดียวที่ทำได้คือส่งผู้ใช้ไปยัง การตั้งค่าแอป เพื่อเปิดสิทธิ์ด้วยตนเอง
import android.content.Intent
import android.provider.Settings
import android.net.Uri
fun openAppSettings(context: Context) {
val intent = Intent(
Settings.ACTION_APPLICATION_DETAILS_SETTINGS,
Uri.fromParts("package", context.packageName, null)
)
context.startActivity(intent)
}การใช้ Accompanist Permissions
ไลบรารี accompanist-permissions ห่อหุ้มกระบวนการทั้งหมดนี้ไว้ในสถานะที่เหมาะกับ Compose rememberMultiplePermissionsState จะติดตามสถานะการได้รับสิทธิ์ และมีการเรียก launchMultiplePermissionRequest() ให้ใช้
import com.google.accompanist.permissions.rememberMultiplePermissionsState
val permissions = rememberMultiplePermissionsState(
listOf(
Manifest.permission.ACCESS_FINE_LOCATION,
Manifest.permission.ACCESS_COARSE_LOCATION
)
)
if (permissions.allPermissionsGranted) {
// show the map / read location
} else {
Button(onClick = { permissions.launchMultiplePermissionRequest() }) {
Text("Grant location")
}
}กฎเกี่ยวกับตำแหน่งในเบื้องหลัง
การใช้ตำแหน่งในเบื้องหลังต้องดำเนินการ สองขั้นตอน: ขั้นแรกให้สิทธิ์การเข้าถึงตำแหน่งขณะใช้งาน (แบบละเอียด/แบบคร่าว) จากนั้นจึงขอ ACCESS_BACKGROUND_LOCATION แยกต่างหาก ซึ่งจะเปิดการตั้งค่าระบบบน Android 11 ขึ้นไป Google Play กำหนดให้ต้องมีคำอธิบายเหตุผลที่ชัดเจนและนโยบายความเป็นส่วนตัว
ขอสิทธิ์นี้เฉพาะเมื่อแอปของคุณจำเป็นต้องใช้ตำแหน่งขณะที่ปิดอยู่จริง ๆ เช่น การกำหนดขอบเขตตำแหน่ง การติดตามการออกกำลังกาย และอื่น ๆ
// Step 1: request foreground first and confirm it's granted.
// Step 2: only then request background:
launcher.launch(
arrayOf(Manifest.permission.ACCESS_BACKGROUND_LOCATION)
)
// On Android 11+ this sends the user to settings to pick "Allow all the time".แผนที่ที่ควบคุมด้วยสิทธิ์
นำทุกอย่างมาเชื่อมโยงกัน โดยควบคุมการเข้าถึงแผนที่ตามสถานะสิทธิ์ แสดงแผนที่เมื่อได้รับสิทธิ์แล้วเท่านั้น มิฉะนั้นให้แสดงข้อความแจ้งขอสิทธิ์ นี่คือรูปแบบมาตรฐานที่คำนึงถึงผู้ใช้
@Composable
fun LocationGate(permissions: MultiplePermissionsState) {
when {
permissions.allPermissionsGranted -> MapScreen()
else -> Column {
Text("We need location to show nearby places.")
Button(onClick = { permissions.launchMultiplePermissionRequest() }) {
Text("Allow location")
}
}
}
}ตรวจสอบอย่างรวดเร็ว
ตั้งแต่ Android 12 เป็นต้นมา ผู้ใช้สามารถเลือกตำแหน่งแบบ โดยประมาณ แทนตำแหน่งแบบ แม่นยำได้ สิ่งนี้ส่งผลอย่างไรต่อการขอสิทธิ์ของคุณ
สรุปทบทวน
ตอนนี้คุณทราบวิธีขอสิทธิ์ตำแหน่งอย่างเหมาะสมแล้ว:
- ประกาศสิทธิ์ตำแหน่งแบบคร่าว/แบบละเอียด (และตำแหน่งในเบื้องหลังเฉพาะเมื่อจำเป็นอย่างยิ่ง) ในไฟล์ manifest
- ขอสิทธิ์ขณะใช้งานด้วย Activity Result APIs หรือ
accompanist-permissions - ขอสิทธิ์แบบละเอียดและแบบคร่าวพร้อมกัน เพื่อรองรับตัวเลือกตำแหน่งแบบแม่นยำ/โดยประมาณ
- แสดงคำอธิบายเหตุผล และนำผู้ใช้ที่ปฏิเสธสิทธิ์ถาวรไปยังการตั้งค่าแอป
- จัดการตำแหน่งในเบื้องหลังเป็นกระบวนการสองขั้นตอนแยกต่างหาก พร้อมเหตุผลที่ชัดเจน
บทเรียน Maps & Location Services จบลงแล้ว — คุณสามารถแสดงแผนที่ ค้นหาตำแหน่งผู้ใช้ วางหมุด และขอสิทธิ์ได้อย่างถูกต้อง
คำถามที่พบบ่อย
บทเรียน “การขอสิทธิ์ตำแหน่งอย่างถูกต้อง” ฟรีหรือไม่
ใช่ — ข้อความเต็มของ “การขอสิทธิ์ตำแหน่งอย่างถูกต้อง” ฟรีให้อ่านที่นี่บนเว็บ เพื่อปฏิบัติแบบโต้ตอบ (ตัวแก้ไขโค้ดในตัวและติวเตอร์ AI ตลอด 24/7) และปลดล็อคส่วนที่เหลือของคอร์ส Android Academy ให้อัปเกรดเป็น CoddyKit PRO คอร์ส Android Academy มีบทเรียนทั้งหมด 4 บทเรียน
คุณจะเรียนรู้อะไรในบทเรียน “การขอสิทธิ์ตำแหน่งอย่างถูกต้อง”
ตำแหน่งเบื้องหน้าและตำแหน่งที่แม่นยำ คุณปฏิบัติ Android Academy ด้วยโค้ดที่ใช้งานได้จริงที่คุณเรียกใช้โดยตรงในเบราว์เซอร์ และติวเตอร์ AI ตลอด 24/7 ตอบคำถามของคุณขณะที่คุณไปผ่านบทเรียน
คุณต้องมีประสบการณ์ก่อนที่จะเริ่มเรียน Android Academy หรือไม่
ไม่จำเป็นต้องมีประสบการณ์มาก่อน Android Academy บน CoddyKit ออกแบบมาสำหรับผู้เริ่มต้นไปจนถึงผู้เรียนขั้นสูง คุณสามารถเริ่มต้นที่นี่หรือเริ่มจากตัวแรกและเรียนด้วยความเร็วของคุณเอง นี่คือบทเรียนที่ 4 จากทั้งหมด 4 บทเรียน
บทเรียน “การขอสิทธิ์ตำแหน่งอย่างถูกต้อง” ใช้เวลานานแค่ไหน
บทเรียน CoddyKit ส่วนใหญ่ใช้เวลาประมาณ 5–10 นาที แต่ละบทเรียนจึงสั้นและเป็นแบบโต้ตอบ คุณสามารถก้าวหน้าอย่างต่อเนื่องและกลับมาเรียนต่อจากตรงที่เพิ่งหยุดบนเว็บและแอปได้เลย
ฉันเขียนและรันโค้ดในบทเรียน Android Academy นี้ได้ไหม
ได้ บทเรียน Android Academy ทุกบทมีตัวแก้ไขโค้ดในตัว คุณจึงเขียนและรันโค้ดจริงได้เลยในเบราว์เซอร์ และได้รับข้อเสนอแนะจาก AI ในทันที — ไม่ต้องติดตั้งในเครื่องของคุณ
บทเรียนทั้งหมดในหลักสูตรนี้
- การแสดงแผนที่
- การรับตำแหน่งของผู้ใช้
- หมุดและกล้อง
- การขอสิทธิ์ตำแหน่งอย่างถูกต้อง