การใช้ข้อมูลตำแหน่งอย่างเหมาะสมอาจเป็นประโยชน์ต่อผู้ใช้แอป เช่น หากแอปช่วยให้ผู้ใช้หาเส้นทางขณะเดินหรือขับรถ หรือหากแอปติดตามตำแหน่งของเนื้อหา แอปก็จะต้องได้รับตำแหน่งของอุปกรณ์เป็นระยะๆ นอกจากสถานที่ตั้งทางภูมิศาสตร์ (ละติจูดและลองจิจูด) แล้ว คุณอาจต้องการให้ข้อมูลเพิ่มเติมแก่ผู้ใช้ เช่น ทิศทาง (ทิศทางการเคลื่อนที่ในแนวนอน) ความสูง หรือความเร็วของอุปกรณ์ ข้อมูลนี้และข้อมูลอื่นๆ มีอยู่ในออบเจ็กต์ Location
ที่แอปสามารถดึงข้อมูลจากผู้ให้บริการตำแหน่งแบบรวม ด้วยเหตุนี้ API จึงอัปเดตแอปเป็นระยะๆ ด้วยตำแหน่งที่ดีที่สุดที่พร้อมใช้งาน โดยอิงตามผู้ให้บริการตำแหน่งที่พร้อมใช้งานในปัจจุบัน เช่น Wi-Fi และ GPS (ระบบกำหนดตำแหน่งทั่วโลก) ความแม่นยำของตำแหน่งจะขึ้นอยู่กับผู้ให้บริการ, สิทธิ์เข้าถึงตำแหน่งที่คุณขอ และตัวเลือกที่คุณตั้งค่าในคำขอตำแหน่ง
บทเรียนนี้จะแสดงวิธีขอการอัปเดตตำแหน่งของอุปกรณ์เป็นประจําโดยใช้เมธอด requestLocationUpdates()
ในผู้ให้บริการตำแหน่งแบบรวม
รับตำแหน่งที่รู้จักล่าสุด
ตำแหน่งสุดท้ายที่ทราบของอุปกรณ์จะมีฐานที่สะดวกสำหรับการเริ่มต้น เพื่อให้แน่ใจว่าแอปมีตำแหน่งที่รู้จักก่อนเริ่มการอัปเดตตำแหน่งเป็นครั้งคราว บทเรียนเกี่ยวกับการรับตำแหน่งล่าสุดที่ทราบจะแสดงวิธีรับตำแหน่งล่าสุดที่ทราบโดยการโทรไปที่ getLastLocation()
ข้อมูลโค้ดในส่วนต่อไปนี้จะถือว่าแอปของคุณได้เรียกข้อมูลตำแหน่งที่ทราบล่าสุดและจัดเก็บเป็นออบเจ็กต์ Location
ในตัวแปรร่วม mCurrentLocation
แล้ว
ส่งคำขอตำแหน่ง
ก่อนที่จะขอการอัปเดตตำแหน่ง แอปของคุณต้องเชื่อมต่อกับบริการตำแหน่งและส่งคำขอตำแหน่ง บทเรียนเรื่องการเปลี่ยนการตั้งค่าตำแหน่งจะแสดงวิธีการ เมื่อมีการส่งคำขอตำแหน่งแล้ว คุณจะเริ่มการอัปเดตตามปกติได้โดยโทรไปที่ requestLocationUpdates()
ผู้ให้บริการ Fused Location จะเรียกใช้เมธอด Callback LocationCallback.onLocationResult()
และส่งต่อรายการออบเจ็กต์ Location
หรือออก PendingIntent
ที่มีตำแหน่งในข้อมูลแบบขยาย ทั้งนี้ขึ้นอยู่กับรูปแบบของคำขอ ความแม่นยำและความถี่ในการอัปเดตจะขึ้นอยู่กับสิทธิ์เข้าถึงตำแหน่งที่คุณขอและตัวเลือกที่คุณตั้งค่าไว้ในออบเจ็กต์คำขอตำแหน่ง
บทเรียนนี้แสดงวิธีรับการอัปเดตโดยใช้วิธี Callback ของ LocationCallback
เรียกใช้ requestLocationUpdates()
โดยส่งอินสแตนซ์ของออบเจ็กต์ LocationRequest
และ LocationCallback
กำหนดเมธอด startLocationUpdates()
ดังที่แสดงในตัวอย่างโค้ดต่อไปนี้
Kotlin
override fun onResume() { super.onResume() if (requestingLocationUpdates) startLocationUpdates() } private fun startLocationUpdates() { fusedLocationClient.requestLocationUpdates(locationRequest, locationCallback, Looper.getMainLooper()) }
Java
@Override protected void onResume() { super.onResume(); if (requestingLocationUpdates) { startLocationUpdates(); } } private void startLocationUpdates() { fusedLocationClient.requestLocationUpdates(locationRequest, locationCallback, Looper.getMainLooper()); }
โปรดสังเกตว่าข้อมูลโค้ดด้านบนหมายถึงธงบูลีน requestingLocationUpdates
ซึ่งใช้เพื่อติดตามว่าผู้ใช้เปิดหรือปิดการอัปเดตตำแหน่ง หากผู้ใช้ปิดการอัปเดตตำแหน่งไว้ คุณจะแจ้งผู้ใช้เกี่ยวกับข้อกำหนดตำแหน่งของแอปได้ ดูข้อมูลเพิ่มเติมเกี่ยวกับการรักษาค่าของแฟล็กบูลีนไว้ในอินสแตนซ์ของกิจกรรมได้ที่บันทึกสถานะของกิจกรรม
กำหนดการเรียกกลับการอัปเดตตำแหน่ง
ผู้ให้บริการตำแหน่งที่ผสานจะเรียกใช้เมธอด Callback ของ LocationCallback.onLocationResult()
อาร์กิวเมนต์ขาเข้ามีออบเจ็กต์รายการ Location
ที่มีละติจูดและลองจิจูดของตำแหน่ง ข้อมูลโค้ดต่อไปนี้แสดงวิธีใช้LocationCallback
อินเทอร์เฟซและกำหนดเมธอด จากนั้นรับการประทับเวลาของการอัปเดตตำแหน่ง และแสดงละติจูด ลองจิจูด และการประทับเวลาในอินเทอร์เฟซผู้ใช้ของแอป
Kotlin
private lateinit var locationCallback: LocationCallback // ... override fun onCreate(savedInstanceState: Bundle?) { // ... locationCallback = object : LocationCallback() { override fun onLocationResult(locationResult: LocationResult?) { locationResult ?: return for (location in locationResult.locations){ // Update UI with location data // ... } } } }
Java
private LocationCallback locationCallback; // ... @Override protected void onCreate(Bundle savedInstanceState) { // ... locationCallback = new LocationCallback() { @Override public void onLocationResult(LocationResult locationResult) { if (locationResult == null) { return; } for (Location location : locationResult.getLocations()) { // Update UI with location data // ... } } }; }
หยุดการอัปเดตตำแหน่ง
ลองพิจารณาว่าคุณต้องการหยุดการอัปเดตตำแหน่งเมื่อกิจกรรม
ไม่ได้อยู่ในโฟกัสแล้วหรือไม่ เช่น เมื่อผู้ใช้สลับไปยังแอปอื่นหรือไปยัง
กิจกรรมอื่นในแอปเดียวกัน วิธีนี้มีประโยชน์ในการลดการใช้พลังงาน โดยที่แอปไม่จำเป็นต้องรวบรวมข้อมูลแม้ว่า
จะทำงานอยู่เบื้องหลัง ส่วนนี้จะแสดงวิธีหยุดการอัปเดตในเมธอด onPause()
ของกิจกรรม
หากต้องการหยุดการอัปเดตตำแหน่ง ให้เรียกใช้ removeLocationUpdates()
โดยส่ง LocationCallback
ไปให้ ดังที่แสดงในตัวอย่างโค้ดต่อไปนี้
Kotlin
override fun onPause() { super.onPause() stopLocationUpdates() } private fun stopLocationUpdates() { fusedLocationClient.removeLocationUpdates(locationCallback) }
Java
@Override protected void onPause() { super.onPause(); stopLocationUpdates(); } private void stopLocationUpdates() { fusedLocationClient.removeLocationUpdates(locationCallback); }
ใช้บูลีน requestingLocationUpdates
เพื่อติดตามว่าขณะนี้การอัปเดตตำแหน่งเปิดอยู่หรือไม่ ในเมธอด onResume()
ของกิจกรรม ให้ตรวจสอบว่าขณะนี้การอัปเดตตำแหน่งทำงานอยู่หรือไม่ และเปิดใช้งานหากไม่ได้ทำงานอยู่ โดยทำดังนี้
Kotlin
override fun onResume() { super.onResume() if (requestingLocationUpdates) startLocationUpdates() }
Java
@Override protected void onResume() { super.onResume(); if (requestingLocationUpdates) { startLocationUpdates(); } }
บันทึกสถานะของกิจกรรม
การเปลี่ยนแปลงการกําหนดค่าอุปกรณ์ เช่น การเปลี่ยนการวางแนวหน้าจอหรือภาษา อาจทําให้กิจกรรมปัจจุบันถูกทำลาย ดังนั้นแอปจึงต้องจัดเก็บข้อมูลที่จำเป็นในการสร้างกิจกรรมอีกครั้ง
วิธีหนึ่งในการทำเช่นนี้คือผ่านสถานะอินสแตนซ์ที่เก็บไว้ในออบเจ็กต์ Bundle
ตัวอย่างโค้ดต่อไปนี้แสดงวิธีใช้ Callback onSaveInstanceState()
ของกิจกรรมเพื่อบันทึกสถานะอินสแตนซ์
Kotlin
override fun onSaveInstanceState(outState: Bundle?) { outState?.putBoolean(REQUESTING_LOCATION_UPDATES_KEY, requestingLocationUpdates) super.onSaveInstanceState(outState) }
Java
@Override protected void onSaveInstanceState(Bundle outState) { outState.putBoolean(REQUESTING_LOCATION_UPDATES_KEY, requestingLocationUpdates); // ... super.onSaveInstanceState(outState); }
กำหนดเมธอด updateValuesFromBundle()
เพื่อกู้คืนค่าที่บันทึกไว้จากอินสแตนซ์ก่อนหน้าของกิจกรรม หากมี เรียกใช้เมธอดจากเมธอด onCreate()
ของกิจกรรม ดังที่แสดงในตัวอย่างโค้ดต่อไปนี้
Kotlin
override fun onCreate(savedInstanceState: Bundle?) { // ... updateValuesFromBundle(savedInstanceState) } private fun updateValuesFromBundle(savedInstanceState: Bundle?) { savedInstanceState ?: return // Update the value of requestingLocationUpdates from the Bundle. if (savedInstanceState.keySet().contains(REQUESTING_LOCATION_UPDATES_KEY)) { requestingLocationUpdates = savedInstanceState.getBoolean( REQUESTING_LOCATION_UPDATES_KEY) } // ... // Update UI to match restored state updateUI() }
Java
@Override public void onCreate(Bundle savedInstanceState) { // ... updateValuesFromBundle(savedInstanceState); } private void updateValuesFromBundle(Bundle savedInstanceState) { if (savedInstanceState == null) { return; } // Update the value of requestingLocationUpdates from the Bundle. if (savedInstanceState.keySet().contains(REQUESTING_LOCATION_UPDATES_KEY)) { requestingLocationUpdates = savedInstanceState.getBoolean( REQUESTING_LOCATION_UPDATES_KEY); } // ... // Update UI to match restored state updateUI(); }
ดูข้อมูลเพิ่มเติมเกี่ยวกับการบันทึกสถานะอินสแตนซ์ได้ที่ข้อมูลอ้างอิงคลาสกิจกรรม Android
หมายเหตุ: หากต้องการพื้นที่เก็บข้อมูลถาวรมากขึ้น คุณสามารถจัดเก็บค่ากำหนดของผู้ใช้ไว้ใน SharedPreferences
ของแอป ตั้งค่ากำหนดที่แชร์ในเมธอด onPause()
ของกิจกรรม และเรียกข้อมูลค่ากำหนดใน onResume()
ดูข้อมูลเพิ่มเติมเกี่ยวกับการบันทึกค่ากําหนดได้ที่หัวข้อการบันทึกชุดคีย์-ค่า
แหล่งข้อมูลเพิ่มเติม
หากต้องการดูข้อมูลเพิ่มเติม โปรดใช้ประโยชน์จากแหล่งข้อมูลต่อไปนี้
ตัวอย่าง
- แอปตัวอย่างเพื่อสาธิตการรับการอัปเดตตำแหน่งใน Android