1. ก่อนเริ่มต้น
Android 10 และ 11 ช่วยให้ผู้ใช้ควบคุมแอปของตนได้มากขึ้น การเข้าถึงตำแหน่งอุปกรณ์
เมื่อแอปที่ทำงานใน Android 11 ขอสิทธิ์เข้าถึงตำแหน่ง ผู้ใช้จะมี 4 ตัวเลือกดังต่อไปนี้
- อนุญาตตลอด
- อนุญาตขณะใช้แอปเท่านั้น (ใน Android 10)
- ครั้งเดียวเท่านั้น (ใน Android 11)
- ปฏิเสธ
Android 10
Android 11
ใน Codelab นี้ คุณจะได้เรียนรู้วิธีรับการอัปเดตตำแหน่งและวิธีรองรับตำแหน่งใน Android ทุกเวอร์ชัน โดยเฉพาะ Android 10 และ 11 เมื่อจบ Codelab แล้ว คุณจะเห็นแอปที่เป็นไปตามแนวทางปฏิบัติแนะนำในปัจจุบันสำหรับการเรียกข้อมูลการอัปเดตตำแหน่ง
ข้อกำหนดเบื้องต้น
สิ่งที่คุณจะต้องทำ
- ทำตามแนวทางปฏิบัติแนะนำสำหรับตำแหน่งใน Android
- จัดการสิทธิ์เข้าถึงตำแหน่งในเบื้องหน้า (เมื่อผู้ใช้ขอให้แอปเข้าถึงตำแหน่งของอุปกรณ์ขณะที่ใช้งานแอป)
- แก้ไขแอปที่มีอยู่เพื่อเพิ่มการสนับสนุนสำหรับการขอสิทธิ์เข้าถึงตำแหน่งโดยเพิ่มโค้ดสำหรับการสมัครใช้บริการและยกเลิกการสมัครใช้บริการตำแหน่ง
- เพิ่มการรองรับแอปสำหรับ Android 10 และ 11 ด้วยการเพิ่มตรรกะเพื่อเข้าถึงตำแหน่งในตำแหน่งเบื้องหน้าหรือขณะใช้งาน
สิ่งที่คุณต้องมี
- Android Studio 3.4 ขึ้นไปเพื่อเรียกใช้โค้ด
- อุปกรณ์/โปรแกรมจำลองที่แสดงตัวอย่าง Android 10 และ 11 สำหรับนักพัฒนาซอฟต์แวร์
2. เริ่มต้นใช้งาน
โคลนที่เก็บของโปรเจ็กต์เริ่มต้น
เพื่อช่วยคุณเริ่มต้นโดยเร็วที่สุด คุณสามารถต่อยอดจากโปรเจ็กต์เริ่มต้นนี้ได้ หากคุณติดตั้ง Git ไว้ คุณสามารถเรียกใช้คำสั่งต่อไปนี้:
git clone https://github.com/android/codelab-while-in-use-location
โปรดไปที่หน้า GitHub โดยตรง
หากคุณไม่มี Git คุณสามารถรับโปรเจ็กต์เป็นไฟล์ ZIP:
นำเข้าโปรเจ็กต์
เปิด Android Studio เลือก "เปิดโปรเจ็กต์ Android Studio ที่มีอยู่" จากหน้าจอต้อนรับ และเปิดไดเรกทอรีโครงการ
หลังจากโหลดโปรเจ็กต์แล้ว คุณอาจเห็นการแจ้งเตือนว่า Git ไม่ได้ติดตามการเปลี่ยนแปลงในเครื่องทั้งหมด คุณสามารถคลิกไม่สนใจ (จะไม่มีการส่งการเปลี่ยนแปลงใดๆ กลับไปยังที่เก็บ Git)
ที่มุมบนซ้ายของหน้าต่างโปรเจ็กต์ คุณควรเห็นบางอย่างที่คล้ายรูปภาพด้านล่างหากอยู่ในมุมมอง Android (หากอยู่ในมุมมองโปรเจ็กต์ คุณจะต้องขยายโปรเจ็กต์เพื่อให้เห็นสิ่งเดียวกัน)
มี 2 โฟลเดอร์ (base
และ complete
) แต่ละโมดูลเรียกว่า "โมดูล"
โปรดทราบว่า Android Studio อาจใช้เวลาหลายวินาทีเพื่อรวบรวมโปรเจ็กต์ในเบื้องหลังเป็นครั้งแรก ในระหว่างนี้คุณจะเห็นข้อความต่อไปนี้ในแถบสถานะที่ด้านล่างของ Android Studio
รอจนกว่า Android Studio จะจัดทำดัชนีและสร้างโปรเจ็กต์เสร็จสิ้นก่อนที่จะเปลี่ยนแปลงโค้ด ซึ่งจะช่วยให้ Android Studio ดึงคอมโพเนนต์ที่จำเป็นทั้งหมดได้
หากได้รับข้อความแจ้งว่า โหลดซ้ำเพื่อให้การเปลี่ยนภาษามีผล หรือข้อความที่คล้ายกัน ให้เลือกใช่
ทำความเข้าใจโปรเจ็กต์เริ่มต้น
คุณได้ตั้งค่าและพร้อมขอตำแหน่งในแอปแล้ว ใช้โมดูล base
เป็นจุดเริ่มต้น ในแต่ละขั้นตอน ให้เพิ่มโค้ดลงในโมดูล base
เมื่อใช้งาน Codelab นี้เสร็จสิ้นแล้ว โค้ดในโมดูล base
ควรตรงกับเนื้อหาของโมดูล complete
คุณสามารถใช้โมดูล complete
เพื่อตรวจสอบงานหรือเพื่อใช้อ้างอิงหากพบปัญหา
องค์ประกอบหลักมีดังต่อไปนี้
MainActivity
— UI สำหรับผู้ใช้ที่อนุญาตให้แอปเข้าถึงตำแหน่งของอุปกรณ์LocationService
— บริการที่สมัครรับและยกเลิกการสมัครรับอีเมลเกี่ยวกับการเปลี่ยนแปลงตำแหน่ง และโปรโมตตัวเองเป็นบริการที่ทำงานอยู่เบื้องหน้า (พร้อมการแจ้งเตือน) หากผู้ใช้ออกจากกิจกรรมของแอป คุณเพิ่มรหัสสถานที่ตั้งที่นี่Util
- เพิ่มฟังก์ชันส่วนขยายสำหรับคลาสLocation
และบันทึกตำแหน่งในSharedPreferences
(ชั้นข้อมูลแบบง่าย)
การตั้งค่าโปรแกรมจำลอง
ดูข้อมูลเกี่ยวกับการตั้งค่าโปรแกรมจำลองของ Android ได้ที่เรียกใช้โปรแกรมจำลอง
เรียกใช้โปรเจ็กต์เริ่มต้น
เรียกใช้แอป
- เชื่อมต่ออุปกรณ์ Android กับคอมพิวเตอร์หรือเริ่มโปรแกรมจําลอง (ตรวจสอบว่าอุปกรณ์ใช้ Android 10 ขึ้นไป)
- ในแถบเครื่องมือ ให้เลือกการกำหนดค่า
base
จากตัวเลือกแบบเลื่อนลง แล้วคลิกเรียกใช้
- โปรดสังเกตว่าแอปต่อไปนี้ปรากฏบนอุปกรณ์ของคุณ
คุณอาจสังเกตเห็นว่าไม่มีข้อมูลตำแหน่งปรากฏในหน้าจอเอาต์พุต เนื่องจากคุณยังไม่ได้เพิ่มรหัสสถานที่ตั้ง
3. กำลังเพิ่มสถานที่
แนวคิด
จุดมุ่งเน้นของ Codelab นี้คือแสดงวิธีรับการอัปเดตตำแหน่ง ซึ่งท้ายที่สุดแล้วจะรองรับ Android 10 และ Android 11
อย่างไรก็ตาม ก่อนที่คุณจะเริ่มต้นเขียนโค้ด คุณควรตรวจสอบหลักการเบื้องต้นก่อน
ประเภทของการเข้าถึงตำแหน่ง
คุณอาจจำตัวเลือก 4 ข้อที่แตกต่างกันสำหรับการเข้าถึงตำแหน่งได้ตั้งแต่ต้นของ Codelab ลองดูความหมายของคำเหล่านี้
- อนุญาตขณะใช้แอปเท่านั้น
- ตัวเลือกนี้เป็นตัวเลือกที่แนะนำสำหรับแอปส่วนใหญ่ หรือที่เรียกว่า "ขณะใช้งาน" หรือ "เบื้องหน้าเท่านั้น" ตัวเลือกนี้เพิ่มเข้ามาใน Android 10 และอนุญาตให้นักพัฒนาแอปดึงข้อมูลตำแหน่งได้ขณะที่มีการใช้งานแอปเท่านั้น ระบบจะถือว่าแอปทำงานอยู่หากเงื่อนไขข้อใดข้อหนึ่งต่อไปนี้เป็นจริง
- กิจกรรมจะปรากฏขึ้น
- บริการที่ทำงานอยู่เบื้องหน้ากำลังทำงานพร้อมการแจ้งเตือนต่อเนื่อง
- ครั้งเดียวเท่านั้น
- สิ่งที่เพิ่มใน Android 11 จะเหมือนกับการอนุญาตขณะมีการใช้แอปเท่านั้น แต่เป็นเวลาที่จำกัด ดูข้อมูลเพิ่มเติมได้ที่สิทธิ์แบบครั้งเดียว
- ปฏิเสธ
- ตัวเลือกนี้จะป้องกันการเข้าถึงข้อมูลตำแหน่ง
- อนุญาตตลอด
- ตัวเลือกนี้จะอนุญาตให้เข้าถึงตำแหน่งตลอดเวลา แต่ต้องได้รับสิทธิ์เพิ่มเติมสำหรับ Android 10 ขึ้นไป นอกจากนี้คุณต้องตรวจสอบว่า Use Case ที่ถูกต้องและปฏิบัติตามนโยบายตำแหน่ง ตัวเลือกนี้ไม่รวมใน Codelab นี้เนื่องจากเป็นกรณีการใช้งานที่พบไม่บ่อย อย่างไรก็ตาม หากคุณมี Use Case ที่ถูกต้องและต้องการทําความเข้าใจวิธีจัดการตําแหน่งตลอดเวลาอย่างถูกต้อง รวมถึงการเข้าถึงตําแหน่งในเบื้องหลัง ให้ดูตัวอย่าง LocationUpdatesBackgroundKotlin
บริการ บริการที่ทำงานอยู่เบื้องหน้า และการเชื่อมโยง
หากต้องการรองรับการอัปเดตตําแหน่งแบบอนุญาตขณะใช้แอปอยู่เท่านั้นอย่างเต็มรูปแบบ คุณต้องพิจารณาเมื่อผู้ใช้ออกจากแอปของคุณ หากต้องการรับข้อมูลอัปเดตต่อในสถานการณ์นั้น คุณต้องสร้างเบื้องหน้า Service
และเชื่อมโยงกับ Notification
นอกจากนี้ หากคุณต้องการใช้ Service
เดียวกันเพื่อขออัปเดตตำแหน่งเมื่อแอปแสดงและเมื่อผู้ใช้ออกจากแอปของคุณ คุณจะต้องเชื่อมโยง/ยกเลิกการเชื่อมโยง Service
ดังกล่าวกับองค์ประกอบ UI
เนื่องจาก Codelab นี้มุ่งเน้นการรับอัปเดตตำแหน่งเท่านั้น คุณจึงค้นหาโค้ดทั้งหมดที่ต้องใช้ได้ในชั้นเรียน ForegroundOnlyLocationService.kt
คุณสามารถเรียกดูชั้นเรียนนั้นและ MainActivity.kt
เพื่อดูว่าทั้ง 2 อย่างทำงานร่วมกันอย่างไร
ดูข้อมูลเพิ่มเติมได้ที่ภาพรวมของบริการและภาพรวมของบริการขอบเขต
สิทธิ์
หากต้องการรับการอัปเดตตำแหน่งจาก NETWORK_PROVIDER
หรือ GPS_PROVIDER
คุณต้องขอสิทธิ์ของผู้ใช้โดยประกาศสิทธิ์ ACCESS_COARSE_LOCATION
หรือ ACCESS_FINE_LOCATION
ตามลำดับในไฟล์ Manifest ของ Android หากไม่มีสิทธิ์เหล่านี้ แอปจะไม่สามารถขอสิทธิ์เข้าถึงตำแหน่งระหว่างรันไทม์ได้
สิทธิ์ดังกล่าวครอบคลุมกรณีเพียงครั้งเดียวเท่านั้นและอนุญาตขณะมีการใช้แอปเท่านั้น เมื่อมีการใช้แอปของคุณในอุปกรณ์ที่ใช้ Android 10 ขึ้นไป
ตำแหน่ง
แอปของคุณเข้าถึงชุดบริการตำแหน่งที่รองรับผ่านคลาสในแพ็กเกจ com.google.android.gms.location
ได้
ดูที่คลาสหลักๆ:
FusedLocationProviderClient
- ส่วนนี้เป็นองค์ประกอบหลักของเฟรมเวิร์กตำแหน่ง เมื่อสร้างแล้ว คุณจะใช้ข้อมูลดังกล่าวเพื่อขออัปเดตตำแหน่งและรับตำแหน่งที่ทราบล่าสุดได้
LocationRequest
- นี่คือออบเจ็กต์ข้อมูลที่มีพารามิเตอร์คุณภาพของการบริการสำหรับคำขอ (ช่วงเวลาสำหรับการอัปเดต ลำดับความสำคัญ และความแม่นยำ) ระบบจะส่งข้อมูลนี้ไปยัง
FusedLocationProviderClient
เมื่อคุณขออัปเดตตำแหน่ง LocationCallback
- ซึ่งใช้สำหรับรับการแจ้งเตือนเมื่อตำแหน่งของอุปกรณ์มีการเปลี่ยนแปลงหรือไม่สามารถระบุได้อีกต่อไป ซึ่งผ่าน
LocationResult
ซึ่งคุณจะรับLocation
เพื่อบันทึกไว้ในฐานข้อมูลได้
ตอนนี้คุณเข้าใจเบื้องต้นแล้วว่ากำลังทำอะไรอยู่ ก็มาเริ่มเขียนโค้ดกันเลย
4. เพิ่มฟีเจอร์ตำแหน่ง
Codelab นี้จะเน้นที่ตัวเลือกตำแหน่งที่พบได้ทั่วไป อันได้แก่ อนุญาตขณะมีการใช้แอปเท่านั้น
หากต้องการรับการอัปเดตตำแหน่ง แอปของคุณต้องมีกิจกรรมที่มองเห็นได้หรือบริการที่ทำงานอยู่เบื้องหน้า (พร้อมการแจ้งเตือน)
สิทธิ์
วัตถุประสงค์ของ Codelab นี้คือแสดงวิธีรับการอัปเดตตำแหน่ง ไม่ใช่วิธีขอสิทธิ์เข้าถึงตำแหน่ง ดังนั้นโค้ดตามสิทธิ์จึงเขียนให้คุณแล้ว คุณสามารถข้ามส่วนนี้ได้หากเข้าใจแล้ว
สิทธิ์ที่ไฮไลต์ไว้มีดังนี้ (ไม่ต้องดำเนินการใดๆ ในส่วนนี้)
- ประกาศสิทธิ์ที่คุณใช้ใน
AndroidManifest.xml
- ก่อนพยายามเข้าถึงข้อมูลตำแหน่ง ให้ตรวจสอบว่าผู้ใช้ได้ให้สิทธิ์แอปของคุณในการทำเช่นนั้นหรือไม่ หากแอปยังไม่ได้รับสิทธิ์ ให้ขอสิทธิ์เข้าถึง
- จัดการตัวเลือกสิทธิ์ของผู้ใช้ (ดูรหัสนี้ได้ใน
MainActivity.kt
)
หากค้นหา TODO: Step 1.0, Review Permissions
ใน AndroidManifest.xml
หรือ MainActivity.kt
คุณจะเห็นโค้ดทั้งหมดที่เขียนไว้สำหรับสิทธิ์
ดูข้อมูลเพิ่มเติมได้ที่ภาพรวมของสิทธิ์
ทีนี้ก็เริ่มเขียนโค้ดสถานที่เลย
ตรวจสอบตัวแปรหลักที่จำเป็นสำหรับการอัปเดตตำแหน่ง
ในโมดูล base
ให้ค้นหา TODO: Step 1.1, Review variables
ใน
ForegroundOnlyLocationService.kt
ไฟล์
คุณไม่จำเป็นต้องดำเนินการใดๆ ในขั้นตอนนี้ คุณเพียงแค่ต้องตรวจสอบโค้ดบล็อกต่อไปนี้พร้อมกับความคิดเห็น เพื่อทำความเข้าใจคลาสและตัวแปรหลักที่คุณใช้ในการรับการอัปเดตตำแหน่ง
// TODO: Step 1.1, Review variables (no changes).
// FusedLocationProviderClient - Main class for receiving location updates.
private lateinit var fusedLocationProviderClient: FusedLocationProviderClient
// LocationRequest - Requirements for the location updates, i.e., how often you
// should receive updates, the priority, etc.
private lateinit var locationRequest: LocationRequest
// LocationCallback - Called when FusedLocationProviderClient has a new Location.
private lateinit var locationCallback: LocationCallback
// Used only for local storage of the last known location. Usually, this would be saved to your
// database, but because this is a simplified sample without a full database, we only need the
// last location to create a Notification if the user navigates away from the app.
private var currentLocation: Location? = null
ตรวจสอบการเริ่มต้น FusedLocationProviderClient
ในโมดูล base
ให้ค้นหา TODO: Step 1.2, Review the FusedLocationProviderClient
ในไฟล์ ForegroundOnlyLocationService.kt
โค้ดของคุณควรมีลักษณะดังนี้
// TODO: Step 1.2, Review the FusedLocationProviderClient.
fusedLocationProviderClient = LocationServices.getFusedLocationProviderClient(this)
ตามที่ได้กล่าวไว้ในความคิดเห็นก่อนหน้านี้ ชั้นเรียนนี้เป็นชั้นเรียนหลักสำหรับรับการอัปเดตตำแหน่ง ระบบกำหนดค่าเริ่มต้นให้กับตัวแปรแล้ว แต่คุณต้องตรวจสอบโค้ดเพื่อทําความเข้าใจวิธีเริ่มต้น คุณเพิ่มรหัสบางอย่างที่นี่ในภายหลังเพื่อขออัปเดตตำแหน่ง
เริ่มต้น LocationRequest
- ในโมดูล
base
ให้ค้นหาTODO: Step 1.3, Create a LocationRequest
ในไฟล์ForegroundOnlyLocationService.kt
- ใส่รหัสต่อไปนี้หลังความคิดเห็น
โค้ดการเริ่มต้น LocationRequest
จะเพิ่มคุณภาพเพิ่มเติมของพารามิเตอร์บริการที่คุณต้องการสำหรับคำขอ (ช่วงเวลา เวลารอสูงสุด และลำดับความสำคัญ)
// TODO: Step 1.3, Create a LocationRequest.
locationRequest = LocationRequest.create().apply {
// Sets the desired interval for active location updates. This interval is inexact. You
// may not receive updates at all if no location sources are available, or you may
// receive them less frequently than requested. You may also receive updates more
// frequently than requested if other applications are requesting location at a more
// frequent interval.
//
// IMPORTANT NOTE: Apps running on Android 8.0 and higher devices (regardless of
// targetSdkVersion) may receive updates less frequently than this interval when the app
// is no longer in the foreground.
interval = TimeUnit.SECONDS.toMillis(60)
// Sets the fastest rate for active location updates. This interval is exact, and your
// application will never receive updates more frequently than this value.
fastestInterval = TimeUnit.SECONDS.toMillis(30)
// Sets the maximum time when batched location updates are delivered. Updates may be
// delivered sooner than this interval.
maxWaitTime = TimeUnit.MINUTES.toMillis(2)
priority = LocationRequest.PRIORITY_HIGH_ACCURACY
}
- อ่านความคิดเห็นเพื่อทำความเข้าใจวิธีการทำงานของแต่ละความคิดเห็น
เริ่มต้น LocationCallback
- ในโมดูล
base
ให้ค้นหาTODO: Step 1.4, Initialize the LocationCallback
ในไฟล์ForegroundOnlyLocationService.kt
- ใส่รหัสต่อไปนี้หลังความคิดเห็น
// TODO: Step 1.4, Initialize the LocationCallback.
locationCallback = object : LocationCallback() {
override fun onLocationResult(locationResult: LocationResult) {
super.onLocationResult(locationResult)
// Normally, you want to save a new location to a database. We are simplifying
// things a bit and just saving it as a local variable, as we only need it again
// if a Notification is created (when the user navigates away from app).
currentLocation = locationResult.lastLocation
// Notify our Activity that a new location was added. Again, if this was a
// production app, the Activity would be listening for changes to a database
// with new locations, but we are simplifying things a bit to focus on just
// learning the location side of things.
val intent = Intent(ACTION_FOREGROUND_ONLY_LOCATION_BROADCAST)
intent.putExtra(EXTRA_LOCATION, currentLocation)
LocalBroadcastManager.getInstance(applicationContext).sendBroadcast(intent)
// Updates notification content if this service is running as a foreground
// service.
if (serviceRunningInForeground) {
notificationManager.notify(
NOTIFICATION_ID,
generateNotification(currentLocation))
}
}
}
LocationCallback
ที่คุณสร้างที่นี่จะเป็น Callback ที่ FusedLocationProviderClient
จะโทรเมื่อมีการอัปเดตตำแหน่งใหม่
ใน Callback คุณจะได้รับตำแหน่งล่าสุดโดยใช้ออบเจ็กต์ LocationResult
ก่อน หลังจากนั้น คุณต้องแจ้ง Activity
เกี่ยวกับตำแหน่งใหม่โดยใช้การออกอากาศในท้องถิ่น (หากทำงานอยู่) หรืออัปเดต Notification
หากบริการนี้ทำงานอยู่เบื้องหน้า Service
- อ่านความคิดเห็นเพื่อทำความเข้าใจสิ่งที่แต่ละส่วนทำ
สมัครรับข้อมูลการเปลี่ยนแปลงสถานที่
ในตอนนี้คุณเริ่มต้นทุกอย่างแล้ว คุณต้องแจ้งให้ FusedLocationProviderClient
ทราบว่าคุณต้องการรับข้อมูลอัปเดต
- ในโมดูล
base
ให้ค้นหาStep 1.5, Subscribe to location changes
ในไฟล์ForegroundOnlyLocationService.kt
- ใส่รหัสต่อไปนี้หลังความคิดเห็น
// TODO: Step 1.5, Subscribe to location changes.
fusedLocationProviderClient.requestLocationUpdates(locationRequest, locationCallback, Looper.getMainLooper())
สายที่โทรผ่าน requestLocationUpdates()
จะช่วยให้ FusedLocationProviderClient
ทราบว่าคุณต้องการรับข้อมูลอัปเดตตำแหน่ง
คุณอาจจะจำ LocationRequest
และ LocationCallback
ที่กำหนดไว้ก่อนหน้านี้ได้ พารามิเตอร์ดังกล่าวช่วยให้ FusedLocationProviderClient
ทราบพารามิเตอร์คุณภาพของการบริการสำหรับคำขอของคุณและสิ่งที่ควรเรียกใช้เมื่อมีการอัปเดต สุดท้าย ออบเจ็กต์ Looper
ระบุเทรดสำหรับ Callback
นอกจากนี้ คุณยังอาจสังเกตเห็นว่ารหัสนี้อยู่ในคำสั่ง try/catch
วิธีนี้ต้องใช้การบล็อกดังกล่าวเนื่องจาก SecurityException
เกิดขึ้นเมื่อแอปของคุณไม่มีสิทธิ์เข้าถึงข้อมูลตำแหน่ง
ยกเลิกการสมัครรับการเปลี่ยนแปลงสถานที่
เมื่อแอปไม่จำเป็นต้องเข้าถึงข้อมูลตำแหน่งอีกต่อไป คุณต้องยกเลิกการสมัครรับการอัปเดตตำแหน่ง
- ในโมดูล
base
ให้ค้นหาTODO: Step 1.6, Unsubscribe to location changes
ในไฟล์ForegroundOnlyLocationService.kt
- ใส่รหัสต่อไปนี้หลังความคิดเห็น
// TODO: Step 1.6, Unsubscribe to location changes.
val removeTask = fusedLocationProviderClient.removeLocationUpdates(locationCallback)
removeTask.addOnCompleteListener { task ->
if (task.isSuccessful) {
Log.d(TAG, "Location Callback removed.")
stopSelf()
} else {
Log.d(TAG, "Failed to remove Location Callback.")
}
}
เมธอด removeLocationUpdates()
ตั้งค่างานเพื่อแจ้งให้ FusedLocationProviderClient
ทราบว่าคุณไม่ต้องการรับข้อมูลอัปเดตตำแหน่งสำหรับ LocationCallback
อีกต่อไป addOnCompleteListener()
จะการเรียกกลับเมื่อเสร็จสมบูรณ์และเรียกใช้ Task
คุณอาจสังเกตเห็นว่าโค้ดนี้อยู่ในคำสั่ง try/catch
เช่นเดียวกับขั้นตอนก่อนหน้านี้ วิธีนี้ต้องใช้การบล็อกดังกล่าวเนื่องจาก SecurityException
เกิดขึ้นเมื่อแอปของคุณไม่มีสิทธิ์เข้าถึงข้อมูลตำแหน่ง
คุณอาจสงสัยว่าจะมีการเรียกใช้เมธอดที่มีรหัสสมัคร/ยกเลิกการสมัครเมื่อใด การแจ้งเตือนจะแสดงผลในชั้นเรียนหลักเมื่อผู้ใช้แตะปุ่ม หากต้องการดู โปรดดูที่ชั้นเรียน MainActivity.kt
เรียกใช้แอป
เรียกใช้แอปจาก Android Studio แล้วลองใช้ปุ่มตำแหน่ง
คุณควรเห็นข้อมูลตำแหน่งในหน้าจอเอาต์พุต แอปนี้มีฟังก์ชันการทำงานเต็มรูปแบบสำหรับ Android 9
5. รองรับ Android 10
ในส่วนนี้ คุณจะเพิ่มการรองรับ Android 10
แอปของคุณสมัครรับข้อมูลการเปลี่ยนแปลงตำแหน่งอยู่แล้ว จึงไม่ต้องทำอะไรมาก
จริงๆ แล้ว คุณเพียงแค่ระบุว่าจะใช้บริการที่ทำงานอยู่เบื้องหน้าเพื่อจุดประสงค์ในการระบุตำแหน่ง
SDK เป้าหมาย 29
- ในโมดูล
base
ให้ค้นหาTODO: Step 2.1, Target Android 10 and then Android 11.
ในไฟล์build.gradle
- ทำการเปลี่ยนแปลงต่อไปนี้
- ตั้งค่า
targetSdkVersion
เป็น29
โค้ดของคุณควรมีลักษณะดังนี้
android {
// TODO: Step 2.1, Target Android 10 and then Android 11.
compileSdkVersion 29
defaultConfig {
applicationId "com.example.android.whileinuselocation"
minSdkVersion 26
targetSdkVersion 29
versionCode 1
versionName "1.0"
}
...
}
หลังจากดำเนินการแล้ว ระบบจะขอให้คุณซิงค์โปรเจ็กต์ คลิก Sync Now
หลังจากนั้น แอปของคุณก็ใกล้จะพร้อมแสดงใน Android 10 แล้ว
เพิ่มประเภทบริการที่ทำงานอยู่เบื้องหน้า
ใน Android 10 คุณต้องระบุประเภทของบริการที่ทำงานอยู่เบื้องหน้าหากต้องการสิทธิ์เข้าถึงตำแหน่งขณะใช้งาน ในกรณีของคุณ จะมีการใช้เพื่อค้นหาข้อมูลตำแหน่ง
ในโมดูล base
ให้ค้นหา TODO: 2.2, Add foreground service type
ใน AndroidManifest.xml
และเพิ่มโค้ดต่อไปนี้ลงในองค์ประกอบ <service>
android:foregroundServiceType="location"
โค้ดของคุณควรมีลักษณะดังนี้
<application>
...
<!-- Foreground services in Android 10+ require type. -->
<!-- TODO: 2.2, Add foreground service type. -->
<service
android:name="com.example.android.whileinuselocation.ForegroundOnlyLocationService"
android:enabled="true"
android:exported="false"
android:foregroundServiceType="location" />
</application>
เท่านี้ก็เรียบร้อย แอปของคุณรองรับตำแหน่งของ Android 10 สำหรับ "ขณะใช้งาน" โดยทำตามแนวทางปฏิบัติแนะนำสำหรับตำแหน่งใน Android
เรียกใช้แอป
เรียกใช้แอปจาก Android Studio แล้วลองใช้ปุ่มตำแหน่ง
ทุกอย่างควรทำงานเหมือนเดิม แต่ตอนนี้ใช้งานได้ใน Android 10 แล้ว หากก่อนหน้านี้คุณไม่เคยยอมรับการอนุญาตสำหรับสถานที่ ตอนนี้คุณควรจะเห็นหน้าจอสิทธิ์แล้ว
6. รองรับ Android 11
คุณกำหนดเป้าหมายเป็น Android 11 ในส่วนนี้
ข่าวดี คุณไม่จำเป็นต้องเปลี่ยนแปลงไฟล์ใดๆ ยกเว้นไฟล์ build.gradle
SDK เป้าหมาย 11
- ในโมดูล
base
ให้ค้นหาTODO: Step 2.1, Target SDK
ในไฟล์build.gradle
- ทำการเปลี่ยนแปลงต่อไปนี้
compileSdkVersion
ถึง30
targetSdkVersion
ถึง30
โค้ดของคุณควรมีลักษณะดังนี้
android {
TODO: Step 2.1, Target Android 10 and then Android 11.
compileSdkVersion 30
defaultConfig {
applicationId "com.example.android.whileinuselocation"
minSdkVersion 26
targetSdkVersion 30
versionCode 1
versionName "1.0"
}
...
}
หลังจากดำเนินการแล้ว ระบบจะขอให้คุณซิงค์โปรเจ็กต์ คลิก Sync Now
หลังจากนั้น แอปจะพร้อมใช้งานสำหรับ Android 11
เรียกใช้แอป
เรียกใช้แอปจาก Android Studio แล้วลองคลิกปุ่มดังกล่าว
ทุกอย่างควรจะทำงานได้ตามปกติ แต่ตอนนี้ใช้งานได้ใน Android 11 แล้ว หากก่อนหน้านี้คุณไม่เคยยอมรับการอนุญาตสำหรับสถานที่ ตอนนี้คุณควรจะเห็นหน้าจอสิทธิ์แล้ว
7. กลยุทธ์ตำแหน่งสำหรับ Android
การตรวจสอบและขอสิทธิ์เข้าถึงตำแหน่งตามวิธีที่แสดงใน Codelab นี้ทำให้แอปติดตามระดับการเข้าถึงเกี่ยวกับตำแหน่งอุปกรณ์ได้สำเร็จ
หน้านี้จะแสดงแนวทางปฏิบัติแนะนำบางส่วนที่เกี่ยวข้องกับสิทธิ์เข้าถึงตำแหน่ง ดูข้อมูลเพิ่มเติมเกี่ยวกับวิธีทำให้ผู้ใช้ของคุณ ความปลอดภัยของข้อมูล โปรดดูแนวทางปฏิบัติแนะนำเกี่ยวกับสิทธิ์ของแอป
ขอเฉพาะสิทธิ์ที่คุณต้องการ
ขอสิทธิ์เมื่อจำเป็นเท่านั้น เช่น
- อย่าขอสิทธิ์เข้าถึงตำแหน่งเมื่อเริ่มต้นแอป เว้นแต่จะจําเป็นจริงๆ
- หากแอปกำหนดเป้าหมายเป็น Android 10 ขึ้นไปและคุณมีบริการที่ทำงานอยู่เบื้องหน้า ให้ประกาศ
foregroundServiceType
เป็น"location"
ในไฟล์ Manifest - อย่าขอสิทธิ์เข้าถึงตำแหน่งในเบื้องหลังเว้นแต่คุณจะมีกรณีการใช้งานที่ถูกต้องตามที่อธิบายไว้ในการเข้าถึงตำแหน่งของผู้ใช้ที่ปลอดภัยและโปร่งใสมากขึ้น
สนับสนุนการลดลงอย่างค่อยเป็นค่อยไปหากไม่ได้รับอนุญาต
ออกแบบแอปให้สามารถรับมือกับสถานการณ์ต่อไปนี้ได้อย่างสวยงามเพื่อให้ผู้ใช้ได้รับประสบการณ์การใช้งานที่ดี
- แอปของคุณไม่มีสิทธิ์เข้าถึงข้อมูลตำแหน่ง
- แอปของคุณไม่มีสิทธิ์เข้าถึงข้อมูลตำแหน่งเมื่อทำงานในเบื้องหลัง
8. ขอแสดงความยินดี
คุณได้เรียนรู้วิธีรับการอัปเดตตำแหน่งใน Android แล้ว อย่าลืมนึกถึงแนวทางปฏิบัติแนะนำด้วย
ดูข้อมูลเพิ่มเติม
- ตัวอย่างแบบเต็มสำหรับการใช้ตำแหน่งในเบื้องหลังหากคุณมีกรณีการใช้งานที่ถูกต้อง
- ขออัปเดตตำแหน่ง