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 ได้ดังนี้
นําเข้าโปรเจ็กต์
เปิด Android Studio เลือก เปิดโปรเจ็กต์ Android Studio ที่มีอยู่" จากหน้าจอต้อนรับ แล้วเปิดไดเรกทอรีโปรเจ็กต์
หลังจากโปรเจ็กต์โหลดแล้ว คุณอาจเห็นการแจ้งเตือนว่า 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 ที่หัวข้อเรียกใช้โปรแกรมจําลอง
ทําโปรเจ็กต์เริ่มต้น
เรียกใช้แอป
- เชื่อมต่ออุปกรณ์ Android กับคอมพิวเตอร์หรือเริ่มโปรแกรมจําลอง (ตรวจสอบว่าอุปกรณ์ใช้ Android 10 ขึ้นไป)
- ในแถบเครื่องมือ ให้เลือกการกําหนดค่า
base
จากตัวเลือกแบบเลื่อนลง แล้วคลิกเรียกใช้
- โปรดสังเกตว่าแอปต่อไปนี้จะปรากฏในอุปกรณ์ของคุณ
คุณอาจสังเกตเห็นว่าไม่มีข้อมูลตําแหน่งปรากฏในหน้าจอเอาต์พุต นั่นเป็นเพราะคุณยังไม่ได้เพิ่มรหัสสถานที่ตั้ง
แนวคิด
จุดมุ่งเน้นของ 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 นี้คือวิธีรับการอัปเดตตําแหน่ง ไม่ใช่วิธีขอสิทธิ์เข้าถึงตําแหน่ง ระบบจึงเขียนโค้ดตามสิทธิ์ให้คุณอยู่แล้ว คุณสามารถข้ามกรณีนี้ได้หากเข้าใจอยู่แล้ว
ไฮไลต์สิทธิ์ต่อไปนี้ (ไม่ต้องดําเนินการใดๆ ในส่วนนี้)
- ประกาศสิทธิ์ที่คุณใช้ใน
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().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)
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
- อ่านความคิดเห็นเพื่อทําความเข้าใจแต่ละส่วนก่อน
ติดตามการเปลี่ยนแปลงตําแหน่ง
เมื่อเริ่มต้นทุกอย่างแล้ว คุณจะต้องแจ้งให้ FusedLocationProviderClient
ทราบว่าคุณต้องการรับข้อมูลอัปเดต
- ในโมดูล
base
ให้ค้นหาStep 1.5, Subscribe to location changes
ในไฟล์ForegroundOnlyLocationService.kt
- เพิ่มโค้ดต่อไปนี้หลังความคิดเห็น
// TODO: Step 1.5, Subscribe to location changes.
fusedLocationProviderClient.requestLocationUpdates(locationRequest, locationCallback, Looper.myLooper())
การโทรจาก 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
เพิ่มการรองรับ Android 10 ในส่วนนี้
แอปของคุณติดตามการเปลี่ยนแปลงตําแหน่งอยู่แล้ว คุณไม่ต้องทําอะไรมากมายเลย
ที่จริงแล้ว สิ่งที่คุณต้องทําก็คือ ระบุว่าจะให้ใช้บริการที่ทํางานอยู่เบื้องหน้าเพื่อวัตถุประสงค์ด้านตําแหน่งหรือไม่
SDK เป้าหมาย 29
- ในโมดูล
base
ให้ค้นหาTODO: Step 2.1, Target SDK 10
ในไฟล์build.gradle
- ทําการเปลี่ยนแปลงเหล่านี้
- ตั้งค่า
compileSdkVersion
เป็น29
- ตั้งค่า
buildToolsVersion
เป็น"29.0.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 เป้าหมาย
- ในโมดูล
base
ให้ค้นหาTODO: Step 2.1, Target SDK
ในไฟล์build.gradle
- ทําการเปลี่ยนแปลงเหล่านี้
compileSdkVersion
ไปยัง"android-R"
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 โดยคํานึงถึงแนวทางปฏิบัติที่ดีที่สุด
ดูข้อมูลเพิ่มเติม
- ตัวอย่างฉบับเต็มสําหรับการใช้ตําแหน่งในเบื้องหลังหากคุณมี Use Case ที่ถูกต้อง
- ขอการอัปเดตตําแหน่ง