Mulai Android API level 26, notifikasi persisten diperlukan untuk layanan latar depan. Persyaratan ini dimaksudkan untuk mencegah Anda menyembunyikan layanan yang mungkin menempatkan permintaan berlebihan pada resource sistem, termasuk khusus baterai. Persyaratan ini menimbulkan potensi masalah: Jika aplikasi dengan beberapa layanan latar depan tidak mengelola notifikasi dengan cermat sehingga dibagikan ke semua layanan, akan ada beberapa notifikasi persisten yang tidak dapat ditutup, yang menyebabkan kekacauan yang tidak diinginkan dalam daftar notifikasi aktif.
Masalah ini akan menjadi lebih menantang saat Anda menggunakan SDK seperti Navigation SDK, yang menjalankan layanan latar depan secara independen dari aplikasi, yang dapat memiliki
notifikasi persisten yang independen, sehingga sulit untuk digabungkan.
Untuk mengatasi masalah ini, Navigation SDK v1.11 memperkenalkan API sederhana untuk
membantu mengelola notifikasi persisten di seluruh aplikasi, termasuk dalam SDK.
Komponen
Pengelola layanan latar depan menyediakan wrapper di sekitar class layanan latar depan Android dan class notifikasi persisten. Fungsi utama wrapper ini adalah menerapkan penggunaan kembali ID Notifikasi sehingga notifikasi dibagikan di semua layanan latar depan menggunakan pengelola.
NavigationAPI berisi metode statis untuk menginisialisasi dan mendapatkan singleton ForegroundServiceManager
. Single ini hanya dapat diinisialisasi satu kali selama masa aktif Navigation SDK. Oleh karena itu, jika menggunakan salah satu panggilan inisialisasi (initForegroundServiceManagerMessageAndIntent()
atau initForegroundServiceManagerProvider()
), Anda harus mengapitnya dengan blok try/catch jika jalur tersebut dimasukkan kembali. Untuk mencegah
masalah inkompatibilitas, Navigation SDK akan menampilkan pengecualian runtime jika Anda
memanggil salah satu metode lebih dari satu kali, kecuali jika Anda menghapus semua referensi ke ForegroundServiceManager
terlebih dahulu dan memanggil clearForegroundServiceManager()
sebelum setiap panggilan berikutnya. Di Navigation SDK v2.0, pengecualian yang diperiksa ditambahkan ke API untuk tujuan ini.
Keempat parameter initForegroundServiceManagerMessageAndIntent()
adalah application
,
notificationId
, defaultMessage
, dan resumeIntent
. Jika tiga parameter
terakhir adalah null, maka notifikasi tersebut adalah notifikasi
Navigation SDK standar. Anda masih dapat menyembunyikan layanan latar depan lainnya di aplikasi
di balik notifikasi ini. Parameter notificationId
menentukan
ID notifikasi yang harus digunakan untuk notifikasi. Jika null, maka nilai arbitrer akan digunakan. Anda dapat menetapkannya secara eksplisit untuk mengatasi konflik dengan notifikasi lain, seperti notifikasi dari SDK lain. defaultMessage
adalah string yang ditampilkan saat sistem tidak melakukan navigasi. resumeIntent
adalah intent yang dipicu saat notifikasi diklik. Jika resumeIntent
bernilai null, klik pada notifikasi akan diabaikan.
Tiga parameter initForegroundServiceManagerProvider()
adalah application
,
notificationId
, dan notificationProvider
. Jika dua parameter terakhir
adalah null, maka notifikasi tersebut adalah notifikasi Navigation SDK
standar. Parameter notificationId
menentukan
ID notifikasi yang harus digunakan untuk notifikasi. Jika null, maka nilai arbitrer akan digunakan. Anda dapat menetapkannya secara eksplisit untuk mengatasi konflik dengan notifikasi lain, seperti notifikasi dari SDK lain. Jika notificationProvider
disetel, penyedia akan selalu bertanggung jawab untuk
membuat notifikasi yang akan dirender.
Metode getForegroundServiceManager()
Navigation SDK menampilkan
singleton pengelola layanan latar depan. Jika Anda belum membuatnya, maka itu setara dengan memanggil initForegroundServiceManagerMessageAndIntent()
dengan parameter null untuk notificationId
, defaultMessage
, dan resumeIntent
.
ForegroundServiceManager
memiliki tiga metode sederhana. Dua fungsi yang pertama adalah untuk
memindahkan layanan ke dalam dan ke luar latar depan, dan biasanya dipanggil dari
dalam layanan yang telah dibuat. Penggunaan metode ini akan memastikan bahwa
layanan dikaitkan dengan notifikasi persisten yang dibagikan. Metode
akhir, updateNotification()
, menandai pengelola bahwa notifikasi telah
berubah, dan harus dirender ulang.
Jika Anda ingin kontrol penuh atas konten notifikasi persisten yang dibagikan, API baru menyediakan antarmuka NotificationContentProvider
untuk menentukan penyedia notifikasi yang berisi satu metode untuk mendapatkan notifikasi dengan konten saat ini. Library ini juga menyediakan class dasar, yang dapat Anda
gunakan secara opsional untuk membantu menentukan penyedia. Salah satu tujuan utama class dasar
adalah menyediakan cara yang mudah untuk memanggil updateNotification()
tanpa perlu
mengakses ForegroundServiceManager
. Metode helper ini dapat berguna jika Anda
menggunakan instance penyedia notifikasi untuk menerima pesan notifikasi
baru, dalam hal ini Anda dapat memanggil metode internal ini secara langsung untuk merender
pesan dalam notifikasi.
Skenario penggunaan
Bagian ini menjelaskan skenario penggunaan untuk menggunakan notifikasi persisten bersama.
- Menyembunyikan notifikasi persisten dari layanan latar depan aplikasi lainnya
- Skenario termudah adalah mempertahankan perilaku saat ini, dan hanya menggunakan
notifikasi persisten untuk merender informasi Navigation SDK. Layanan lain
dapat disembunyikan di balik notifikasi ini dengan menggunakan
metode
startForeground()
danstopForeground()
pengelola layanan latar depan. - Menyembunyikan notifikasi persisten dari layanan latar depan aplikasi lainnya, tetapi menetapkan teks default yang ditampilkan saat tidak menavigasi
- Skenario termudah kedua adalah mempertahankan perilaku saat ini, dan hanya menggunakan
notifikasi persisten untuk merender informasi Navigation SDK, kecuali saat
sistem tidak bernavigasi. Saat sistem tidak melakukan navigasi, string
yang diberikan ke
initForegroundServiceManagerMessageAndIntent()
akan ditampilkan, bukan string Navigation SDK default yang menyebutkan "Google Maps". Panggilan ini juga bisa digunakan untuk menetapkan intent resume yang akan dipicu saat notifikasi diklik. - Mengontrol sepenuhnya rendering notifikasi persisten
- Skenario terakhir mengharuskan penentuan dan pembuatan penyedia notifikasi serta meneruskannya ke ForegroundServiceManager melalui
initForegroundServiceManagerProvider()
. Opsi ini memberi Anda kontrol penuh atas apa yang dirender dalam notifikasi, tetapi juga memutuskan sambungan informasi notifikasi Navigation SDK dari notifikasi, sehingga menghapus petunjuk belokan demi belokan berguna yang ditampilkan dalam notifikasi. Google belum menyediakan cara sederhana untuk mengambil informasi ini dan memasukkannya ke dalam notifikasi.
Contoh penyedia notifikasi
Contoh kode berikut menunjukkan cara membuat dan menampilkan notifikasi menggunakan penyedia konten notifikasi sederhana.
public class NotificationContentProviderImpl
extends NotificationContentProviderBase
implements NotificationContentProvider {
private String channelId;
private Context context;
private String message;
/** Constructor */
public NotificationContentProviderImpl(Application application) {
super(application);
message = "-- uninitialized --";
channelId = null;
this.context = application;
}
/**
* Sets message to display in the notification. Calls updateNotification
* to display the message immediately.
*
* @param msg The message to display in the notification.
*/
public void setMessage(String msg) {
message = msg;
updateNotification();
}
/**
* Returns the notification as it should be rendered.
*/
@Override
public Notification getNotification() {
Notification notification;
if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.O) {
Spanned styledText = Html.fromHtml(message, FROM_HTML_MODE_LEGACY);
String channelId = getChannelId(context);
notification =
new Notification.Builder(context, channelId)
.setContentTitle("Notifications Demo")
.setStyle(new Notification.BigTextStyle()
.bigText(styledText))
.setSmallIcon(R.drawable.ic_navigation_white_24dp)
.setTicker("ticker text")
.build();
} else {
notification = new Notification.Builder(context)
.setContentTitle("Notification Demo")
.setContentText("testing non-O text")
.build();
}
return notification;
}
// Helper to set up a channel ID.
private String getChannelId(Context context) {
if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.O) {
if (channelId == null) {
NotificationManager notificationManager =
(NotificationManager) context.getSystemService(Context.NOTIFICATION_SERVICE);
NotificationChannel channel = new NotificationChannel(
"default", "navigation", NotificationManager.IMPORTANCE_DEFAULT);
channel.setDescription("For navigation persistent notification.");
notificationManager.createNotificationChannel(channel);
channelId = channel.getId();
}
return channelId;
} else {
return "";
}
}
}
Peringatan dan rencana mendatang
- Pastikan untuk memanggil
initForegroundServiceManagerMessageAndIntent()
atauinitForegroundServiceManagerProvider()
lebih awal sehingga skenario penggunaan yang diharapkan dapat ditentukan dengan baik. Anda harus memanggil metode ini sebelum membuat Navigator baru. - Pastikan untuk menangkap pengecualian dari panggilan ke
initForegroundServiceManagerMessageAndIntent()
atauinitForegroundServiceManagerProvider()
jika jalur kode dimasukkan lebih dari sekali. Di Navigation SDK v2.0, memanggil metode ini beberapa kali akan menampilkan pengecualian yang dicentang, bukan pengecualian runtime. - Google mungkin masih memiliki pekerjaan untuk mendapatkan penataan gaya yang konsisten selama masa aktif notifikasi yang cocok dengan gaya header.
- Saat menentukan penyedia notifikasi, Anda dapat mengontrol perilaku peringatan dini dengan prioritas.
- Google belum menyediakan cara sederhana untuk mengambil informasi belokan demi belokan yang mungkin dimasukkan oleh penyedia notifikasi ke dalam notifikasi.