Layanan latar depan menjalankan operasi yang terlihat oleh pengguna.
Layanan latar depan menampilkan notifikasi status bar, untuk membuat pengguna mengetahui bahwa aplikasi Anda sedang menjalankan tugas di latar depan dan memakai resource sistem.
Contoh aplikasi yang menggunakan layanan latar depan mencakup:
- Aplikasi pemutar musik yang memutar musik di layanan latar depan. Notifikasi mungkin menampilkan lagu yang sedang diputar.
- Aplikasi kebugaran yang merekam aktivitas lari pengguna di layanan latar depan, setelah menerima izin dari pengguna. Notifikasi mungkin menampilkan jarak yang telah ditempuh pengguna selama sesi kebugaran saat ini.
Hanya gunakan layanan latar depan jika aplikasi Anda perlu melakukan tugas yang dapat dilihat oleh pengguna, meskipun saat mereka tidak berinteraksi langsung dengan aplikasi. Jika tindakannya cukup rendah sehingga Anda ingin menggunakan notifikasi prioritas minimum, buat tugas latar belakang.
Dokumen ini menjelaskan izin yang diperlukan untuk menggunakan layanan latar depan, dan cara memulai layanan latar depan serta menghapusnya dari latar belakang. Panduan ini juga menjelaskan cara mengaitkan kasus penggunaan tertentu dengan jenis layanan latar depan, dan pembatasan akses yang berlaku saat Anda memulai layanan latar depan dari aplikasi yang berjalan di latar belakang.
Pengguna dapat menutup notifikasi secara default
Mulai Android 13 (API level 33), pengguna dapat menutup notifikasi yang terkait dengan layanan latar depan secara default. Untuk melakukannya, pengguna melakukan gestur geser pada notifikasi. Secara tradisional, notifikasi tidak ditutup kecuali jika layanan latar depan dihentikan atau dihapus dari latar depan.
Jika Anda ingin notifikasi tidak dapat ditutup oleh pengguna, teruskan
true
ke metode
setOngoing()
saat Anda membuat notifikasi menggunakan Notification.Builder
.
Layanan yang langsung menampilkan notifikasi
Jika layanan latar depan memiliki setidaknya salah satu karakteristik berikut, sistem akan segera menampilkan notifikasi terkait setelah layanan dimulai, bahkan di perangkat yang menjalankan Android 12 atau yang lebih baru:
- Layanan ini dikaitkan dengan notifikasi yang menyertakan tombol tindakan.
- Layanan memiliki
foregroundServiceType
darimediaPlayback
,mediaProjection
, atauphoneCall
. - Layanan ini menyediakan kasus penggunaan yang berkaitan dengan panggilan telepon, navigasi, atau pemutaran media, seperti yang dijelaskan dalam atribut kategori notifikasi.
- Layanan memilih tidak menggunakan perubahan perilaku dengan meneruskan
FOREGROUND_SERVICE_IMMEDIATE
kesetForegroundServiceBehavior()
saat menyiapkan notifikasi.
Di Android 13 (API level 33) atau yang lebih baru, jika pengguna menolak izin notifikasi, mereka tetap melihat notifikasi yang terkait dengan layanan latar depan di Pengelola Tugas tetapi tidak melihatnya di panel samping notifikasi.
Mendeklarasikan layanan latar depan dalam manifes
Dalam manifes aplikasi, deklarasikan setiap layanan latar depan aplikasi
dengan elemen
<service>
. Untuk setiap layanan, gunakan
atribut android:foregroundServiceType
untuk mendeklarasikan jenis pekerjaan yang dilakukan layanan.
Misalnya, jika aplikasi Anda membuat layanan latar depan yang memutar musik, Anda dapat mendeklarasikan layanan seperti ini:
<manifest xmlns:android="http://schemas.android.com/apk/res/android" ...>
<application ...>
<service
android:name=".MyMediaPlaybackService"
android:foregroundServiceType="mediaPlayback"
android:exported="false">
</service>
</application>
</manifest>
Jika beberapa jenis berlaku untuk layanan Anda, pisahkan dengan operator |
. Misalnya, layanan yang menggunakan kamera dan mikrofon
akan mendeklarasikannya seperti ini:
android:foregroundServiceType="camera|microphone"
Meminta izin layanan latar depan
Aplikasi yang menargetkan Android 9 (API level 28) atau yang lebih tinggi dan menggunakan layanan latar depan
harus meminta
FOREGROUND_SERVICE
di manifes aplikasi, seperti yang ditunjukkan dalam cuplikan kode berikut. Ini adalah izin
normal, sehingga sistem
otomatis memberikannya ke aplikasi yang meminta.
Selain itu, jika aplikasi menargetkan API level 34 atau yang lebih tinggi, aplikasi harus meminta
jenis izin yang sesuai untuk jenis pekerjaan yang akan dilakukan
layanan latar depan. Setiap jenis layanan latar depan
memiliki jenis izin yang sesuai. Misalnya, jika aplikasi meluncurkan
layanan latar depan yang menggunakan kamera, Anda harus meminta izin
FOREGROUND_SERVICE
dan FOREGROUND_SERVICE_CAMERA
. Semua ini adalah izin normal, sehingga sistem akan memberikannya
secara otomatis jika tercantum dalam manifes.
<manifest xmlns:android="http://schemas.android.com/apk/res/android" ...>
<uses-permission android:name="android.permission.FOREGROUND_SERVICE"/>
<uses-permission android:name="android.permission.FOREGROUND_SERVICE_CAMERA"/>
<application ...>
...
</application>
</manifest>
Prasyarat layanan latar depan
Mulai Android 14 (API level 34), saat Anda meluncurkan layanan latar depan,
sistem akan memeriksa prasyarat tertentu berdasarkan jenis layanan. Misalnya,
jika Anda mencoba meluncurkan layanan latar depan jenis location
, sistem akan memeriksa
untuk memastikan aplikasi Anda sudah memiliki izin ACCESS_COARSE_LOCATION
atau
ACCESS_FINE_LOCATION
. Jika tidak, sistem akan menampilkan
SecurityException
.
Oleh karena itu, Anda harus mengonfirmasi bahwa prasyarat yang diperlukan telah terpenuhi sebelum memulai layanan latar depan. Dokumentasi jenis layanan latar depan mencantumkan prasyarat yang diperlukan untuk setiap jenis layanan latar depan.
Memulai layanan latar depan
Sebelum Anda meminta sistem untuk menjalankan layanan sebagai layanan latar depan, mulai layanan itu sendiri:
Kotlin
val intent = Intent(...) // Build the intent for the service context.startForegroundService(intent)
Java
Context context = getApplicationContext(); Intent intent = new Intent(...); // Build the intent for the service context.startForegroundService(intent);
Di dalam layanan, biasanya di onStartCommand()
, Anda dapat meminta
agar layanan berjalan di latar depan. Untuk melakukannya, panggil
ServiceCompat.startForeground()
(tersedia di androidx-core 1.12 dan yang lebih tinggi). Metode ini menggunakan parameter
berikut:
- Layanan
- Bilangan bulat positif yang mengidentifikasi notifikasi secara unik di status bar
- Objek
Notification
itu sendiri - Jenis layanan latar depan yang mengidentifikasi pekerjaan yang dilakukan oleh layanan
Jenis ini mungkin merupakan subset dari jenis yang dideklarasikan dalam manifes,
bergantung pada kasus penggunaan tertentu. Kemudian, jika perlu menambahkan lebih banyak jenis layanan,
Anda dapat memanggil startForeground()
lagi.
Misalnya, aplikasi kebugaran menjalankan layanan pelacak lari yang selalu
memerlukan informasi location
, tetapi mungkin atau mungkin tidak perlu memutar media. Anda
harus mendeklarasikan location
dan mediaPlayback
dalam manifes. Jika
pengguna memulai lari dan hanya ingin lokasinya dilacak, aplikasi Anda harus memanggil
startForeground()
dan hanya meneruskan izin ACCESS_FINE_LOCATION
. Kemudian,
jika pengguna ingin mulai memutar audio, panggil startForeground()
lagi dan
teruskan kombinasi bitwise dari semua jenis layanan latar depan (dalam hal ini,
ACCESS_FINE_LOCATION|FOREGROUND_SERVICE_MEDIA_PLAYBACK
).
Berikut adalah contoh yang meluncurkan layanan latar depan kamera:
Kotlin
class MyCameraService: Service() { private fun startForeground() { // Before starting the service as foreground check that the app has the // appropriate runtime permissions. In this case, verify that the user has // granted the CAMERA permission. val cameraPermission = PermissionChecker.checkSelfPermission(this, Manifest.permission.CAMERA) if (cameraPermission != PermissionChecker.PERMISSION_GRANTED) { // Without camera permissions the service cannot run in the foreground // Consider informing user or updating your app UI if visible. stopSelf() return } try { val notification = NotificationCompat.Builder(this, "CHANNEL_ID") // Create the notification to display while the service is running .build() ServiceCompat.startForeground( /* service = */ this, /* id = */ 100, // Cannot be 0 /* notification = */ notification, /* foregroundServiceType = */ if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.R) { ServiceInfo.FOREGROUND_SERVICE_TYPE_CAMERA } else { 0 }, ) } catch (e: Exception) { if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.S && e is ForegroundServiceStartNotAllowedException) { // App not in a valid state to start foreground service // (e.g. started from bg) } // ... } } }
Java
public class MyCameraService extends Service { private void startForeground() { // Before starting the service as foreground check that the app has the // appropriate runtime permissions. In this case, verify that the user // has granted the CAMERA permission. int cameraPermission = ContextCompat.checkSelfPermission(this, Manifest.permission.CAMERA); if (cameraPermission == PackageManager.PERMISSION_DENIED) { // Without camera permissions the service cannot run in the // foreground. Consider informing user or updating your app UI if // visible. stopSelf(); return; } try { Notification notification = new NotificationCompat.Builder(this, "CHANNEL_ID") // Create the notification to display while the service // is running .build(); int type = 0; if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.R) { type = ServiceInfo.FOREGROUND_SERVICE_TYPE_CAMERA; } ServiceCompat.startForeground( /* service = */ this, /* id = */ 100, // Cannot be 0 /* notification = */ notification, /* foregroundServiceType = */ type ); } catch (Exception e) { if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.S && e instanceof ForegroundServiceStartNotAllowedException ) { // App not in a valid state to start foreground service // (e.g started from bg) } // ... } } //... }
Menghapus layanan dari latar depan
Untuk menghapus layanan dari latar depan, panggil
stopForeground()
.
Metode ini memerlukan boolean, yang menunjukkan apakah notifikasi
bilah status juga akan dihapus. Perhatikan bahwa layanan terus berjalan.
Jika Anda menghentikan layanan saat berjalan di latar depan, notifikasinya akan dihapus.
Menangani penghentian aplikasi yang dimulai pengguna yang menjalankan layanan latar depan
Mulai Android 13 (API level 33), pengguna dapat menyelesaikan alur kerja dari panel samping notifikasi untuk menghentikan aplikasi yang memiliki layanan latar depan yang sedang berjalan, terlepas dari versi SDK target aplikasi tersebut. Kemampuan ini, yang disebut Pengelola Tugas, menampilkan daftar aplikasi yang saat ini menjalankan layanan latar depan.
Daftar ini diberi label Aplikasi aktif. Di samping setiap aplikasi terdapat tombol Berhenti. Gambar 1 mengilustrasikan alur kerja Pengelola Tugas pada perangkat yang menjalankan Android 13.
Saat pengguna menekan tombol Berhenti di samping aplikasi Anda di Pengelola Tugas, tindakan berikut akan terjadi:
- Sistem akan menghapus aplikasi Anda dari memori. Oleh karena itu, seluruh aplikasi Anda akan berhenti, bukan hanya layanan latar depan yang sedang berjalan.
- Sistem akan menghapus data sebelumnya dari aktivitas aplikasi Anda.
- Semua pemutaran media akan berhenti.
- Notifikasi yang terkait dengan layanan latar depan akan dihapus.
- Aplikasi Anda tetap ada di histori.
- Tugas terjadwal dijalankan pada waktu yang dijadwalkan.
- Alarm berbunyi pada waktu atau jangka waktu yang dijadwalkan.
Untuk menguji apakah aplikasi Anda berperilaku seperti yang diharapkan selama dan setelah pengguna menghentikan aplikasi, jalankan perintah ADB berikut di jendela terminal:
adb shell cmd activity stop-app PACKAGE_NAME
Pengecualian
Sistem ini menyediakan beberapa tingkat pengecualian untuk jenis aplikasi tertentu, yang dijelaskan di bagian berikut.
Pengecualian berlaku per aplikasi, bukan per proses. Jika sistem mengecualikan satu proses dalam sebuah aplikasi, semua proses lain dalam aplikasi tersebut juga akan dikecualikan.
Pengecualian agar tidak muncul sama sekali di Pengelola Tugas
Aplikasi berikut dapat menjalankan layanan latar depan dan tidak muncul sama sekali di Pengelola Tugas:
- Aplikasi tingkat sistem
- Aplikasi keselamatan; yaitu, aplikasi yang memiliki
peran
ROLE_EMERGENCY
- Perangkat yang menggunakan mode demo
Pengecualian agar tidak dapat dihentikan oleh pengguna
Saat jenis aplikasi berikut menjalankan layanan latar depan, aplikasi tersebut akan muncul di Pengelola Tugas, tetapi tidak ada tombol Berhenti di samping nama aplikasi yang dapat diketuk pengguna:
- Aplikasi Pemilik perangkat
- Aplikasi Pemilik profil
- Aplikasi persisten
- Aplikasi yang memiliki
peran
ROLE_DIALER
Menggunakan API khusus tujuan, bukan layanan latar depan
Untuk banyak kasus penggunaan, ada API platform atau Jetpack yang dapat Anda gunakan untuk melakukan tugas yang mungkin Anda gunakan untuk layanan latar depan. Jika ada API khusus yang sesuai, Anda hampir selalu harus menggunakannya, bukan menggunakan layanan latar depan. API yang dibuat khusus sering kali memberikan kemampuan khusus kasus penggunaan tambahan yang harus Anda buat sendiri. Misalnya, Bubbles API menangani logika UI yang kompleks untuk aplikasi pesan yang perlu menerapkan fitur balon chat.
Dokumentasi untuk jenis layanan latar depan mencantumkan alternatif yang baik untuk digunakan, bukan layanan latar depan.
Batasan untuk memulai layanan latar depan dari latar belakang
Aplikasi yang menargetkan Android 12 atau yang lebih baru tidak dapat memulai layanan
latar depan saat aplikasi berjalan di latar belakang, kecuali untuk beberapa kasus
khusus. Jika aplikasi mencoba memulai
layanan latar depan saat aplikasi berjalan di latar belakang, dan layanan
latar depan tersebut bukan merupakan kasus khusus, sistem akan menampilkan
ForegroundServiceStartNotAllowedException
.
Selain itu, jika aplikasi ingin meluncurkan layanan latar depan yang memerlukan izin saat digunakan (misalnya, izin sensor tubuh, kamera, mikrofon, atau lokasi), aplikasi tidak dapat membuat layanan saat aplikasi berada di latar belakang, meskipun aplikasi termasuk dalam salah satu pengecualian dari pembatasan peluncuran latar belakang. Alasannya dijelaskan di bagian Pembatasan memulai layanan latar depan yang memerlukan izin saat digunakan.
Pengecualian dari batasan memulai di latar belakang
Dalam situasi berikut, aplikasi Anda dapat memulai layanan latar depan bahkan saat aplikasi berjalan di latar belakang:
- Aplikasi Anda bertransisi dari status yang terlihat oleh pengguna, seperti aktivitas.
- Aplikasi Anda dapat memulai aktivitas dari latar belakang, kecuali jika aplikasi memiliki aktivitas di data sebelumnya pada tugas yang ada.
Aplikasi Anda menerima pesan prioritas tinggi menggunakan Firebase Cloud Messaging.
Pengguna menjalankan tindakan di elemen UI yang terkait dengan aplikasi Anda. Misalnya, pengguna mungkin berinteraksi dengan balon, notifikasi, widget, atau aktivitas.
Aplikasi Anda memanggil alarm yang tepat untuk menyelesaikan tindakan yang diminta pengguna.
Aplikasi Anda adalah metode input perangkat saat ini.
Aplikasi Anda menerima peristiwa yang terkait dengan pembatasan wilayah atau transisi pengenalan aktivitas.
Setelah perangkat dimulai ulang dan menerima tindakan intent
ACTION_BOOT_COMPLETED
,ACTION_LOCKED_BOOT_COMPLETED
, atauACTION_MY_PACKAGE_REPLACED
di penerima siaran.Aplikasi Anda menerima tindakan intent
ACTION_TIMEZONE_CHANGED
,ACTION_TIME_CHANGED
, atauACTION_LOCALE_CHANGED
di penerima siaran.Aplikasi Anda menerima peristiwa
ACTION_TRANSACTION_DETECTED
dariNfcService
.Aplikasi dengan peran atau izin sistem tertentu, seperti pemilik perangkat dan pemilik profil.
Aplikasi Anda menggunakan Pengelola Perangkat Pendamping dan mendeklarasikan izin
REQUEST_COMPANION_START_FOREGROUND_SERVICES_FROM_BACKGROUND
atau izinREQUEST_COMPANION_RUN_IN_BACKGROUND
. Jika memungkinkan, gunakanREQUEST_COMPANION_START_FOREGROUND_SERVICES_FROM_BACKGROUND
.Pengguna menonaktifkan pengoptimalan baterai untuk aplikasi Anda.
Aplikasi Anda memiliki izin
SYSTEM_ALERT_WINDOW
. Catatan: Jika menargetkan Android 15 atau yang lebih tinggi, aplikasi Anda harus memiliki izinSYSTEM_ALERT_WINDOW
dan saat ini aplikasi harus memiliki jendela overlay yang terlihat.
Pembatasan untuk memulai layanan latar depan yang memerlukan izin saat penggunaan
Di Android 14 (API level 34) atau yang lebih baru, ada situasi khusus yang harus diketahui jika Anda memulai layanan latar depan yang memerlukan izin saat digunakan.
Jika aplikasi Anda menargetkan Android 14 atau yang lebih tinggi, sistem operasi
akan memeriksa saat Anda membuat layanan latar depan untuk memastikan aplikasi Anda memiliki semua
izin yang sesuai untuk jenis layanan tersebut. Misalnya, saat Anda membuat
layanan latar depan dari jenis
microphone, sistem
operasi akan memverifikasi bahwa aplikasi Anda saat ini memiliki
izin
RECORD_AUDIO
. Jika Anda tidak memiliki izin tersebut, sistem akan menampilkan
SecurityException
.
Untuk izin saat digunakan, hal ini dapat menyebabkan potensi masalah. Jika memiliki
izin saat digunakan, aplikasi hanya memiliki izin tersebut saat berada di
latar depan. Artinya, jika aplikasi Anda berada di latar belakang, dan mencoba membuat
layanan latar depan dari jenis kamera, lokasi, atau mikrofon, sistem akan melihat
bahwa aplikasi Anda saat ini tidak memiliki izin yang diperlukan, dan menampilkan
SecurityException
.
Demikian pula, jika aplikasi Anda berada di latar belakang dan membuat
layanan kesehatan yang memerlukan izin BODY_SENSORS
, aplikasi
saat ini tidak memiliki izin tersebut, dan sistem akan menampilkan pengecualian.
(Hal ini tidak berlaku jika layanan kesehatan memerlukan izin yang berbeda,
seperti ACTIVITY_RECOGNITION
.) Memanggil
PermissionChecker.checkSelfPermission()
tidak mencegah masalah ini. Jika aplikasi Anda memiliki izin saat digunakan, dan
memanggil checkSelfPermission()
untuk memeriksa apakah aplikasi memiliki izin tersebut, metode
akan menampilkan PERMISSION_GRANTED
meskipun aplikasi berada di latar belakang. Saat
metode menampilkan PERMISSION_GRANTED
, metode tersebut akan menampilkan "aplikasi Anda memiliki izin ini
saat aplikasi sedang digunakan".
Oleh karena itu, jika layanan latar depan memerlukan izin saat digunakan, Anda
harus memanggil Context.startForegroundService()
atau Context.bindService()
saat
aplikasi memiliki aktivitas yang terlihat, kecuali jika layanan termasuk dalam salah satu
pengecualian yang ditentukan.
Pengecualian dari batasan pada izin saat penggunaan
Dalam beberapa situasi, meskipun layanan latar depan dimulai saat aplikasi berjalan di latar belakang, layanan tersebut masih dapat mengakses informasi lokasi, kamera, dan mikrofon saat aplikasi berjalan di latar depan ("saat-digunakan").
Dalam situasi yang sama ini, jika layanan mendeklarasikan
jenis layanan latar depan location
dan dimulai oleh aplikasi yang
memiliki
izin
ACCESS_BACKGROUND_LOCATION
, layanan ini dapat mengakses informasi lokasi sepanjang waktu, bahkan saat
aplikasi berjalan di latar belakang.
Daftar berikut berisi situasi tersebut:
- Komponen sistem memulai layanan.
- Layanan dimulai dengan berinteraksi dengan widget aplikasi.
- Layanan dimulai dengan berinteraksi dengan notifikasi.
- Layanan dimulai sebagai
PendingIntent
yang dikirim dari aplikasi lain yang terlihat. - Layanan dimulai oleh aplikasi yang merupakan pengontrol kebijakan perangkat yang berjalan dalam mode pemilik perangkat.
- Layanan dimulai oleh aplikasi yang menyediakan
VoiceInteractionService
. - Layanan dimulai oleh aplikasi yang memiliki
izin hak istimewa
START_ACTIVITIES_FROM_BACKGROUND
.
Menentukan layanan yang terpengaruh di aplikasi Anda
Saat menguji aplikasi Anda, mulai layanan latar depannya. Jika layanan yang dimulai memiliki akses terbatas ke lokasi, mikrofon, dan kamera, pesan berikut akan muncul di Logcat:
Foreground service started from background can not have \ location/camera/microphone access: service SERVICE_NAME