flutter_local_notificationsパッケージをバージョン13.0.0から17.2.1+2にアップグレードした際、様々な修正が必要になり、やや苦労しました。この記事は、同じような状況に直面した方の参考になればと思い、備忘録として書いています。
バージョン17.0.0(2024年5月9日リリース)あたりで、Android 14(targetSdkVersion 34)対応のために大きな変更があったようです。
Web上の解説記事の多くが、2023年以前のものだったため、パッケージの公式サイトのReadmeを13.0.0と17.2.1+2とで見比べながら修正を行いました。
iOS用の変更点はほぼなく(Podfileの「platform :ios」を12.0から13.0に上げた程度)、基本的には全てAndroid用の変更でした。
以下に、具体的な変更点と実施した対応を共有します。
flutter_timezoneパッケージへの変更
スケジュール通知を実装するには、デバイスのタイムゾーンを取得する必要があります。
これまで使用していたflutter_native_timezoneパッケージの更新が3年前に停止しており、flutter_timezoneというパッケージに引き継がれていました。
パッケージの入れ替えに伴い、以下の変更が必要でした:
- インポート文の変更:
// 変更前 import 'package:flutter_native_timezone/flutter_native_timezone.dart'; // 変更後 import 'package:flutter_timezone/flutter_timezone.dart';
- タイムゾーン取得関数の変更:
// 変更前 await FlutterNativeTimezone.getLocalTimezone(); // 変更後 await FlutterTimezone.getLocalTimezone();
ちなみに、flutter_local_notificationsに付随してインポートされるtimezoneパッケージには、デバイスのタイムゾーンを取得する機能は含まれていないそうです(パッケージのReadmeより)。
AndroidManifest.xmlへの許可権限追加
13.0.0と比較すると、Readmeに「AndroidManifest.xml setup」という項目が追加されていました。
主に以下の2点の追記が必要でした。
- ユーザーにパーミッション(許可)を求めるための追記:
<uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED"/> <uses-permission android:name="android.permission.SCHEDULE_EXACT_ALARM" />
RECEIVE_BOOT_COMPLETEDは、デバイスの再起動時に、通知を再スケジュールできるようにするために必要です。
SCHEDULE_EXACT_ALARMは、Android 14以降で、アプリが正確なタイミングで通知をスケジュールする必要がある場合(例えば、デバイスが低電力休止モードのときも、予定通り通知を実行する等)に設定が必要になったものです。
この記載をせずにビルドすると、アプリは起動できるものの、通知を登録する時に以下のエラーが発生し、登録を実行できませんでした。
PlatformException(exact_alarms_not_permitted, Exact alarms are not permitted, null, null)
なお、SCHEDULE_EXACT_ALARMの部分をUSE_EXACT_ALARMに変更すれば、ユーザーからの許可取得は不要ですが、Google Playへのアプリ更新申請時に審査が必要との事なので、デメリットが大きいと判断し、採用しませんでした。
- スケジュール通知を表示するための追記:
<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>
通知許可の取得方法の変更
ユーザーに通知許可のダイアログを表示するためのメソッド名が変更されました。
// 変更前 .requestPermission() // 変更後 .requestNotificationsPermission()
具体的には、FlutterLocalNotificationsPluginのインスタンスを以下のように置いていた場合、
FlutterLocalNotificationsPlugin flutterLocalNotificationsPluginO = FlutterLocalNotificationsPlugin();
許可を得るメソッドを以下のように修正する必要がありました。
flutterLocalNotificationsPluginO .resolvePlatformSpecificImplementation<AndroidFlutterLocalNotificationsPlugin>() .requestNotificationsPermission();
正確なアラーム許可の追加
前述の通り、Android 14以降は、正確なタイミングでの通知を必要とする場合、追加で許可を得ることが必要になりました。
具体的には、以下のようにrequestExactAlarmsPermission()メソッドを追加しました。
flutterLocalNotificationsPluginO .resolvePlatformSpecificImplementation<AndroidFlutterLocalNotificationsPlugin>()? .requestExactAlarmsPermission();
前項で書いた、通知自体の許可を求めるrequestNotificationsPermissionと併記してよいのか迷いましたが、下記情報によると、問題ないようだったので、2つを普通に併記しました。
実際に、アプリ起動時に確認したところ、このメソッドにより以下のような画面が表示されました。
androidScheduleModeプロパティへの変更
スケジュール通知を設定するzonedScheduleメソッドで、以下のように設定していた部分に、非推奨のアラートが出ていました。
androidAllowWhileIdle: true,
これは、通知が指定された正確な時間に表示されるようにスケジュールされ、デバイスが低電力休止モードのときにも実行されることを指定していたものです。
この部分が、androidScheduleModeというプロパティに変わり、enum型の値で設定する方式に変わったようです(ソースを見ると、設定できるenum型の値は、5種類ありました)。
今回のケースでは、以下のように変更する必要がありました。
androidScheduleMode: AndroidScheduleMode.exactAllowWhileIdle,
これで無事、アラートは解消されました。
まとめ
久しぶりにflutter_local_notificationsパッケージをアップデートしましたが、変更点が多く戸惑いました。
主な変更点は以下の通りです:
- タイムゾーン取得パッケージの変更
- AndroidManifest.xmlへの許可権限追加
- 通知許可の取得方法の変更
- 正確なアラーム許可の追加
- androidScheduleModeプロパティへの変更
同様の課題に直面している方々のご参考になれば幸いです。
コメント