目次
はじめに
「かってに通知メモ」のAndroid対応中に、通知が全く届かない問題で丸一日ハマりました。
同じ問題で困っている方のために、解決までの過程と最終的な設定をまとめておきます。
症状
flutter_local_notificationsでスケジュール通知を登録- ログ上は正しい時刻で登録されている
- しかし指定時刻になっても通知が一切届かない
- 通知センターにも何も表示されない
試してダメだったこと
1. 通知権限の追加
<uses-permission android:name="android.permission.POST_NOTIFICATIONS"/>
→ 通知許可ダイアログは出るようになったが通知は来ない
2. 正確なアラーム権限の追加
<uses-permission android:name="android.permission.SCHEDULE_EXACT_ALARM"/>
<uses-permission android:name="android.permission.USE_EXACT_ALARM"/>
→ 権限は付与されたが通知は来ない
3. permission_handlerでの権限リクエスト
await Permission.scheduleExactAlarm.request();
→ 設定画面が開かない、効果なし
4. AndroidScheduleModeの変更
androidScheduleMode: AndroidScheduleMode.inexact,
→ 通知は来ない
解決した方法
AndroidManifest.xml に <receiver> タグを追加することで解決しました。
<receiver
android:name="com.dexterous.flutterlocalnotifications.ScheduledNotificationReceiver"
android:exported="false"/>
<receiver
android:name="com.dexterous.flutterlocalnotifications.ScheduledNotificationBootReceiver"
android:exported="true">
<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"/>
</intent-filter>
</receiver>
flutter_local_notifications v18では、このreceiverが自動では追加されないため、
手動でAndroidManifest.xmlに記述する必要があります。
最終的なAndroidManifest.xmlの全体像
<manifest xmlns:android="http://schemas.android.com/apk/res/android">
<!-- マイク権限 -->
<uses-permission android:name="android.permission.RECORD_AUDIO"/>
<!-- 正確なアラーム権限 -->
<uses-permission android:name="android.permission.SCHEDULE_EXACT_ALARM"/>
<uses-permission android:name="android.permission.USE_EXACT_ALARM"/>
<!-- 通知権限(Android 13以降必須) -->
<uses-permission android:name="android.permission.POST_NOTIFICATIONS"/>
<application
android:label="通知メモ"
android:name="${applicationName}"
android:icon="@mipmap/ic_launcher">
<activity
android:name=".MainActivity"
android:exported="true"
android:launchMode="singleTop"
android:taskAffinity=""
android:theme="@style/LaunchTheme"
android:configChanges="orientation|keyboardHidden|keyboard|screenSize|smallestScreenSize|locale|layoutDirection|fontScale|screenLayout|density|uiMode"
android:hardwareAccelerated="true"
android:windowSoftInputMode="adjustResize">
<meta-data
android:name="io.flutter.embedding.android.NormalTheme"
android:resource="@style/NormalTheme"/>
<intent-filter>
<action android:name="android.intent.action.MAIN"/>
<category android:name="android.intent.category.LAUNCHER"/>
</intent-filter>
</activity>
<meta-data
android:name="flutterEmbedding"
android:value="2"/>
<!-- 通知受信に必須のreceiver -->
<receiver
android:name="com.dexterous.flutterlocalnotifications.ScheduledNotificationReceiver"
android:exported="false"/>
<receiver
android:name="com.dexterous.flutterlocalnotifications.ScheduledNotificationBootReceiver"
android:exported="true">
<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"/>
</intent-filter>
</receiver>
</application>
</manifest>
あわせて解決したその他のAndroid対応
TimeParserの誤作動
17時51分 が 51分後 として解釈されるバグがありました。
正規表現を以下のように修正して解決:
// ❌ 修正前(「51分」にもマッチしてしまう)
final pattern = RegExp(r'(?:あと)?(\d+)分(?:後|したら|で|くらい|ほど)?');
// ✅ 修正後(「後」などが必須)
final pattern = RegExp(r'(?:あと)?(\d+)分(後|したら|で|くらい|ほど)');
通知チャンネルのキャッシュ問題
一度 importance=DEFAULT で作成された通知チャンネルがキャッシュされ、importance=HIGH に変更しても反映されない問題がありました。
# アプリデータを完全削除して解決
adb shell pm clear パッケージ名
まとめ
| 設定 | 内容 |
|---|---|
POST_NOTIFICATIONS | Android 13以降の通知権限 |
SCHEDULE_EXACT_ALARM | 正確な時刻のアラーム権限 |
USE_EXACT_ALARM | 正確なアラーム使用権限 |
ScheduledNotificationReceiver | スケジュール通知の受信 |
ScheduledNotificationBootReceiver | 再起動後の通知復元 |
flutter_local_notifications を使う場合、receiverの追加が最重要です。
ドキュメントに書かれていても見落としやすいので注意してください
おわりに
「かってに通知メモ」は現在iOS審査中、Android版も近日公開予定です。
自然な日本語を入力するだけで通知を設定できるリマインダーアプリです📱
