FlutterLocalNotificationでプッシュ通知
概要
Flutterでプッシュ通知を実装するには、flutter_local_notificationsパッケージを使用する。
インストール
まず、パッケージをインストールする。
Info
flutter pub add flutter_local_notifications権限
android/app/src/main/AndroidManifest.xmlへ以下を記述する。
<application>
<receiver android:exported="false" android:name="com.dexterous.flutterlocalnotifications.ScheduledNotificationReceiver" />
<receiver android:exported="false" android:name="com.dexterous.flutterlocalnotifications.ScheduledNotificationBootReceiver">
<intent-filter>
<action android:name="android.intent.action.BOOT_COMPLETED"/>
<action android:name="android.intent.action.MY_PACKAGE_REPLACED"/>
<action android:name="android.intent.action.QUICKBOOT_POWERON" />
<action android:name="com.htc.intent.action.QUICKBOOT_POWERON"/>
</intent-filter>
</receiver>
</application>
#追加 端末が起動されたときに通知を受ける権限を要求する
<uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED"/>
<uses-permission android:name="android.permission.SCHEDULE_EXACT_ALARM"/>
<uses-permission android:name="android.permission.USE_EXACT_ALARM"/>
権限要求を使用して通知の権限要求をユーザに求める。
import 'package:permission_handler/permission_handler.dart';
class PermissionManager{
Future<void> requsestNotifyPermission() async {
PermissionStatus status = await Permission.notification.request();
}
}オブジェクト初期化
Androidは通知に使用するアイコンに初期化が必要である。
通知チャネルの概念が存在するので、NotificationDetailsに設定を渡す必要がある。
Info
通知チャネルとはこういうもの。
ユーザがそれぞれの通知を無効化などすることができる機能である。
以下のコードはそれを設定している。
import 'package:flutter_local_notifications/flutter_local_notifications.dart';
Future<void> notify() {
final flnp = FlutterLocalNotificationsPlugin();
return flnp.initialize(
InitializationSettings(
android: AndroidInitializationSettings('@mipmap/ic_launcher'),
),
).then((_) => flnp.show(0, 'title', 'body', NotificationDetails(
android: AndroidNotificationDetails(
'channel_id',
'channel_name',
channelDescription: 'channel_description',
),
)));
}android: AndroidInitializationSettings('@mipmap/ic_launcher'),ではandroid/app/src/main/res/drawable以下の画像パス(拡張子なしのファイル名)を入れるとアイコンとして設定される。
ほとんどの場合以下のコードで初期化することができる。
import 'package:flutter_local_notifications/flutter_local_notifications.dart';
class NotificationService {
final FlutterLocalNotificationsPlugin notificationsPlugin =
FlutterLocalNotificationsPlugin();
Future<void> initNotification() async {
AndroidInitializationSettings initializationSettingsAndroid =
const AndroidInitializationSettings('flutter_logo');
var initializationSettingsIOS = DarwinInitializationSettings(
requestAlertPermission: true,
requestBadgePermission: true,
requestSoundPermission: true,
onDidReceiveLocalNotification:
(int id, String? title, String? body, String? payload) async {}
;
var initializationSettings = InitializationSettings(
android: initializationSettingsAndroid, iOS: initializationSettingsIOS);
await notificationsPlugin.initialize(initializationSettings,
onDidReceiveNotificationResponse:
(NotificationResponse notificationResponse) async {});
}
}バナー通知
バナーを出す場合は、以下のようにコードを変更する。
flnp.show(0, 'title', 'body', NotificationDetails(
android: AndroidNotificationDetails(
'channel_id',
'channel_name',
'channel_description',
+ importance: Importance.high,
+ priority: Priority.high,
),
))指定時間に毎回通知
まず、時間をTZTimeZoneに直すプログラムを書く。
時間をTZDateTimeへ変換
以下のコードは時間(hour)と分(minutes)からTZDateTimeインスタンスを生成するコードである。
元記事へのリンク tz.TZDateTime _convertTime(int hour, int minutes) { final tz.TZDateTime now = tz.TZDateTime.now(tz.local); tz.TZDateTime scheduleDate = tz.TZDateTime( tz.local, now.year, now.month, now.day, hour, minutes, ); if (scheduleDate.isBefore(now)) { scheduleDate = scheduleDate.add(const Duration(days: 1)); } return scheduleDate; }
そして、zonedScheduleメソッドで定期実行する。
// 毎週同じ時刻に通知(バックグラウンドも可)
await flnp.zonedSchedule(
ここに通知ID,
title,
bodyText,
_convertTime(10, 10),
NotificationDetails(
android: AndroidNotificationDetails(
title,
bodyText,
importance: Importance.high,
priority: Priority.high,
),
),
uiLocalNotificationDateInterpretation: UILocalNotificationDateInterpretation.absoluteTime
);よく使用するのは、id、title、body、scheduledDate、notificationDetails、uiLocalNotificationDateInterpretationである。
id
idは通知のIDを登録する。
これは通知IDの識別や通知登録の削除に使用される。
title、body
titleとbodyはユーザのAndroidの設定画面から通知のONOFFなどを設定する際に表示されるもの
scheduledDate
scheduledDateはTimeZoneを使用していつ通知を行うかを制御するものである。
notificationDetails
notificationDetailsには、AndroidやiOSのネイティブの通知の設定を行う。
androidの場合は、
NotificationDetails(
android: AndroidNotificationDetails(
notify.title,
notify.bodyText,
importance: Importance.high,
priority: Priority.high,
),
), ここにタイトルやボディテキストを設定する。
優先度や重要度設定も可能。
uiLocalNotificationDateInterpretation
uiLocalNotificationDateInterpretationはUiLocalNotificationDateInterpretationの値を渡す。
uiLocalNotificationDateInterpretation: UILocalNotificationDateInterpretation.absoluteTimeこれは絶対時間を使用するもの
relativeTimeZoneを使用した場合はユーザのタイムゾーンに沿って通知をスケジュールする。
通知の繰り返す設定
matchDateTimeComponents: DateTimeComponents.time 。
これを設定すると、設定した日付時刻には1回めに通知され、2回目以降は同じ時間に繰り返させることができる。
DateTimeComponentsは、dayOfWeekAndTime dayOfMonthAndTime dateAndTime があり、dayOfWeekAndTimeなら、2回目以降、同じ曜日の同じ時間に繰り返すことができる。
通知の解除
通地の解除には、cancelメソッドを使用する。
引き数に通知IDをとる。
await flutterLocalNotificationsPlugin.cancel(0);全てを解除するにはcancelALlを使用する。
await flutterLocalNotificationPlugin.cancelAll();