Mulai Android API level 26, notifikasi persisten diperlukan untuk layanan latar depan. Persyaratan ini dimaksudkan untuk mencegah Anda menyembunyikan layanan yang mungkin memberikan permintaan berlebihan pada resource sistem, termasuk baterai secara khusus. Persyaratan ini menimbulkan potensi masalah: Jika aplikasi dengan beberapa layanan latar depan tidak mengelola notifikasi dengan cermat sehingga dibagikan ke semua layanan, mungkin ada beberapa notifikasi persisten yang tidak dapat ditutup, yang menyebabkan kekacauan yang tidak diinginkan dalam daftar aktif notifikasi.
Masalah ini menjadi lebih menantang saat Anda menggunakan SDK seperti Navigation
SDK, yang menjalankan layanan latar depan secara independen dari aplikasi yang memiliki
notifikasi persisten independennya sendiri, 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 untuk menerapkan penggunaan kembali ID Notifikasi sehingga notifikasi dibagikan di semua layanan latar depan yang menggunakan pengelola.
Navigation SDK berisi metode statis untuk melakukan inisialisasi dan mendapatkan
singleton ForegroundServiceManager
. Singleton ini hanya dapat diinisialisasi
satu kali selama masa aktif Navigation SDK. Oleh karena itu, jika Anda menggunakan salah satu
panggilan inisialisasi (initForegroundServiceManagerMessageAndIntent()
atau
initForegroundServiceManagerProvider()
), Anda harus mengapitnya
dengan blok try-catch jika jalur tersebut dimasukkan kembali. Navigation SDK
akan menampilkan pengecualian runtime jika Anda memanggil salah satu metode lebih dari sekali, kecuali jika Anda
menghapus semua referensi ke ForegroundServiceManager
terlebih dahulu dan memanggil
clearForegroundServiceManager()
sebelum setiap panggilan berikutnya.
Empat parameter initForegroundServiceManagerMessageAndIntent()
adalah
application
, notificationId
, defaultMessage
, dan resumeIntent
. Jika
tiga parameter terakhir bernilai null, notifikasi tersebut adalah notifikasi
Navigation SDK standar. Anda masih dapat menyembunyikan layanan latar depan
lain di aplikasi di balik notifikasi ini. Parameter notificationId
menentukan ID notifikasi yang harus digunakan untuk notifikasi. Jika
null, nilai arbitrer akan digunakan. Anda dapat menetapkannya secara eksplisit untuk mengatasi
konflik dengan notifikasi lain, seperti yang berasal dari SDK lain. defaultMessage
adalah string yang ditampilkan saat sistem tidak
menavigasi. resumeIntent
adalah intent yang diaktifkan saat notifikasi
diklik. Jika resumeIntent
adalah null, klik pada notifikasi
akan diabaikan.
Tiga parameter initForegroundServiceManagerProvider()
adalah
application
, notificationId
, dan notificationProvider
. Jika dua parameter
akhir bernilai null, notifikasi tersebut adalah notifikasi Navigation SDK
standar. Parameter notificationId
menentukan ID notifikasi yang
harus digunakan untuk notifikasi. Jika null, nilai arbitrer akan
digunakan. Anda dapat menetapkannya secara eksplisit untuk mengatasi konflik dengan notifikasi
lain, seperti yang berasal dari SDK lain. Jika notificationProvider
ditetapkan, penyedia selalu bertanggung jawab untuk
membuat notifikasi yang akan dirender.
Metode getForegroundServiceManager()
Navigation SDK menampilkan
singleton pengelola layanan latar depan. Jika Anda belum membuatnya, hal ini setara dengan memanggil initForegroundServiceManagerMessageAndIntent()
dengan parameter null untuk notificationId
, defaultMessage
, dan
resumeIntent
.
ForegroundServiceManager
memiliki tiga metode sederhana. Dua yang pertama adalah untuk
memindahkan layanan ke dalam dan keluar dari latar depan, dan biasanya dipanggil dari
dalam layanan yang telah dibuat. Penggunaan metode ini memastikan bahwa
layanan dikaitkan dengan notifikasi persisten bersama. Metode
akhir, updateNotification()
, menandai pengelola bahwa notifikasi telah
berubah, dan harus dirender ulang.
Jika Anda memerlukan kontrol penuh atas notifikasi persisten bersama, API akan menyediakan antarmuka NotificationContentProvider
untuk menentukan
penyedia notifikasi, yang berisi satu metode untuk mendapatkan notifikasi
dengan konten saat ini. Class ini juga menyediakan class dasar, yang dapat Anda
gunakan secara opsional untuk membantu menentukan penyedia. Salah satu tujuan utama
class dasar adalah menyediakan cara untuk memanggil updateNotification()
tanpa
perlu mengakses ForegroundServiceManager
. Jika menggunakan instance
penyedia notifikasi untuk menerima pesan notifikasi baru, 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 layanan latar depan aplikasi lain
- Skenario termudah adalah mempertahankan perilaku saat ini, dan hanya menggunakan
notifikasi persisten untuk merender informasi Navigation SDK. Layanan lain
dapat bersembunyi di balik notifikasi ini dengan menggunakan metode pengelola layanan latar depan
startForeground()
danstopForeground()
. - Menyembunyikan notifikasi persisten layanan latar depan aplikasi lain, 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 menavigasi. Saat sistem tidak menavigasi, string yang diberikan ke
initForegroundServiceManagerMessageAndIntent()
akan ditampilkan, bukan string Navigation SDK default yang menyebutkan "Google Maps". Anda juga dapat menggunakan panggilan ini untuk menetapkan intent lanjutkan yang diaktifkan saat notifikasi diklik. - Mengontrol sepenuhnya rendering notifikasi persisten
- Skenario akhir memerlukan penentuan dan pembuatan penyedia notifikasi
serta meneruskannya ke
ForegroundServiceManager
menggunakaninitForegroundServiceManagerProvider()
. Opsi ini memberi Anda kontrol penuh atas apa yang dirender dalam notifikasi, tetapi juga memutuskan informasi notifikasi Navigation SDK dari notifikasi, sehingga menghapus perintah belokan demi belokan yang berguna yang ditampilkan dalam notifikasi. Google tidak menyediakan cara sederhana untuk mengambil informasi ini dan menyisipkannya 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 "";
}
}
}
Setelah membuat NotificationContentProviderImpl
, Anda menghubungkan
Navigation SDK ke NotificationContentProviderImpl
menggunakan kode berikut:
ForegroundServiceManager f = NavigationApi.getForegroundServiceManager(getApplication());
mNotification = new NotificationContentProviderImpl(getApplication());
NavigationApi.clearForegroundServiceManager();
NavigationApi.initForegroundServiceManagerProvider(getApplication(), null, mNotification);
Peringatan dan rencana mendatang
- Pastikan untuk memanggil
initForegroundServiceManagerMessageAndIntent()
atauinitForegroundServiceManagerProvider()
lebih awal sehingga skenario penggunaan yang diharapkan 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 diperiksa, bukan pengecualian runtime. - Google mungkin masih perlu melakukan pekerjaan untuk mendapatkan gaya visual yang konsisten selama masa aktif notifikasi yang cocok dengan gaya visual header.
- Saat menentukan penyedia notifikasi, Anda dapat mengontrol perilaku pemberitahuan dengan prioritas.
- Google tidak menyediakan cara sederhana untuk mengambil informasi rute per belokan yang mungkin disisipkan oleh penyedia notifikasi ke dalam notifikasi.