Notifikasi adalah cara terbaik untuk melibatkan pengguna agar kembali ke aplikasi Anda atau membuat mereka memperhatikan sesuatu saat berada di aplikasi.
Ada dua jenis notifikasi:
- Push Notification
- Local Notification
Seperti yang disarankan oleh judul artikel ini, kami tidak akan berfokus pada pemberitahuan Push (juga karena itu adalah sesuatu yang telah banyak didokumentasikan). Sebagai gantinya, kami hanya akan fokus pada notifikasi lokal. Perbedaan antara keduanya berasal dari satu poin utama:
Notifikasi lokal berasal dari aplikasi itu sendiri, berbeda dengan notifikasi Push yang dipicu dari server jauh.
Untuk tujuan artikel ini, kami akan menggunakan proyek vanilla yang dibuat saat Anda membuka aplikasi Flutter baru (yang memiliki penghitung), dikurangi semua bit penghitung terkait.
Persiapan
Untuk mengizinkan aplikasi kita menggunakan notifikasi lokal, kita perlu menambahkan paket flutter_local_notifications ke proyek kita. Tambahkan yang berikut ini ke file pubspec.yaml Anda, di bawah dependensi:
dependencies:
flutter:
sdk: flutter
flutter_local_notifications: ^5.0.0+1
Kemudian jalankan perintah flutter pub get
.
Karena paket pemberitahuan lokal perlu diinisialisasi, kami akan membuat kelas layanan untuk menangani logika ini untuk seluruh aplikasi kami. Kelas ini juga akan mengekspos metode untuk membuat/mengirim/membatalkan notifikasi. Buat file dart baru bernama notification_service.dart dengan kode berikut:
import 'package:flutter_local_notifications/flutter_local_notifications.dart';
class NotificationService {
static final NotificationService _notificationService =
NotificationService._internal();
factory NotificationService() {
return _notificationService;
}
NotificationService._internal();
}
Kode di atas diterjemahkan menjadi objek Singleton di dart. Pastikan untuk mengimpor paket pemberitahuan lokal di bagian atas file ini.
Integrasi
Karena fakta bahwa Flutter adalah kerangka kerja lintas platform, setiap paket yang dibuat untuknya perlu mendukung perangkat iOS dan Android. Karena notifikasi ditangani dengan sangat berbeda antara iOS dan Android, ada beberapa kalibrasi yang perlu dilakukan saat menggunakan paket notifikasi lokal.
Pertama kita perlu membuat instance untuk FlutterLocalNotificationPlugin . Kami akan menggunakan objek ini untuk menginisialisasi pengaturan untuk Android dan iOS dan juga untuk tujuan pemberitahuan lainnya.
final flutterLocalNotificationsPlugin = FlutterLocalNotificationsPlugin();
Kita sekarang perlu menginisialisasi plugin pemberitahuan lokal dengan pengaturan khusus untuk Android dan iOS. Untuk melakukannya, kita perlu membuat objek InitializationSettings . Ia menerima argumen untuk sistem operasi berikut: Android, iOS dan MacOS.
Kami tidak akan membahas MacOS di sini karena mirip dengan mengonfigurasi iOS
Android
Di sini, ini cukup sederhana karena hanya ada satu argumen wajib yang harus dilewati, defaultIcon (String). Ini mewakili ikon yang akan ditampilkan dalam notifikasi. Di sini Anda harus memberikan nama ikon yang ingin Anda gunakan. Anda harus menempatkan ikon ini di dalam direktori yang dapat digambar. Path lengkapnya adalah:
YOUR_APPLICATION_NAME\android\app\src\main\res\drawable\YOUR_APP_ICON.png

Tidak perlu meminta izin apa pun.
iOS
Seperti kebanyakan subjek yang terkait dengan iOS, hal-hal di sini menjadi sedikit lebih rumit. Karena sifat cara pemberitahuan ditangani di antara versi sistem operasi yang berbeda, ada kebutuhan di sini untuk beberapa konfigurasi tambahan.
Di dalam file AppDelegate
Anda perlu menambahkan baris kode berikut:
- (BOOL)application:(UIApplication *)application
didFinishLaunchingWithOptions:(NSDictionary<UIApplicationLaunchOptionsKey, id> *)launchOptions {
if (@available(iOS 10.0, *)) {
[UNUserNotificationCenter currentNotificationCenter].delegate = (id<UNUserNotificationCenterDelegate>) self;
}
}
Diperlukan untuk meminta izin dari pengguna untuk berbagai masalah yang terkait dengan notifikasi. Oleh karena itu, objek penginisialisasi untuk iOS memiliki argumen berikut:
- permintaanPeringatanIzin
- permintaanLencanaIzin
- permintaanSoundPermission
Masing-masing dari mereka cukup jelas tetapi berhubungan dengan aspek yang berbeda dalam pemberitahuan. Untuk menyesuaikan dengan izin ini juga nilai default yang dapat Anda atur untuk masing-masingnya.
- defaultPresentAlert
- defaultPresentLencana
- defaultPresentSound
Opsi ini ada, karena inisialisasi plugin pemberitahuan lokal dapat menyebabkan sistem operasi menampilkan dialog izin kepada pengguna pada saat Anda tidak ingin mereka muncul. Jika Anda tidak menginginkan perilaku ini, Anda dapat menyetel semua nilai ini ke false.
Satu lagi peringatan di iOS berkaitan dengan perbedaan perilaku antara pemberitahuan yang disajikan kepada pengguna saat aplikasi Anda berada di latar depan atau saat berada di latar belakang. Di luar kotak, sistem operasi tidak akan menampilkan pemberitahuan kepada pengguna jika aplikasi berada di latar depan. Plugin itu sendiri akan menangani tampilan notifikasi saat aplikasi berada di latar depan, tetapi di bawah iOS10, ada kebutuhan untuk memberikan metode panggilan balik onDidReceiveLocalNotification yang akan menangani interaksi pengguna dengan notifikasi.
Setelah mengonfigurasi inisialisasi platform tertentu, saatnya untuk menggabungkan semua logika ini ke dalam metode di layanan notifikasi kami. Pendekatan terbaik kami di sini adalah membuat metode init yang akan dipanggil dari file main.dart kami saat aplikasi pertama kali diluncurkan.
void init() {
final AndroidInitializationSettings initializationSettingsAndroid =
AndroidInitializationSettings('app_icon');
final IOSInitializationSettings initializationSettingsIOS =
IOSInitializationSettings(
requestSoundPermission: false,
requestBadgePermission: false,
requestAlertPermission: false,
onDidReceiveLocalNotification: onDidReceiveLocalNotification,
);
final InitializationSettings initializationSettings =
InitializationSettings(
android: initializationSettingsAndroid,
iOS: initializationSettingsIOS,
macOS: null);
}
Perhatikan bahwa setelah membuat instance untuk pengaturan inisialisasi khusus platform, kita juga perlu membuat objek InitializationSettings yang kita lewati di objek pengaturan inisialisasi khusus platform kita.
Langkah terakhir kita di sini adalah memanggil metode inisialisasi pada objek FlutterLocalNotificationsPlugin.
Selain pengaturan inisialisasi dari atas, ia juga memiliki argumen lain yang disebut onSelectNotification . Argumen ini mewakili panggilan balik yang akan dipanggil setelah notifikasi diketuk dan ini adalah argumen opsional. Callback ini memiliki satu argumen yang disebut payload yang akan menampung data apa pun yang dilewatkan melalui notifikasi.
Future<void> init() async {
final AndroidInitializationSettings initializationSettingsAndroid =
AndroidInitializationSettings('app_icon');
final IOSInitializationSettings initializationSettingsIOS =
IOSInitializationSettings(
requestSoundPermission: false,
requestBadgePermission: false,
requestAlertPermission: false,
onDidReceiveLocalNotification: onDidReceiveLocalNotification,
);
final InitializationSettings initializationSettings =
InitializationSettings(
android: initializationSettingsAndroid,
iOS: initializationSettingsIOS,
macOS: null);
await flutterLocalNotificationsPlugin.initialize(initializationSettings,
onSelectNotification: selectNotification);
}
Future selectNotification(String payload) async {
//Handle notification tapped logic here
}
Dalam file main.dart kita, kita akan memanggil metode init seperti ini:
Future<void> main() async {
WidgetsFlutterBinding.ensureInitialized();
await NotificationService().init(); // <----
runApp(MyApp());
}
Kasus Penggunaan - Menampilkan Pemberitahuan
Untuk menampilkan notifikasi, Anda perlu membuat instance detail notifikasi yang sesuai (Android/iOS). Setiap platform memiliki argumen spesifiknya sendiri yang perlu diteruskan.
const AndroidNotificationDetails androidPlatformChannelSpecifics =
AndroidNotificationDetails(
channelId: String, //Required for Android 8.0 or after
channelName: String, //Required for Android 8.0 or after
channelDescription: String, //Required for Android 8.0 or after
importance: Importance,
priority: Priority
);
Contoh di atas hanya menunjukkan beberapa argumen yang dapat Anda teruskan ke AndroidNotificationDetails . Daftarnya jauh lebih panjang dan Anda dapat memeriksanya di sini.
const IOSNotificationDetails iOSPlatformChannelSpecifics =
IOSNotificationDetails(
presentAlert: bool?, // Present an alert when the notification is displayed and the application is in the foreground (only from iOS 10 onwards)
presentBadge: bool?, // Present the badge number when the notification is displayed and the application is in the foreground (only from iOS 10 onwards)
presentSound: bool?, // Play a sound when the notification is displayed and the application is in the foreground (only from iOS 10 onwards)
sound: String?, // Specifics the file path to play (only from iOS 10 onwards)
badgeNumber: int?, // The application's icon badge number
attachments: List<IOSNotificationAttachment>?, (only from iOS 10 onwards)
subtitle: String?, //Secondary description (only from iOS 10 onwards)
threadIdentifier: String? (only from iOS 10 onwards)
);
Selanjutnya, kami akan membuat objek NotificationDetails dan meneruskannya ke objek detail notifikasi khusus platform kami.
const NotificationDetails platformChannelSpecifics =
NotificationDetails(android: androidPlatformChannelSpecifics);
// OR
const NotificationDetails platformChannelSpecifics =
NotificationDetails(iOS: iOSPlatformChannelSpecifics);
Kemudian kita perlu memanggil metode show dari FlutterLocalNotificationPlugin.
await flutterLocalNotificationsPlugin.show(
int id,
String? title,
String? body,
NotificationDetails? notificationDetails,
String? payload);
Parameter di sini lebih jelas, tetapi kami akan membahasnya:
- id - pengenal notifikasi. Setiap notifikasi harus memiliki pengenal unik
- judul - judul notifikasi
- body - apa yang ingin kami tampilkan sebagai pesan utama notifikasi kami
- notificationDetails - objek detail notifikasi yang kita bahas di atas
- payload - data yang ingin kita lewati dengan notifikasi ini agar bisa digunakan nanti saat notifikasi di tap dan aplikasi kita terbuka kembali
Contoh terlihat seperti ini:
await flutterLocalNotificationsPlugin.show(
12345,
"A Notification From My Application",
"This notification was sent using Flutter Local Notifcations Package",
platformChannelSpecifics,
payload: 'data');
Kasus Penggunaan - Menjadwalkan Pemberitahuan
Menjadwalkan notifikasi memerlukan waktu dan tanggal yang sesuai dengan zona waktu perangkat pengguna. Hal ini untuk mengatasi perbedaan waktu yang dapat disebabkan oleh daylight saving. Karena plugin pemberitahuan lokal sudah berisi perpustakaan zona waktu, kita tidak perlu menambahkan ketergantungan lain di file pubspec.yaml kita. Kami memang perlu mengimpornya ke layanan notifikasi kami dan juga menginisialisasinya.
import 'package:flutter_local_notifications/flutter_local_notifications.dart';
import 'package:timezone/data/latest.dart' as tz;
import 'package:timezone/timezone.dart' as tz;
Future<void> init() async {
final AndroidInitializationSettings initializationSettingsAndroid =
AndroidInitializationSettings('app_icon');
final IOSInitializationSettings initializationSettingsIOS =
IOSInitializationSettings(
requestSoundPermission: false,
requestBadgePermission: false,
requestAlertPermission: false,
onDidReceiveLocalNotification: onDidReceiveLocalNotification,
);
final InitializationSettings initializationSettings =
InitializationSettings(
android: initializationSettingsAndroid,
iOS: initializationSettingsIOS,
macOS: null);
tz.initializeTimeZones(); // <------
await flutterLocalNotificationsPlugin.initialize(initializationSettings,
onSelectNotification: selectNotification);
}
Untuk menjadwalkan notifikasi, kita perlu menggunakan metode zoneSchedule
.
Future<void> zonedSchedule(
int id,
String? title,
String? body,
TZDateTime scheduledDate,
NotificationDetails notificationDetails,
{
required UILocalNotificationDateInterpretation uiLocalNotificationDateInterpretation,
required bool androidAllowWhileIdle,
String? payload,
DateTimeComponents? matchDateTimeComponents
}
Ini memiliki beberapa kesamaan dengan metode pertunjukan, tetapi memiliki argumen yang berhubungan dengan kapan notifikasi harus dikirim. Mari kita lihat satu per satu:
- scheduleDate - ini adalah parameter yang memberi tahu pemberitahuan kapan harus dikirim. Anda bisa mendapatkan tanggal hari ini dan menambahkan jumlah waktu yang Anda inginkan
- uiLocalNotificationDateInterpretation - digunakan dalam versi iOS di bawah 10 (karena kurangnya dukungan) untuk menafsirkan waktu sebagai waktu absolut atau waktu jam dinding
- androidAllowWhileIdle - menentukan apakah pemberitahuan harus dikirim bahkan ketika perangkat dalam mode siaga daya rendah
Contoh terlihat seperti ini:
await flutterLocalNotificationsPlugin.zonedSchedule(
12345,
"A Notification From My App",
"This notification is brought to you by Local Notifcations Package",
tz.TZDateTime.now(tz.local).add(const Duration(days: 3)),
const NotificationDetails(
android: AndroidNotificationDetails(CHANNEL_ID, CHANNEL_NAME,
CHANNEL_DESCRIPTION)),
androidAllowWhileIdle: true,
uiLocalNotificationDateInterpretation:
UILocalNotificationDateInterpretation.absoluteTime);
}
Membatalkan Pemberitahuan
Saat membatalkan pemberitahuan, Anda memiliki dua opsi:
- Anda dapat membatalkan pemberitahuan tertentu
- Anda dapat membatalkan semua notifikasi yang tertunda
Untuk membatalkan notifikasi tertentu, Anda harus menggunakan id notifikasi.
await flutterLocalNotificationsPlugin.cancel(NOTIFICATION_ID);
Untuk membatalkan semua notifikasi, Anda menggunakan metode cancelAll
await flutterLocalNotificationsPlugin.cancelAll();
Masih banyak lagi yang dapat dilakukan dengan paket pemberitahuan lokal dan saya mendorong Anda untuk membaca lebih lanjut tentangnya dan memeriksa dokumentasi resminya.