รับการอัปเดตตําแหน่งใน Android ด้วย Kotlin

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 สําหรับนักพัฒนาซอฟต์แวร์

จําลองที่เก็บโปรเจ็กต์เริ่มต้น

คุณสามารถสร้างโปรเจ็กต์เริ่มต้นนี้เพื่อให้เริ่มต้นใช้งานโดยเร็วที่สุดได้ หากติดตั้ง Git ไว้ คุณสามารถเรียกใช้คําสั่งต่อไปนี้

 git clone https://github.com/googlecodelabs/while-in-use-location

โปรดไปที่หน้า GitHub โดยตรง

หากไม่มี Git คุณสามารถรับโปรเจ็กต์เป็นไฟล์ ZIP ได้ดังนี้

ดาวน์โหลด ZIP

นําเข้าโปรเจ็กต์

เปิด Android Studio เลือก เปิดโปรเจ็กต์ Android Studio ที่มีอยู่&quot จากหน้าจอต้อนรับ แล้วเปิดไดเรกทอรีโปรเจ็กต์

หลังจากโปรเจ็กต์โหลดแล้ว คุณอาจเห็นการแจ้งเตือนว่า Git ไม่ได้ติดตามการเปลี่ยนแปลงในเครื่องทั้งหมด คุณคลิกไม่สนใจได้ (คุณจะไม่พุชการเปลี่ยนแปลงใดๆ กลับไปยังที่เก็บ Git)

ที่มุมบนซ้ายของหน้าต่างโครงการ คุณจะเห็นข้อมูลที่มีลักษณะเหมือนรูปภาพด้านล่างหากอยู่ในมุมมอง Android (หากอยู่ในมุมมองโปรเจ็กต์ คุณจะต้องขยายโปรเจ็กต์เพื่อให้เห็นสิ่งเดียวกัน)

โฟลเดอร์มี 2 โฟลเดอร์ (base และ complete) แต่ละโฟลเดอร์เรียกว่า "module"

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

รอจนกว่า Android Studio จะจัดทําดัชนีและสร้างโปรเจ็กต์เสร็จเรียบร้อยแล้วก่อนที่จะเปลี่ยนแปลงโค้ด การดําเนินการนี้จะช่วยให้ Android Studio ดึงข้อมูลคอมโพเนนต์ที่จําเป็นทั้งหมดได้

หากคุณได้รับข้อความแจ้งโหลดซ้ําเพื่อให้การเปลี่ยนแปลงภาษามีผลหรือไม่ หรือข้อความที่คล้ายกัน ให้เลือกใช่

ทําความเข้าใจโปรเจ็กต์เริ่มต้น

คุณตั้งค่าและพร้อมส่งคําขอตําแหน่งในแอปแล้ว ใช้โมดูล base เป็นจุดเริ่มต้น เพิ่มโค้ดในโมดูล base ในแต่ละขั้นตอน เมื่อทํา Codelab เสร็จแล้ว โค้ดในโมดูล base ควรตรงกับเนื้อหาของโมดูล complete โมดูล complete สามารถใช้เพื่อตรวจสอบงานของคุณหรือให้คุณอ้างอิงหากพบปัญหา

องค์ประกอบหลักประกอบด้วย

  • MainActivity—UI สําหรับให้ผู้ใช้อนุญาตให้แอปเข้าถึงตําแหน่งของอุปกรณ์##39;
  • LocationService คือบริการที่ติดตามและยกเลิกการสมัครรับการเปลี่ยนแปลงสถานที่ และโปรโมตบริการที่ทํางานอยู่เบื้องหน้า (ด้วยการแจ้งเตือน) หากผู้ใช้ออกจากกิจกรรมของแอป คุณเพิ่มรหัสสถานที่ตั้งได้ที่นี่
  • Util - เพิ่มฟังก์ชันส่วนขยายสําหรับคลาส Location และบันทึกตําแหน่งใน SharedPreferences (ชั้นข้อมูลที่เรียบง่าย)

การตั้งค่าโปรแกรมจําลอง

โปรดดูข้อมูลเพิ่มเติมเกี่ยวกับการตั้งค่าโปรแกรมจําลองของ Android ที่หัวข้อเรียกใช้โปรแกรมจําลอง

ทําโปรเจ็กต์เริ่มต้น

เรียกใช้แอป

  1. เชื่อมต่ออุปกรณ์ Android กับคอมพิวเตอร์หรือเริ่มโปรแกรมจําลอง (ตรวจสอบว่าอุปกรณ์ใช้ Android 10 ขึ้นไป)
  2. ในแถบเครื่องมือ ให้เลือกการกําหนดค่า base จากตัวเลือกแบบเลื่อนลง แล้วคลิกเรียกใช้


  1. โปรดสังเกตว่าแอปต่อไปนี้จะปรากฏในอุปกรณ์ของคุณ


คุณอาจสังเกตเห็นว่าไม่มีข้อมูลตําแหน่งปรากฏในหน้าจอเอาต์พุต นั่นเป็นเพราะคุณยังไม่ได้เพิ่มรหัสสถานที่ตั้ง

แนวคิด

จุดมุ่งเน้นของ Codelab นี้คือการแสดงวิธีรับการอัปเดตตําแหน่ง และรองรับ Android 10 และ Android 11 ในที่สุด

อย่างไรก็ตาม ก่อนที่จะเริ่มต้นเขียนโค้ด คุณควรอ่านข้อมูลเบื้องต้น

ประเภทของการเข้าถึงตําแหน่ง

คุณอาจจํา 4 ตัวเลือกที่แตกต่างกันสําหรับการเข้าถึงตําแหน่งตั้งแต่ต้นของ Codelab ลองดูความหมาย

  • อนุญาตขณะมีการใช้แอปเท่านั้น
  • ตัวเลือกนี้เป็นตัวเลือกที่แนะนําสําหรับแอปส่วนใหญ่ หรือที่เรียกว่า ""ขณะใช้งาน" หรือ "ส่วนหน้าเท่านั้น"" การเข้าถึง ได้มีการเพิ่มตัวเลือกนี้ใน Android 10 และทําให้นักพัฒนาซอฟต์แวร์สามารถเรียกตําแหน่งได้เฉพาะขณะที่กําลังใช้งานแอปเท่านั้น จะถือว่าแอปใดแอปหนึ่งทํางานเมื่อข้อใดข้อหนึ่งต่อไปนี้เป็นจริง
  • กิจกรรมแสดงอยู่
  • มีบริการที่ทํางานอยู่เบื้องหน้าพร้อมการแจ้งเตือนอย่างต่อเนื่อง
  • ครั้งเดียวเท่านั้น
  • เพิ่มไปยัง Android 11 ซึ่งเหมือนกับอนุญาตขณะใช้แอปเท่านั้น แต่มีเวลาจํากัด โปรดดูข้อมูลเพิ่มเติมที่หัวข้อสิทธิ์ครั้งเดียว
  • ปฏิเสธ
  • ตัวเลือกนี้จะป้องกันไม่ให้เข้าถึงข้อมูลตําแหน่ง
  • อนุญาตตลอด
  • ตัวเลือกนี้อนุญาตให้เข้าถึงตําแหน่งตลอดเวลา แต่ต้องมีสิทธิ์เพิ่มเติมสําหรับ Android 10 ขึ้นไป นอกจากนี้คุณยังต้องมี Use Case ที่ถูกต้องและเป็นไปตามนโยบายตําแหน่ง คุณจะไม่ครอบคลุมตัวเลือกนี้ใน Codelab เนื่องจากเป็นกรณีการใช้งานที่ไม่ค่อยเกิดขึ้น อย่างไรก็ตาม หากคุณมีกรณีการใช้งานที่ถูกต้องและต้องการทําความเข้าใจวิธีจัดการตําแหน่งตั้งแต่ต้นอย่างถูกต้อง รวมถึงการเข้าถึงตําแหน่งในเบื้องหลัง โปรดอ่านตัวอย่าง LocationUpdatesBackgroundKotlin

บริการ บริการที่ทํางานอยู่เบื้องหน้า และการเชื่อมโยง

หากต้องการรองรับการอัปเดตตําแหน่งแบบอนุญาตขณะใช้แอปเท่านั้นโดยสมบูรณ์ คุณต้องคํานึงถึงเวลาที่ผู้ใช้ไปยังส่วนต่างๆ ของแอปด้วย หากต้องการรับการอัปเดตในสถานการณ์นั้นต่อไป คุณต้องสร้างเบื้องหน้าServiceและเชื่อมโยงกับ Notification

นอกจากนี้ หากต้องการใช้ Service เดียวกันเพื่อขออัปเดตตําแหน่งเมื่อมองเห็นแอป และเมื่อผู้ใช้ออกจากแอปของคุณ คุณจะต้องเชื่อมโยง/ยกเลิกการเชื่อมโยง Service กับองค์ประกอบ UI

เนื่องจาก Codelab นี้มุ่งเน้นที่การรับการอัปเดตตําแหน่งเท่านั้น คุณจะค้นหาโค้ดทั้งหมดที่จําเป็นได้ในชั้นเรียน ForegroundOnlyLocationService.kt คุณจะเรียกดูชั้นเรียนดังกล่าวและ MainActivity.kt เพื่อดูการทํางานร่วมกันได้

ดูข้อมูลเพิ่มเติมได้ที่ภาพรวมของบริการและภาพรวมบริการ

สิทธิ์

หากต้องการรับการอัปเดตตําแหน่งจาก 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 เพื่อบันทึกไว้ในฐานข้อมูลของคุณ

ตอนนี้คุณมีแนวคิดเบื้องต้นว่ากําลังทําอะไรอยู่ มาเริ่มเขียนโค้ดกันเลย

Codelab นี้มุ่งเน้นที่ตัวเลือกสถานที่ตั้งที่พบบ่อยที่สุด ได้แก่ อนุญาตขณะใช้แอปเท่านั้น

หากต้องการอัปเดตแอปตําแหน่ง แอปจะต้องมีกิจกรรมที่มองเห็นได้หรือบริการที่ทํางานอยู่ในเบื้องหน้า (พร้อมการแจ้งเตือน)

สิทธิ์

วัตถุประสงค์ของ Codelab นี้คือวิธีรับการอัปเดตตําแหน่ง ไม่ใช่วิธีขอสิทธิ์เข้าถึงตําแหน่ง ระบบจึงเขียนโค้ดตามสิทธิ์ให้คุณอยู่แล้ว คุณสามารถข้ามกรณีนี้ได้หากเข้าใจอยู่แล้ว

ไฮไลต์สิทธิ์ต่อไปนี้ (ไม่ต้องดําเนินการใดๆ ในส่วนนี้)

  1. ประกาศสิทธิ์ที่คุณใช้ในAndroidManifest.xml
  2. ก่อนที่จะพยายามเข้าถึงข้อมูลตําแหน่ง ให้ตรวจสอบว่าผู้ใช้ให้สิทธิ์แอปของคุณในการเข้าถึงหรือไม่ หากแอปยังไม่ได้รับสิทธิ์ ให้ขอสิทธิ์เข้าถึง
  3. จัดการตัวเลือกสิทธิ์ของผู้ใช้ (คุณจะเห็นรหัสนี้ใน 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

  1. ในโมดูล base ให้ค้นหา TODO: Step 1.3, Create a LocationRequest ในไฟล์ ForegroundOnlyLocationService.kt
  2. เพิ่มโค้ดต่อไปนี้หลังความคิดเห็น

โค้ดการเริ่มต้นของ LocationRequest จะเพิ่มคุณภาพของพารามิเตอร์บริการเพิ่มเติมที่คุณต้องใช้ในคําขอ (ช่วงเวลา เวลารอสูงสุด และลําดับความสําคัญ)

// TODO: Step 1.3, Create a LocationRequest.
locationRequest = LocationRequest().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
}
  1. อ่านความคิดเห็นเพื่อทําความเข้าใจวิธีการทํางานของความคิดเห็นแต่ละรายการ

เริ่มต้น LocationCallback

  1. ในโมดูล base ให้ค้นหา TODO: Step 1.4, Initialize the LocationCallback ในไฟล์ ForegroundOnlyLocationService.kt
  2. เพิ่มโค้ดต่อไปนี้หลังความคิดเห็น
// TODO: Step 1.4, Initialize the LocationCallback.
locationCallback = object : LocationCallback() {
   override fun onLocationResult(locationResult: LocationResult?) {
       super.onLocationResult(locationResult)

       if (locationResult?.lastLocation != null) {

           // 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 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))
           }
       } else {
           Log.d(TAG, "Location information isn't available.")
       }
   }
}

LocationCallback ที่คุณสร้างที่นี่คือโค้ดเรียกกลับที่ FusedLocationProviderClient จะเรียกใช้เมื่อการอัปเดตตําแหน่งใหม่พร้อมใช้งาน

ในการเรียกกลับ ก่อนอื่นคุณจะต้องได้ตําแหน่งล่าสุดโดยใช้ออบเจ็กต์ LocationResult หลังจากนั้น คุณจะแจ้ง Activity ของตําแหน่งใหม่โดยใช้ประกาศในท้องถิ่น (หากใช้งานอยู่) หรือคุณอัปเดต Notification หากบริการนี้ทํางานอยู่เป็นเบื้องหน้า Service

  1. อ่านความคิดเห็นเพื่อทําความเข้าใจแต่ละส่วนก่อน

ติดตามการเปลี่ยนแปลงตําแหน่ง

เมื่อเริ่มต้นทุกอย่างแล้ว คุณจะต้องแจ้งให้ FusedLocationProviderClient ทราบว่าคุณต้องการรับข้อมูลอัปเดต

  1. ในโมดูล base ให้ค้นหา Step 1.5, Subscribe to location changes ในไฟล์ ForegroundOnlyLocationService.kt
  2. เพิ่มโค้ดต่อไปนี้หลังความคิดเห็น
// TODO: Step 1.5, Subscribe to location changes.
fusedLocationProviderClient.requestLocationUpdates(locationRequest, locationCallback, Looper.myLooper())

การโทรจาก requestLocationUpdates() จะแจ้ง FusedLocationProviderClient ว่าคุณต้องการรับการอัปเดตตําแหน่ง

คุณอาจจํา LocationRequest และ LocationCallback ที่คุณกําหนดไว้ก่อนหน้านี้ได้ รายการเหล่านี้ช่วยให้ FusedLocationProviderClient ได้ทราบพารามิเตอร์คุณภาพของบริการสําหรับคําขอและสิ่งที่ควรเรียกเมื่อมีอัปเดต สุดท้าย ออบเจ็กต์ Looper จะระบุชุดข้อความสําหรับโค้ดเรียกกลับ

คุณอาจสังเกตเห็นว่าโค้ดนี้อยู่ในคําสั่ง try/catch วิธีการนี้ต้องมีการบล็อกเนื่องจาก SecurityException จะเกิดขึ้นเมื่อแอปของคุณไม่มีสิทธิ์เข้าถึงข้อมูลตําแหน่ง

ยกเลิกการสมัครรับการเปลี่ยนแปลงสถานที่

เมื่อแอปไม่จําเป็นต้องเข้าถึงข้อมูลตําแหน่งอีกต่อไป การยกเลิกการสมัครอัปเดตตําแหน่งก็เป็นสิ่งสําคัญ

  1. ในโมดูล base ให้ค้นหา TODO: Step 1.6, Unsubscribe to location changes ในไฟล์ ForegroundOnlyLocationService.kt
  2. เพิ่มโค้ดต่อไปนี้หลังความคิดเห็น
// 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

เพิ่มการรองรับ Android 10 ในส่วนนี้

แอปของคุณติดตามการเปลี่ยนแปลงตําแหน่งอยู่แล้ว คุณไม่ต้องทําอะไรมากมายเลย

ที่จริงแล้ว สิ่งที่คุณต้องทําก็คือ ระบุว่าจะให้ใช้บริการที่ทํางานอยู่เบื้องหน้าเพื่อวัตถุประสงค์ด้านตําแหน่งหรือไม่

SDK เป้าหมาย 29

  1. ในโมดูล base ให้ค้นหา TODO: Step 2.1, Target SDK 10 ในไฟล์ build.gradle
  2. ทําการเปลี่ยนแปลงเหล่านี้
  1. ตั้งค่า compileSdkVersion เป็น 29
  2. ตั้งค่า buildToolsVersion เป็น "29.0.3"
  3. ตั้งค่า targetSdkVersion เป็น 29

โค้ดควรมีลักษณะดังนี้

android {
   // TODO: Step 2.1, Target Android 10.
   compileSdkVersion 29
   buildToolsVersion "29.0.3"
   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 สําหรับ &{0}tt;;ขณะใช้งาน&&" โดยทําตามแนวทางปฏิบัติแนะนําสําหรับตําแหน่งใน Android

เรียกใช้แอป

เรียกใช้แอปจาก Android Studio แล้วลองใช้ปุ่มตําแหน่ง

ทุกสิ่งควรทํางานเหมือนก่อนหน้านี้ แต่ตอนนี้ใช้งานได้แล้วใน Android 10 หากที่ผ่านมาคุณไม่ยอมรับสิทธิ์สําหรับสถานที่ คุณก็จะเห็นหน้าจอสิทธิ์แล้ว

ในส่วนนี้ คุณจะกําหนดเป้าหมายเป็น Android 11

ข่าวดี คุณไม่จําเป็นต้องแก้ไขไฟล์ใดๆ ยกเว้นไฟล์ build.gradle!

SDK เป้าหมาย

  1. ในโมดูล base ให้ค้นหา TODO: Step 2.1, Target SDK ในไฟล์ build.gradle
  2. ทําการเปลี่ยนแปลงเหล่านี้
  1. compileSdkVersion ไปยัง "android-R"
  2. targetSdkVersion ไปยัง "R"

โค้ดควรมีลักษณะดังนี้

android {
   // TODO: Step 2.1, Target Android 10.
   compileSdkVersion "android-R"
   buildToolsVersion "29.0.2"
   defaultConfig {
       applicationId "com.example.android.whileinuselocation"
       minSdkVersion 26
       targetSdkVersion "R"
       versionCode 1
       versionName "1.0"
   }
...
}

เมื่อดําเนินการนี้แล้ว ระบบจะขอให้คุณซิงค์โปรเจ็กต์ คลิก Sync Now

หลังจากนั้นแอปจะพร้อมใช้งานสําหรับ Android 11

เรียกใช้แอป

เรียกใช้แอปจาก Android Studio แล้วลองคลิกปุ่ม

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

การตรวจสอบและขอสิทธิ์เข้าถึงตําแหน่งโดยใช้วิธีที่แสดงใน Codelab นี้ทําให้แอปของคุณติดตามระดับการเข้าถึงของอุปกรณ์ได้

หน้านี้มีแนวทางปฏิบัติแนะนําบางส่วนที่เกี่ยวข้องกับสิทธิ์เข้าถึงตําแหน่ง ดูข้อมูลเพิ่มเติมเกี่ยวกับวิธีรักษาความปลอดภัยของผู้ใช้และข้อมูลได้ที่แนวทางปฏิบัติแนะนําเกี่ยวกับสิทธิ์ของแอป

ขอสิทธิ์ที่จําเป็นเท่านั้น

ขอสิทธิ์เมื่อจําเป็นเท่านั้น เช่น

  • อย่าขอสิทธิ์เข้าถึงตําแหน่งเมื่อเริ่มต้นแอป เว้นแต่จําเป็นอย่างยิ่ง
  • หากแอปกําหนดเป้าหมายเป็น Android 10 ขึ้นไปและคุณมีบริการที่ทํางานอยู่เบื้องหน้า ให้ประกาศ foregroundServiceType จาก "location" ในไฟล์ Manifest
  • อย่าขอสิทธิ์เข้าถึงตําแหน่งในเบื้องหลังเว้นแต่คุณจะมี Use Case ที่ถูกต้องตามที่อธิบายไว้ในการเข้าถึงตําแหน่งของผู้ใช้ที่ปลอดภัยและโปร่งใสมากขึ้น

ลดทอนรายละเอียดอย่างค่อยเป็นค่อยไปหากไม่ได้รับอนุญาต

โปรดออกแบบแอปให้รับมือกับสถานการณ์ต่อไปนี้ได้อย่างราบรื่น เพื่อให้ผู้ใช้ได้รับประสบการณ์การใช้งานที่ดี

  • แอปของคุณไม่มีสิทธิ์เข้าถึงข้อมูลตําแหน่ง
  • แอปของคุณไม่มีสิทธิ์เข้าถึงข้อมูลตําแหน่งเมื่อทํางานอยู่เบื้องหลัง

คุณดูวิธีรับการอัปเดตตําแหน่งใน Android โดยคํานึงถึงแนวทางปฏิบัติที่ดีที่สุด

ดูข้อมูลเพิ่มเติม