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 แบบที่แตกต่างกันได้ตั้งแต่ช่วงต้นของโค้ดแล็บ โดยมีความหมายดังนี้
- อนุญาตขณะใช้แอปเท่านั้น
- ตัวเลือกนี้เป็นตัวเลือกที่แนะนำสำหรับแอปส่วนใหญ่ ตัวเลือกนี้เรียกอีกอย่างว่าการเข้าถึง "ขณะใช้งาน" หรือ "เบื้องหน้าเท่านั้น" ซึ่งเพิ่มเข้ามาใน Android 10 และช่วยให้นักพัฒนาแอปดึงข้อมูลตำแหน่งได้เฉพาะในขณะที่แอปกำลังใช้งานอยู่เท่านั้น แอปจะถือว่าใช้งานอยู่หากมีลักษณะตรงตามข้อใดข้อหนึ่งต่อไปนี้
- กิจกรรมจะปรากฏ
- บริการที่ทำงานอยู่เบื้องหน้ากำลังทำงานพร้อมการแจ้งเตือนต่อเนื่อง
- ครั้งเดียวเท่านั้น
- ตัวเลือกนี้เพิ่มเข้ามาใน Android 11 และเหมือนกับอนุญาตขณะใช้แอปเท่านั้น แต่จะใช้ได้ในระยะเวลาจำกัด ดูข้อมูลเพิ่มเติมได้ที่สิทธิ์แบบครั้งเดียว
- ปฏิเสธ
- ตัวเลือกนี้จะป้องกันการเข้าถึงข้อมูลตำแหน่ง
- อนุญาตตลอด
- ตัวเลือกนี้อนุญาตให้เข้าถึงตำแหน่งได้ตลอดเวลา แต่ต้องมีสิทธิ์เพิ่มเติมสำหรับ Android 10 ขึ้นไป นอกจากนี้ คุณต้องตรวจสอบว่ามีกรณีการใช้งานที่ถูกต้องและปฏิบัติตามนโยบายตำแหน่ง คุณจะไม่เห็นตัวเลือกนี้ในโค้ดแล็บนี้ เนื่องจากเป็นกรณีการใช้งานที่พบได้น้อยกว่า อย่างไรก็ตาม หากคุณมี 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. เพิ่มฟีเจอร์ตำแหน่ง
โค้ดแล็บนี้มุ่งเน้นที่ตัวเลือกตำแหน่งที่พบบ่อยที่สุด นั่นคืออนุญาตขณะใช้แอปเท่านั้น
หากต้องการรับข้อมูลอัปเดตตำแหน่ง แอปจะต้องมีกิจกรรมที่มองเห็นได้หรือบริการที่ทำงานในเบื้องหน้า (พร้อมการแจ้งเตือน)
สิทธิ์
วัตถุประสงค์ของโค้ดแล็บนี้คือการแสดงวิธีรับข้อมูลอัปเดตตำแหน่ง ไม่ใช่วิธีขอสิทธิ์เข้าถึงตำแหน่ง ดังนั้นเราจึงเขียนโค้ดที่อิงตามสิทธิ์ไว้ให้คุณแล้ว คุณข้ามส่วนนี้ได้หากเข้าใจอยู่แล้ว
ไฮไลต์สิทธิ์มีดังนี้ (ไม่ต้องดำเนินการใดๆ ในส่วนนี้)
- ประกาศสิทธิ์ที่คุณใช้ใน
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ที่คุณสร้างที่นี่คือการเรียกกลับที่ FusedLocationProviderClient จะเรียกเมื่อมีการอัปเดตตำแหน่งใหม่
ในการเรียกกลับ คุณจะได้รับตำแหน่งล่าสุดก่อนโดยใช้ออบเจ็กต์ 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 จะระบุเธรดสำหรับการเรียกกลับ
คุณอาจสังเกตเห็นว่าโค้ดนี้อยู่ภายในคำสั่ง 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"
}
...
}
หลังจากดำเนินการนี้แล้ว ระบบจะขอให้คุณซิงค์โปรเจ็กต์ คลิกซิงค์เลย

หลังจากนั้น แอปของคุณก็เกือบพร้อมสำหรับ 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ถึง30targetSdkVersionถึง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"
}
...
}
หลังจากดำเนินการนี้แล้ว ระบบจะขอให้คุณซิงค์โปรเจ็กต์ คลิกซิงค์เลย

หลังจากนั้น แอปของคุณก็พร้อมสำหรับ Android 11 แล้ว
เรียกใช้แอป
เรียกใช้แอปจาก Android Studio แล้วลองคลิกปุ่ม
ทุกอย่างควรทำงานได้เหมือนเดิม แต่ตอนนี้ใช้ได้ใน Android 11 แล้ว หากก่อนหน้านี้คุณไม่ได้ยอมรับสิทธิ์เข้าถึงตำแหน่ง ตอนนี้คุณควรเห็นหน้าจอขอสิทธิ์แล้ว


7. กลยุทธ์ด้านตำแหน่งสำหรับ Android
การตรวจสอบและขอสิทธิ์เข้าถึงตำแหน่งในวิธีที่แสดงในโค้ดแล็บนี้จะช่วยให้แอปติดตามระดับการเข้าถึงตำแหน่งของอุปกรณ์ได้สำเร็จ
หน้านี้แสดงแนวทางปฏิบัติแนะนำที่สำคัญบางส่วนเกี่ยวกับการให้สิทธิ์เข้าถึงตำแหน่ง ดูข้อมูลเพิ่มเติมเกี่ยวกับวิธีรักษาข้อมูลของผู้ใช้ให้ปลอดภัยได้ที่แนวทางปฏิบัติแนะนำเกี่ยวกับสิทธิ์ของแอป
ขอเฉพาะสิทธิ์ที่จำเป็นเท่านั้น
ขอสิทธิ์เมื่อจำเป็นเท่านั้น เช่น
- อย่าขอสิทธิ์เข้าถึงตำแหน่งเมื่อแอปเริ่มต้นทำงาน เว้นแต่จะจำเป็นอย่างยิ่ง
- หากแอปกำหนดเป้าหมายเป็น Android 10 ขึ้นไปและมีบริการที่ทำงานอยู่เบื้องหน้า ให้ประกาศ
foregroundServiceTypeของ"location"ในไฟล์ Manifest - อย่าขอสิทธิ์เข้าถึงตำแหน่งในเบื้องหลัง เว้นแต่จะมีกรณีการใช้งานที่ถูกต้องตามที่อธิบายไว้ในการเข้าถึงตำแหน่งของผู้ใช้ที่ปลอดภัยและโปร่งใสยิ่งขึ้น
รองรับการลดระดับอย่างราบรื่นหากไม่ได้รับสิทธิ์
ออกแบบแอปให้รองรับสถานการณ์ต่อไปนี้ได้อย่างราบรื่นเพื่อรักษาประสบการณ์การใช้งานที่ดี
- แอปของคุณไม่มีสิทธิ์เข้าถึงข้อมูลตำแหน่ง
- แอปของคุณไม่มีสิทธิ์เข้าถึงข้อมูลตำแหน่งเมื่อทำงานในเบื้องหลัง
8. ขอแสดงความยินดี
คุณได้เรียนรู้วิธีรับข้อมูลอัปเดตตำแหน่งใน Android โดยคำนึงถึงแนวทางปฏิบัติแนะนำแล้ว
ดูข้อมูลเพิ่มเติม
- ตัวอย่างฉบับเต็มสำหรับการใช้ตำแหน่งในเบื้องหลังหากคุณมีกรณีการใช้งานที่ถูกต้อง
- ขอข้อมูลอัปเดตตำแหน่ง