MaikuB / flutter_local_notifications

A Flutter plugin for displaying local notifications on Android, iOS, macOS and Linux
2.45k stars 1.4k forks source link

Schedule notification not working when app is killed #1574

Closed abinmittu closed 2 years ago

abinmittu commented 2 years ago

Scheduled notification is not working when app is killed on Android Physical device.

It is working fine in Android emulator, iOS emulator and iOS physical device. On Android physical device, it is working when app is on Foreground and Background. But on Android physical device, when app is killed the notification is not showing up. I have read so many issues that are closed mentioning the same problem. I have tried 3 different Android devices Google Pixel 2XL, Micromax ione and Samsung S22. I also made sure that the battery saver mode is turned off and androidAllowWhileIdle: true.

Can anyone suggest an Android Physical device where it worked fine when app is killed?

mohammadaboalanein commented 2 years ago

I got the same issue with the Android emulator and device. When the app is killed sometimes the notification is not showing up or it is showing later (not at the same time that is given). While it is working fine with the IOS simulator or IOS devices.

Here is my code

var androidPlatformChannelSpecifics = AndroidNotificationDetails(
      "Channel id",
      "Channel name",
      channelDescription: 'Channel for Alarm notification',
      icon: 'logo',
      playSound: true,
      importance: Importance.max,
      priority: Priority.max,
      sound: RawResourceAndroidNotificationSound("sound"),
      largeIcon: DrawableResourceAndroidBitmap('logo'),
    );
    var iOSPlatformChannelSpecifics = IOSNotificationDetails(sound: sound, presentAlert: true, presentBadge: true, presentSound: playSound);
    var platformChannelSpecifics = NotificationDetails(
      android: androidPlatformChannelSpecifics,
      iOS: iOSPlatformChannelSpecifics,
    );
await flutterLocalNotificationsPlugin.zonedSchedule(
      id,
      title,
      message,
      tz.TZDateTime.from(dateTime, tz.local),
      platformChannelSpecifics,
      payload: payload,
      androidAllowWhileIdle: true,
      uiLocalNotificationDateInterpretation: UILocalNotificationDateInterpretation.absoluteTime,
    );
IronHeartDan commented 2 years ago

It will only work when the app is built in release mode.

MaikuB commented 2 years ago

You may need to check your app's configuration. I would suggest cloning the repository and running the example app on the devices to see if you observe the same behaviour and also use the example app as a reference

MaikuB commented 2 years ago

Closing this due to lack of information. If you believe there's a bug, please use the bug report template and include a link to a repo with a minimal app that can reproduce the issue

abinmittu commented 2 years ago

Scheduled notifications won't show up when the app is killed in Android because Android OS prevents background tasks for battery optimization. This is device-specific and is beyond the scope of this package. To make local notification work even when the app is killed you need to get IGNORE_BATTERY_OPTIMIZATION permission from the user. This will enable the app to run background tasks.

But, the app shouldn't be asking this permission unless it breaks the core function of the app or there is a technical reason why the app cannot use FCM high-priority messages (https://developer.android.com/training/monitoring-device-state/doze-standby#exemption-cases). For example you can ask permission in case of a medicine reminder app because the purpose of the app is to provide time-specific reminders.

To get permission from user:

  1. Specify your permission in the application manifest `android/app/src/main/AndroidManifest.xml

    <manifest...>
    <uses-permission android:name="android.permission.REQUEST_IGNORE_BATTERY_OPTIMIZATIONS"/>
    </manifest...>
  2. Get permission from user using permission_handler package.

    _getPermission() async {
    var status = await Permission.ignoreBatteryOptimizations.status;
    if(status.isDenied){
      if (await Permission.ignoreBatteryOptimizations.request().isGranted) {
        print("Ignore battery optimization Permission is granted");
      }else{
        print("Ignore battery optimization Permission is denied.");
      }
    }
    }

Once you get permission, all your scheduled notifications will work great even if app is in background or killed. 👍🏼