FlutterのAndroid通知が届かない問題を解決した話【AndroidManifest.xml設定まとめ】

目次

はじめに

「かってに通知メモ」の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_NOTIFICATIONSAndroid 13以降の通知権限
SCHEDULE_EXACT_ALARM正確な時刻のアラーム権限
USE_EXACT_ALARM正確なアラーム使用権限
ScheduledNotificationReceiverスケジュール通知の受信
ScheduledNotificationBootReceiver再起動後の通知復元

flutter_local_notifications を使う場合、receiverの追加が最重要です。
ドキュメントに書かれていても見落としやすいので注意してください


おわりに

「かってに通知メモ」は現在iOS審査中、Android版も近日公開予定です。
自然な日本語を入力するだけで通知を設定できるリマインダーアプリです📱

目次