ก่อนขอสิทธิ์เข้าถึงตำแหน่งขณะรันไทม์ โปรดอ่านตัวเลือกและแนวทางปฏิบัติแนะนำ สำหรับการเข้าถึงตำแหน่ง รวมถึงคำแนะนำในการลดคำขอสิทธิ์ ของคุณ แหล่งข้อมูลเหล่านี้จะช่วยคุณตัดสินใจว่าจะขอสิทธิ์ใด และ ปุ่มตำแหน่งเป็นทางเลือกที่ดีกว่าสำหรับกรณีการใช้งานของคุณหรือไม่
หลักเกณฑ์ในการเข้าถึงสิทธิ์เข้าถึงตำแหน่ง
กฎทั่วไปบางข้อที่ควรปฏิบัติตามเมื่อตัดสินใจว่าจะใช้สิทธิ์เข้าถึงตำแหน่งในแอปอย่างไร
เข้าถึงตำแหน่งตามบริบท
เมื่อฟีเจอร์ในแอปต้องใช้สิทธิ์เข้าถึงตำแหน่ง คุณต้องรอจนกว่าผู้ใช้จะโต้ตอบกับฟีเจอร์นั้นก่อนจึงจะส่งคำขอสิทธิ์ได้ ซึ่งเป็นไปตามแนวทางปฏิบัติแนะนำในการขอสิทธิ์ขณะรันไทม์ตามบริบท ดังที่อธิบายไว้ในคำแนะนำที่อธิบายวิธีขอสิทธิ์ของแอป
รูปที่ 1 แสดงวิธีดำเนินการตามกระบวนการนี้ แอปมีฟีเจอร์ "แชร์ตำแหน่ง" ที่ต้องใช้สิทธิ์เข้าถึงตำแหน่งในเบื้องหน้า อย่างไรก็ตาม แอปจะไม่ขอสิทธิ์เข้าถึงตำแหน่งจนกว่าผู้ใช้จะเลือกปุ่มแชร์ตำแหน่ง
ผู้ใช้ให้สิทธิ์เข้าถึงตำแหน่งโดยประมาณเท่านั้น
ใน Android 12 (ระดับ API 31) ขึ้นไป ผู้ใช้สามารถขอให้แอปของคุณดึงข้อมูลตำแหน่งโดยประมาณเท่านั้น แม้ว่าแอปของคุณจะขอสิทธิ์รันไทม์
ACCESS_FINE_LOCATIONก็ตาม
หากต้องการจัดการพฤติกรรมที่อาจเกิดขึ้นของผู้ใช้ อย่าขอสิทธิ์ ACCESS_FINE_LOCATION เพียงอย่างเดียว แต่ให้ขอทั้งสิทธิ์ ACCESS_FINE_LOCATION
และสิทธิ์ ACCESS_COARSE_LOCATION ในคำขอขณะรันไทม์
คำขอเดียว หากคุณพยายามขอเฉพาะ ACCESS_FINE_LOCATION ระบบจะละเว้นคำขอใน Android 12 บางเวอร์ชัน หากแอปกำหนดเป้าหมายเป็น
Android 12 ขึ้นไป ระบบจะบันทึกข้อความแสดงข้อผิดพลาดต่อไปนี้
ใน Logcat:
ACCESS_FINE_LOCATION must be requested with ACCESS_COARSE_LOCATION.
เมื่อแอปขอทั้ง ACCESS_FINE_LOCATION และ ACCESS_COARSE_LOCATION กล่องโต้ตอบสิทธิ์ของระบบจะมีตัวเลือกต่อไปนี้ให้ผู้ใช้
- แน่นอน: อนุญาตให้แอปรับข้อมูลตำแหน่งที่แน่นอน
- โดยประมาณ: อนุญาตให้แอปของคุณรับข้อมูลตำแหน่งโดยประมาณเท่านั้น
รูปที่ 3 แสดงว่ากล่องโต้ตอบมีคำแนะนำแบบภาพสำหรับทั้ง 2 ตัวเลือก เพื่อ ช่วยให้ผู้ใช้เลือกได้ หลังจากที่ผู้ใช้ตัดสินใจเลือกความแม่นยำของตำแหน่งแล้ว ให้แตะปุ่มใดปุ่มหนึ่งใน 3 ปุ่มเพื่อเลือกระยะเวลาการให้สิทธิ์
ใน Android 12 ขึ้นไป ผู้ใช้สามารถไปที่การตั้งค่าระบบเพื่อตั้งค่าความแม่นยำของตำแหน่งที่ต้องการสำหรับแอปใดก็ได้ ไม่ว่าแอปนั้นจะกำหนดเป้าหมายเป็น SDK เวอร์ชันใด ซึ่งจะเป็นเช่นนี้แม้ว่าแอปของคุณจะติดตั้งอยู่ในอุปกรณ์ที่ใช้ Android 11 หรือต่ำกว่า แล้วผู้ใช้อัปเกรดอุปกรณ์เป็น Android 12 ขึ้นไป
ACCESS_COARSE_LOCATION เท่านั้นACCESS_FINE_LOCATION และ
ACCESS_COARSE_LOCATION ในคำขอขณะรันไทม์คำขอเดียว
ตัวเลือกของผู้ใช้ส่งผลต่อการให้สิทธิ์
ตารางต่อไปนี้แสดงสิทธิ์ที่ระบบให้แก่แอปของคุณ โดยอิงตามตัวเลือกที่ผู้ใช้เลือกในกล่องโต้ตอบสิทธิ์ขณะรันไทม์
| แน่นอน | โดยประมาณ | |
|---|---|---|
| ขณะใช้แอป | ACCESS_FINE_LOCATION และ ACCESS_COARSE_LOCATION |
ACCESS_COARSE_LOCATION |
| เฉพาะครั้งนี้ | ACCESS_FINE_LOCATION และ ACCESS_COARSE_LOCATION |
ACCESS_COARSE_LOCATION |
| ปฏิเสธ | ไม่มีสิทธิ์เข้าถึงตำแหน่ง | ไม่มีสิทธิ์เข้าถึงตำแหน่ง |
หากต้องการดูว่าระบบให้สิทธิ์ใดแก่แอปของคุณ ให้ตรวจสอบค่าที่แสดงผลของคำขอสิทธิ์ คุณสามารถใช้ไลบรารี Jetpack ในโค้ด ที่คล้ายกับโค้ดต่อไปนี้ หรือจะใช้ไลบรารีแพลตฟอร์มที่คุณ จัดการโค้ดคำขอสิทธิ์ด้วยตนเองก็ได้
Kotlin
@RequiresApi(Build.VERSION_CODES.N) fun requestPermissions() { val locationPermissionRequest = registerForActivityResult( ActivityResultContracts.RequestMultiplePermissions() ) { permissions -> when { permissions.getOrDefault(Manifest.permission.ACCESS_FINE_LOCATION, false) -> { // Precise location access granted. } permissions.getOrDefault(Manifest.permission.ACCESS_COARSE_LOCATION, false) -> { // Only approximate location access granted. } else -> { // No location access granted. } } } // Before you perform the actual permission request, check whether your app // already has the permissions, and whether your app needs to show a permission // rationale dialog. For more details, see Request permissions: // https://developer.android.com/training/permissions/requesting#request-permission locationPermissionRequest.launch( arrayOf( Manifest.permission.ACCESS_FINE_LOCATION, Manifest.permission.ACCESS_COARSE_LOCATION ) ) }
Java
private void requestPermissions() { ActivityResultLauncher<String[]> locationPermissionRequest = registerForActivityResult(new ActivityResultContracts .RequestMultiplePermissions(), result -> { Boolean fineLocationGranted = null; Boolean coarseLocationGranted = null; if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) { fineLocationGranted = result.getOrDefault( Manifest.permission.ACCESS_FINE_LOCATION, false); coarseLocationGranted = result.getOrDefault( Manifest.permission.ACCESS_COARSE_LOCATION,false); } if (fineLocationGranted != null && fineLocationGranted) { // Precise location access granted. } else if (coarseLocationGranted != null && coarseLocationGranted) { // Only approximate location access granted. } else { // No location access granted. } } ); // ... // Before you perform the actual permission request, check whether your app // already has the permissions, and whether your app needs to show a permission // rationale dialog. For more details, see Request permissions. locationPermissionRequest.launch(new String[] { Manifest.permission.ACCESS_FINE_LOCATION, Manifest.permission.ACCESS_COARSE_LOCATION }); }
ขออัปเกรดเป็นตำแหน่งที่แน่นอน
คุณสามารถขอให้ผู้ใช้อัปเกรดสิทธิ์เข้าถึงของแอปจากตำแหน่งโดยประมาณเป็นตำแหน่งที่แน่นอน อย่างไรก็ตาม ก่อนที่จะขอให้ผู้ใช้อัปเกรดสิทธิ์เข้าถึงของแอปเป็นตำแหน่งที่แน่นอน โปรดพิจารณาก่อนว่ากรณีการใช้งานของแอปจำเป็นต้องใช้ความแม่นยำระดับนี้หรือไม่ หากแอปต้องจับคู่อุปกรณ์กับอุปกรณ์ที่อยู่ใกล้เคียง
ผ่านบลูทูธหรือ Wi-Fi ให้พิจารณาใช้การจับคู่อุปกรณ์ที่ใช้ร่วมกันหรือ
สิทธิ์เข้าถึงบลูทูธแทนการขอสิทธิ์ACCESS_FINE_LOCATION
หากต้องการขอให้ผู้ใช้อัปเกรดสิทธิ์เข้าถึงตำแหน่งของแอปจากโดยประมาณเป็นแน่นอน ให้ทำดังนี้
- อธิบายเหตุผลที่แอปต้องใช้สิทธิ์ หากจำเป็น
- ขอสิทธิ์
ACCESS_FINE_LOCATIONและACCESS_COARSE_LOCATIONพร้อมกันอีกครั้ง เนื่องจากผู้ใช้ได้อนุญาตให้ระบบให้สิทธิ์เข้าถึงตำแหน่งโดยประมาณแก่แอปของคุณแล้ว กล่องโต้ตอบของระบบจึงแตกต่างออกไปในครั้งนี้ ดังที่แสดงในรูปที่ 4 และรูปที่ 5
ขอเฉพาะสิทธิ์เข้าถึงตำแหน่งในเบื้องหน้าในตอนแรก
แม้ว่าฟีเจอร์หลายรายการในแอปของคุณต้องใช้สิทธิ์เข้าถึงตำแหน่ง แต่ก็มีเพียงบางฟีเจอร์เท่านั้นที่ต้องใช้สิทธิ์เข้าถึงตำแหน่งในเบื้องหลัง ดังนั้น เราขอแนะนำให้แอปของคุณส่ง คำขอทีละส่วน สำหรับสิทธิ์เข้าถึงตำแหน่ง โดยขอสิทธิ์เข้าถึงตำแหน่งในเบื้องหน้าก่อน แล้วจึงขอสิทธิ์เข้าถึงตำแหน่งในเบื้องหลัง การส่งคำขอทีละส่วนจะช่วยให้ผู้ใช้ควบคุมและเห็นข้อมูลได้มากขึ้น เนื่องจากผู้ใช้จะเข้าใจได้ดียิ่งขึ้นว่าฟีเจอร์ใดในแอปของคุณต้องใช้สิทธิ์เข้าถึงตำแหน่งในเบื้องหลัง
รูปที่ 6 แสดงตัวอย่างแอปที่ออกแบบมาเพื่อจัดการคำขอทีละส่วน ทั้งฟีเจอร์ "แสดงตำแหน่งปัจจุบัน" และ "แนะนำสถานที่ใกล้เคียง" ต้องใช้สิทธิ์เข้าถึงตำแหน่งในเบื้องหน้า อย่างไรก็ตาม มีเพียงฟีเจอร์ "แนะนำสถานที่ใกล้เคียง" เท่านั้นที่ต้องใช้สิทธิ์เข้าถึงตำแหน่งในเบื้องหลัง
กระบวนการส่งคำขอทีละส่วนมีดังนี้
ในตอนแรก แอปควรแนะนำผู้ใช้ไปยังฟีเจอร์ที่ต้องใช้สิทธิ์เข้าถึงตำแหน่งในเบื้องหน้า เช่น ฟีเจอร์ "แชร์ตำแหน่ง" ในรูปที่ 1 หรือฟีเจอร์ "แสดงตำแหน่งปัจจุบัน" ในรูปที่ 2
เราขอแนะนำให้ปิดใช้สิทธิ์เข้าถึงของผู้ใช้สำหรับฟีเจอร์ที่ต้องใช้สิทธิ์เข้าถึงตำแหน่งในเบื้องหลังจนกว่าแอปของคุณจะมีสิทธิ์เข้าถึงตำแหน่งในเบื้องหน้า
ในภายหลัง เมื่อผู้ใช้สำรวจฟีเจอร์ที่ต้องใช้สิทธิ์เข้าถึงตำแหน่งในเบื้องหลัง คุณสามารถขอสิทธิ์เข้าถึงตำแหน่งในเบื้องหลังได้
แหล่งข้อมูลเพิ่มเติม
ดูข้อมูลเพิ่มเติมเกี่ยวกับสิทธิ์เข้าถึงตำแหน่งใน Android ได้จากแหล่งข้อมูลต่อไปนี้
Codelab
วิดีโอ
ตัวอย่าง
- แอปตัวอย่าง เพื่อแสดงการใช้สิทธิ์เข้าถึงตำแหน่ง