1. Sebelum memulai
Android 10 dan 11 memberi pengguna kontrol yang lebih besar atas aplikasi mereka akses ke lokasi perangkat mereka.
Saat aplikasi yang berjalan di Android 11 meminta akses lokasi, pengguna memiliki empat opsi:
- Selalu izinkan
- Izinkan hanya saat aplikasi digunakan (di Android 10)
- Hanya satu kali (di Android 11)
- Tolak
Android 10
Android 11
Dalam codelab ini, Anda akan mempelajari cara menerima pembaruan lokasi dan cara mendukung lokasi di versi Android apa pun, terutama Android 10 dan 11. Di akhir codelab, Anda akan memiliki aplikasi yang mengikuti praktik terbaik saat ini untuk mengambil pembaruan lokasi.
Prasyarat
Yang akan Anda lakukan
- Ikuti praktik terbaik untuk lokasi di Android.
- Menangani izin akses lokasi latar depan (saat pengguna meminta aplikasi Anda mengakses lokasi perangkat saat aplikasi sedang digunakan).
- Mengubah aplikasi yang ada guna menambahkan dukungan untuk meminta akses lokasi dengan menambahkan kode untuk berlangganan dan berhenti berlangganan lokasi.
- Tambahkan dukungan ke aplikasi untuk Android 10 dan 11 dengan menambahkan logika untuk mengakses lokasi di lokasi latar depan atau saat digunakan.
Yang Anda butuhkan
- Android Studio 3.4 atau yang lebih baru untuk menjalankan kode
- Perangkat/emulator yang menjalankan pratinjau developer Android 10 dan 11
2. Memulai
Meng-clone repositori project awal
Untuk membantu Anda memulai secepat mungkin, Anda dapat mengembangkan project awal ini. Jika sudah menginstal Git, Anda cukup menjalankan perintah berikut:
git clone https://github.com/android/codelab-while-in-use-location
Jangan ragu untuk mengunjungi halaman GitHub secara langsung.
Jika tidak memiliki Git, Anda bisa mendapatkan project sebagai file ZIP:
Mengimpor project
Buka Android Studio, pilih "Open an existing Android Studio project" dari layar sambutan, dan buka direktori project.
Setelah project dimuat, Anda juga akan melihat notifikasi bahwa Git tidak melacak semua perubahan lokal. Anda dapat mengklik Abaikan. (Anda tidak akan mendorong perubahan apa pun kembali ke repositori Git.)
Di sudut kiri atas jendela project, Anda akan melihat gambar seperti gambar di bawah ini jika berada dalam tampilan Android. (Jika berada dalam tampilan Project, Anda harus memperluas project untuk melihat hal yang sama.)
Ada dua folder (base
dan complete
). Masing-masing dikenal sebagai "modul".
Perlu diketahui bahwa Android Studio mungkin memerlukan waktu beberapa detik untuk mengompilasi project di latar belakang untuk pertama kalinya. Selama peninjauan, Anda akan melihat pesan berikut di status bar di bagian bawah Android Studio:
Tunggu hingga Android Studio selesai mengindeks dan membuat project sebelum mengubah kode. Ini akan memungkinkan Android Studio menarik semua komponen yang diperlukan.
Jika Anda mendapatkan perintah yang mengatakan Reload for language changes to take effect? atau yang serupa, pilih Yes.
Memahami project awal
Anda sudah siap untuk meminta lokasi di aplikasi. Gunakan modul base
sebagai titik awal. Pada setiap langkah, tambahkan kode ke modul base
. Setelah menyelesaikan codelab ini, kode dalam modul base
seharusnya cocok dengan konten modul complete
. Modul complete
dapat digunakan untuk memeriksa pekerjaan Anda atau sebagai referensi jika Anda mengalami masalah apa pun.
Komponen utama meliputi:
MainActivity
—UI untuk pengguna yang mengizinkan aplikasi mengakses lokasi perangkatLocationService
—layanan yang berlangganan dan berhenti berlangganan perubahan lokasi, dan mempromosikan dirinya ke layanan latar depan (dengan notifikasi) jika pengguna keluar dari aktivitas aplikasi. Anda menambahkan kode lokasi di sini.Util
—Menambahkan fungsi ekstensi untuk classLocation
dan menyimpan lokasi diSharedPreferences
(lapisan data yang disederhanakan).
Penyiapan emulator
Untuk mengetahui informasi tentang cara menyiapkan Android Emulator, lihat Menjalankan di emulator.
Menjalankan project awal
Jalankan aplikasi Anda.
- Hubungkan perangkat Android ke komputer atau mulai emulator. (Pastikan perangkat menjalankan Android 10 atau yang lebih tinggi.)
- Di toolbar, pilih konfigurasi
base
dari pemilih drop-down, lalu klik Run:
- Perhatikan aplikasi berikut yang muncul di perangkat Anda:
Anda mungkin melihat bahwa tidak ada informasi lokasi yang muncul di layar output. Hal itu karena Anda belum menambahkan kode lokasi.
3. Menambahkan lokasi
Konsep
Fokus codelab ini adalah menunjukkan cara menerima pembaruan lokasi, dan pada akhirnya mendukung Android 10 dan Android 11.
Namun, sebelum memulai coding, sebaiknya Anda mempelajari dasar-dasarnya.
Jenis akses lokasi
Anda mungkin ingat empat opsi berbeda untuk akses lokasi dari awal codelab. Lihat artinya:
- Izinkan hanya saat aplikasi digunakan
- Opsi ini adalah opsi yang direkomendasikan untuk sebagian besar aplikasi. Juga dikenal sebagai "saat digunakan" atau "hanya latar depan" , opsi ini ditambahkan di Android 10 dan memungkinkan developer mengambil lokasi hanya saat aplikasi secara aktif digunakan. Aplikasi dianggap aktif jika salah satu kondisi berikut terpenuhi:
- Sebuah aktivitas terlihat.
- Layanan latar depan berjalan dengan notifikasi berkelanjutan.
- Hanya satu kali
- Ditambahkan di Android 11, fungsi ini sama dengan Izinkan hanya saat aplikasi digunakan, tetapi untuk waktu terbatas. Untuk mengetahui informasi selengkapnya, lihat Izin satu kali.
- Tolak
- Opsi ini mencegah akses ke informasi lokasi.
- Selalu izinkan
- Opsi ini memungkinkan akses lokasi sepanjang waktu, tetapi memerlukan izin tambahan untuk Android 10 dan yang lebih baru. Anda juga harus memastikan bahwa Anda memiliki kasus penggunaan yang valid dan mematuhi kebijakan lokasi. Anda tidak akan membahas opsi ini dalam codelab ini, karena ini adalah kasus penggunaan yang lebih jarang. Namun, jika Anda memiliki kasus penggunaan yang valid dan ingin memahami cara menangani lokasi sepanjang waktu dengan benar, termasuk mengakses lokasi di latar belakang, tinjau contoh LocationUpdatesBackgroundKotlin.
Layanan, layanan latar depan, dan binding
Untuk mendukung sepenuhnya pembaruan lokasi Izinkan hanya saat aplikasi digunakan, Anda perlu memperhitungkan saat pengguna keluar dari aplikasi Anda. Jika ingin terus menerima update dalam situasi tersebut, Anda harus membuat Service
latar depan dan mengaitkannya dengan Notification
.
Selain itu, jika Anda ingin menggunakan Service
yang sama untuk meminta pembaruan lokasi saat aplikasi Anda terlihat dan saat pengguna keluar dari aplikasi Anda, Anda harus mengikat/melepaskan Service
tersebut ke elemen UI.
Karena codelab ini hanya berfokus untuk mendapatkan pembaruan lokasi, Anda dapat menemukan semua kode yang diperlukan di class ForegroundOnlyLocationService.kt
. Anda dapat menjelajahi class tersebut dan MainActivity.kt
untuk melihat cara keduanya bekerja sama.
Untuk mengetahui informasi selengkapnya, lihat Ringkasan layanan dan Ringkasan layanan terikat.
Izin
Untuk menerima pembaruan lokasi dari NETWORK_PROVIDER
atau GPS_PROVIDER
, Anda harus meminta izin pengguna dengan menyatakan masing-masing izin ACCESS_COARSE_LOCATION
atau ACCESS_FINE_LOCATION
, di file manifes Android Anda. Tanpa izin ini, aplikasi Anda tidak akan dapat meminta akses ke lokasi saat runtime.
Izin tersebut mencakup kasus Satu kali saja dan Izinkan hanya saat aplikasi digunakan saat aplikasi Anda digunakan di perangkat yang menjalankan Android 10 atau yang lebih baru.
Lokasi
Aplikasi Anda dapat mengakses kumpulan layanan lokasi yang didukung melalui class dalam paket com.google.android.gms.location
.
Lihat class utama:
FusedLocationProviderClient
- Ini adalah komponen utama dari framework lokasi. Setelah dibuat, Anda akan menggunakannya untuk meminta pembaruan lokasi dan mendapatkan lokasi terakhir yang diketahui.
LocationRequest
- Ini adalah objek data yang berisi parameter kualitas layanan untuk permintaan (interval untuk pembaruan, prioritas, dan akurasi). Lokasi ini akan diteruskan ke
FusedLocationProviderClient
saat Anda meminta pembaruan lokasi. LocationCallback
- Fitur ini digunakan untuk menerima notifikasi saat lokasi perangkat telah berubah atau tidak lagi dapat ditentukan. Tindakan ini akan meneruskan
LocationResult
tempat Anda bisa mendapatkanLocation
untuk disimpan di database Anda.
Setelah memiliki gambaran dasar tentang apa yang Anda lakukan, mulailah dengan membuat kode.
4. Tambahkan fitur lokasi
Codelab ini berfokus pada opsi lokasi yang paling umum: Izinkan hanya saat aplikasi digunakan.
Untuk menerima update lokasi, aplikasi Anda harus memiliki aktivitas yang terlihat atau layanan yang berjalan di latar depan (dengan notifikasi).
Izin
Tujuan codelab ini adalah menunjukkan cara menerima pembaruan lokasi, bukan cara meminta izin akses lokasi, sehingga kode berbasis izin sudah ditulis untuk Anda. Jangan ragu untuk melewatinya jika Anda sudah memahaminya.
Berikut adalah sorotan izin (tidak diperlukan tindakan untuk bagian ini):
- Deklarasikan izin yang Anda gunakan di
AndroidManifest.xml
. - Sebelum mencoba mengakses informasi lokasi, periksa apakah pengguna telah memberikan izin kepada aplikasi Anda untuk melakukannya. Jika aplikasi Anda belum menerima izin, minta akses.
- Menangani pilihan izin pengguna. (Anda dapat melihat kode ini di
MainActivity.kt
.)
Jika Anda menelusuri TODO: Step 1.0, Review Permissions
di AndroidManifest.xml
atau MainActivity.kt
, Anda akan melihat semua kode yang ditulis untuk izin.
Untuk mengetahui informasi selengkapnya, lihat Ringkasan izin.
Sekarang, mulailah menulis beberapa kode lokasi.
Meninjau variabel utama yang diperlukan untuk pembaruan lokasi
Dalam modul base
, telusuri TODO: Step 1.1, Review variables
di
File ForegroundOnlyLocationService.kt
.
Anda tidak perlu melakukan tindakan apa pun dalam langkah ini. Anda hanya perlu meninjau blok kode berikut, beserta komentar, untuk memahami class dan variabel utama yang Anda gunakan untuk menerima update lokasi.
// 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
Meninjau inisialisasi FusedLocationProviderClient
Dalam modul base
, telusuri TODO: Step 1.2, Review the FusedLocationProviderClient
dalam file ForegroundOnlyLocationService.kt
. Kode akan terlihat seperti ini:
// TODO: Step 1.2, Review the FusedLocationProviderClient.
fusedLocationProviderClient = LocationServices.getFusedLocationProviderClient(this)
Seperti yang disebutkan dalam komentar sebelumnya, ini adalah class utama untuk mendapatkan pembaruan lokasi. Variabel sudah diinisialisasi untuk Anda, tetapi penting untuk meninjau kodenya guna memahami cara inisialisasinya. Anda akan menambahkan beberapa kode di sini nanti untuk meminta pembaruan lokasi.
Melakukan inisialisasi LocationRequest
- Dalam modul
base
, telusuriTODO: Step 1.3, Create a LocationRequest
dalam fileForegroundOnlyLocationService.kt
. - Tambahkan kode berikut setelah komentar.
Kode inisialisasi LocationRequest
menambahkan kualitas parameter layanan ekstra yang Anda perlukan untuk permintaan (interval, waktu tunggu maks, dan prioritas).
// 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
}
- Baca komentar untuk memahami cara kerjanya.
Melakukan inisialisasi LocationCallback
- Dalam modul
base
, telusuriTODO: Step 1.4, Initialize the LocationCallback
dalam fileForegroundOnlyLocationService.kt
. - Tambahkan kode berikut setelah komentar.
// 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
yang Anda buat di sini adalah callback yang akan dipanggil FusedLocationProviderClient
saat pembaruan lokasi baru tersedia.
Dalam callback, pertama-tama Anda akan mendapatkan lokasi terbaru menggunakan objek LocationResult
. Setelah itu, beri tahu Activity
tentang lokasi baru tersebut menggunakan siaran lokal (jika aktif) atau perbarui Notification
jika layanan ini berjalan sebagai Service
latar depan.
- Baca komentar untuk memahami fungsi setiap bagian.
Berlangganan perubahan lokasi
Setelah melakukan inisialisasi semuanya, Anda harus memberi tahu FusedLocationProviderClient
bahwa Anda ingin menerima update.
- Dalam modul
base
, telusuriStep 1.5, Subscribe to location changes
dalam fileForegroundOnlyLocationService.kt
. - Tambahkan kode berikut setelah komentar.
// TODO: Step 1.5, Subscribe to location changes.
fusedLocationProviderClient.requestLocationUpdates(locationRequest, locationCallback, Looper.getMainLooper())
Panggilan requestLocationUpdates()
memberi tahu FusedLocationProviderClient
bahwa Anda ingin menerima pembaruan lokasi.
Anda mungkin mengenali LocationRequest
dan LocationCallback
yang Anda tentukan sebelumnya. Parameter tersebut memberi tahu FusedLocationProviderClient
parameter kualitas layanan untuk permintaan Anda dan apa yang harus dipanggil saat memiliki update. Terakhir, objek Looper
menentukan thread untuk callback.
Anda mungkin juga melihat bahwa kode ini berada dalam pernyataan try/catch
. Metode ini memerlukan pemblokiran tersebut karena SecurityException
terjadi saat aplikasi Anda tidak memiliki izin untuk mengakses informasi lokasi.
Berhenti berlangganan perubahan lokasi
Jika aplikasi tidak lagi memerlukan akses ke informasi lokasi, Anda harus berhenti berlangganan pembaruan lokasi.
- Dalam modul
base
, telusuriTODO: Step 1.6, Unsubscribe to location changes
dalam fileForegroundOnlyLocationService.kt
. - Tambahkan kode berikut setelah komentar.
// 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.")
}
}
Metode removeLocationUpdates()
menyiapkan tugas untuk memberi tahu FusedLocationProviderClient
bahwa Anda tidak ingin lagi menerima pembaruan lokasi untuk LocationCallback
. addOnCompleteListener()
memberikan callback untuk diselesaikan dan mengeksekusi Task
.
Seperti pada langkah sebelumnya, Anda mungkin telah melihat bahwa kode ini berada dalam pernyataan try/catch
. Metode ini memerlukan pemblokiran tersebut karena SecurityException
terjadi saat aplikasi Anda tidak memiliki izin untuk mengakses informasi lokasi
Anda mungkin bertanya-tanya kapan metode yang berisi kode berlangganan/berhenti berlangganan dipanggil. Tombol dipicu di class utama saat pengguna mengetuk tombol. Jika Anda ingin melihatnya, lihat class MainActivity.kt
.
Jalankan aplikasi
Jalankan aplikasi Anda dari Android Studio dan coba tombol lokasi.
Anda akan melihat informasi lokasi di layar output. Ini adalah aplikasi yang berfungsi penuh untuk Android 9.
5. Mendukung Android 10
Di bagian ini, Anda akan menambahkan dukungan untuk Android 10.
Aplikasi Anda sudah berlangganan perubahan lokasi, sehingga tidak banyak pekerjaan yang harus dilakukan.
Bahkan, yang perlu Anda lakukan adalah menentukan bahwa layanan latar depan digunakan untuk tujuan lokasi.
SDK Target 29
- Dalam modul
base
, telusuriTODO: Step 2.1, Target Android 10 and then Android 11.
dalam filebuild.gradle
. - Buat perubahan berikut:
- Tetapkan
targetSdkVersion
ke29
.
Kode akan terlihat seperti ini:
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"
}
...
}
Setelah melakukannya, Anda akan diminta untuk menyinkronkan project. Klik Sync Now.
Setelah itu, aplikasi Anda hampir siap untuk Android 10.
Menambahkan Jenis Layanan Latar Depan
Di Android 10, Anda harus menyertakan jenis layanan latar depan jika memerlukan akses lokasi saat digunakan. Dalam kasus Anda, info ini digunakan untuk mendapatkan informasi lokasi.
Dalam modul base
, telusuri TODO: 2.2, Add foreground service type
di AndroidManifest.xml
dan tambahkan kode berikut ke elemen <service>
:
android:foregroundServiceType="location"
Kode akan terlihat seperti ini:
<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>
Selesai. Aplikasi Anda mendukung lokasi Android 10 untuk "saat digunakan" dengan mengikuti praktik terbaik untuk lokasi di Android.
Jalankan aplikasi
Jalankan aplikasi Anda dari Android Studio dan coba tombol lokasi.
Semuanya seharusnya berfungsi seperti sebelumnya, tetapi sekarang sudah berfungsi di Android 10. Jika sebelumnya Anda tidak menerima izin untuk lokasi, sekarang Anda akan melihat layar izin.
6. Mendukung Android 11
Di bagian ini, Anda menargetkan Android 11.
Kabar baik, Anda tidak perlu melakukan perubahan pada file apa pun kecuali file build.gradle
.
SDK 11 Target
- Dalam modul
base
, telusuriTODO: Step 2.1, Target SDK
dalam filebuild.gradle
. - Buat perubahan berikut:
compileSdkVersion
hingga30
targetSdkVersion
hingga30
Kode akan terlihat seperti ini:
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"
}
...
}
Setelah melakukannya, Anda akan diminta untuk menyinkronkan project. Klik Sync Now.
Setelah itu, aplikasi Anda siap untuk Android 11.
Jalankan aplikasi
Jalankan aplikasi Anda dari Android Studio dan coba klik tombol.
Semuanya seharusnya berfungsi seperti sebelumnya, tetapi sekarang sudah berfungsi di Android 11. Jika sebelumnya Anda tidak menerima izin untuk lokasi, sekarang Anda akan melihat layar izin.
7. Strategi lokasi untuk Android
Dengan memeriksa dan meminta izin akses lokasi dengan cara yang ditampilkan dalam codelab ini, aplikasi Anda dapat berhasil melacak tingkat aksesnya terkait lokasi perangkat.
Halaman ini mencantumkan beberapa praktik terbaik utama yang terkait dengan izin akses lokasi. Untuk informasi selengkapnya tentang cara menjaga keamanan data, lihat Praktik terbaik izin aplikasi.
Hanya meminta izin yang Anda perlukan
Minta izin hanya jika diperlukan. Contoh:
- Jangan meminta izin akses lokasi saat aplikasi dimulai kecuali jika benar-benar diperlukan.
- Jika aplikasi menargetkan Android 10 atau yang lebih baru dan Anda memiliki layanan latar depan, deklarasikan
foregroundServiceType
dari"location"
dalam manifes. - Jangan meminta izin akses lokasi latar belakang kecuali Anda memiliki kasus penggunaan yang valid seperti yang dijelaskan dalam Akses yang Lebih Aman dan Transparan ke Lokasi Pengguna.
Mendukung degradasi halus jika izin tidak diberikan
Untuk mempertahankan pengalaman pengguna yang baik, desain aplikasi Anda agar dapat menangani situasi berikut dengan baik:
- Aplikasi Anda tidak memiliki akses ke informasi lokasi.
- Aplikasi Anda tidak memiliki akses ke informasi lokasi saat berjalan di latar belakang.
8. Selamat
Anda telah mempelajari cara menerima pembaruan lokasi di Android, dengan selalu mengingat praktik terbaik.
Pelajari lebih lanjut
- Contoh lengkap untuk menggunakan lokasi latar belakang jika Anda memiliki kasus penggunaan yang valid
- Meminta pembaruan lokasi