diff --git a/flutter_local_notifications/CHANGELOG.md b/flutter_local_notifications/CHANGELOG.md index de6a7cc6e..9c484e70c 100644 --- a/flutter_local_notifications/CHANGELOG.md +++ b/flutter_local_notifications/CHANGELOG.md @@ -1,3 +1,7 @@ +## [19.0.0-dev.2] +* **Breaking change** [Android] Removed `AndroidServiceStartType` as it wasn't having any effect. Remove the parameter from your calls to `startForegroundService()`. +* [Android] Clarified docs for [AndroidNotificationDetails.ongoing] that notifications are now always dismissible on Android 14+ + ## [19.0.0-dev.1] * **Breaking change** bumped minimum Flutter SDK requirement to 3.19.0 and Dart SDK requirement to 3.3.0 @@ -156,7 +160,7 @@ # [15.1.0] * [iOS][macOS] added the ability to request provisional permissions. On iOS, this is only applicable to iOS 12 or newer. On macOS, this property is only applicable to macOS 10.14 or newer. Thanks to the PR from [Tokenyet](https://github.com/MaikuB/flutter_local_notifications/pull/2022) - + # [15.0.1] * [Android] fixed issue [2033](https://github.com/MaikuB/flutter_local_notifications/issues/2033) where notifications on scheduled using older version of the plugin would fail to have the next subsequent ones scheduled. This issue started occuring in 14.0 where support for inexact notifications was added using the `ScheduleMode` enum that was added and resulted in the deprecation of `androidAllowWhileIdle`. A mechanism was added to help "migrate" old notifications that had `androidAllowWhileIdle` specified but didn't account for how there are recurring notifications that were scheduled using older versions of the plugin prior to `androidAllowWhile` being added. This was also released part of the 14.1.2 hotfix release @@ -165,7 +169,7 @@ * **Breaking change** removed deprecated `schedule()`, `showDailyAtTime()` and `showWeeklyAtDayAndTime()` methods. Notifications that were scheduled prior to this release should still work * **Breaking change** removed `Time` class -* [Linux] **Breaking change** calling `zonedSchedule()` on Linux will now throw an `UnimplementedError` to align with how their is a Linux implementation but the method hasn't been implemented +* [Linux] **Breaking change** calling `zonedSchedule()` on Linux will now throw an `UnimplementedError` to align with how their is a Linux implementation but the method hasn't been implemented * [iOS][macOS] **Breaking change** added supported for banner and list presentation options for iOS and macOS that is applicable for iOS 14.0 or newer and macOS 11 or newer. This is a breaking change as the values default to true and the alert presentation option is no longer applicable on these OS versions as Apple has deprecated it to be replaced by the banner and list presentations. Please ensure that if you target these OS versions that you configure the options appropriately for your application. * [Android] updated tags used when writing error logs. For corrupt scheduled notifications and error is logged the tag is now `ScheduledNotifReceiver` instead of `ScheduledNotifReceiver`. When logging that exact alarm permissions have been revoked the the tag is now `FLTLocalNotifPlugin` instead of `notification` * Updated API documentation related to the iOS/macOS notification presentation options to include links to Apple's documentations to show what they correspond to @@ -261,10 +265,10 @@ ... } ``` - + # [12.0.4] -* Fixed issue [1796](https://github.com/MaikuB/flutter_local_notifications/issues/1796) where a `java.lang.ClassCastException` may be thrown on some Android devices when the `onDidReceiveBackgroundNotificationResponse` has been specified when calling `initialize()` +* Fixed issue [1796](https://github.com/MaikuB/flutter_local_notifications/issues/1796) where a `java.lang.ClassCastException` may be thrown on some Android devices when the `onDidReceiveBackgroundNotificationResponse` has been specified when calling `initialize()` # [12.0.3+1] @@ -288,7 +292,7 @@ # [12.0.1] -* [Android][iOS] fixed issue [1721](https://github.com/MaikuB/flutter_local_notifications/issues/1721) where a crash occurs upon tapping on a notification action fbut the `onDidReceiveBackgroundNotificationResponse` optional callback hasn't been specified. +* [Android][iOS] fixed issue [1721](https://github.com/MaikuB/flutter_local_notifications/issues/1721) where a crash occurs upon tapping on a notification action fbut the `onDidReceiveBackgroundNotificationResponse` optional callback hasn't been specified. * [iOS] suppressed deprecation warnings where plugin was Apple's old notification APIs to support older iOS devices # [12.0.0] @@ -322,7 +326,7 @@ * `GET_ACTIVE_NOTIFICATION_MESSAGING_STYLE_ERROR_CODE` -> `getActiveNotificationMessagingStyle` * `PERMISSION_REQUEST_IN_PROGRESS` -> `permissionRequestInProgress` * [Android] **Breaking change** the `category` of the `AndroidNotificationDetails` now requires an instance of the newly added `AndroidNotificationCategory` class instead of a string. This was to improve the discoverability of the APIs and improve the semantics as the category can specified in a similar fashion to using an enum value -* **Breaking change** callbacks have now been reworked. There are now the following callbacks and both will pass an instance of the `NotificationResponse` class +* **Breaking change** callbacks have now been reworked. There are now the following callbacks and both will pass an instance of the `NotificationResponse` class * `onDidReceiveNotificationResponse`: invoked only when the app is running. This works for when a user has selected a notification or notification action. This replaces the `onSelectNotification` callback that existed before. For notification actions, the action needs to be configured to indicate the the app or user interface should be shown on invoking the action for this callback to be invoked i.e. by specifying the `DarwinNotificationActionOption.foreground` option on iOS and the `showsUserInterface` property on Android. On macOS and Linux, as there's no support for background isolates it will always invoke this callback * `onDidReceiveBackgroundNotificationResponse`: invoked on a background isolate for when a user has selected a notification action. This replaces the `onSelectNotificationAction` callback * **Breaking change** the `NotificationAppLaunchDetails` has been updated to contain an instance `NotificationResponse` class with the `payload` belonging to the `NotificationResponse` class. This is to allow knowing more details about what caused the app to launch e.g. if a notification action was used to do so @@ -424,7 +428,7 @@ # [9.2.0] * [Android] Added `areNotificationsEnabled()` method to `AndroidFlutterLocalNotificationsPlugin`. This allows querying if notifications are enabled for the app calling the method. Thanks to the PR from [Konstantin Pelz](https://github.com/komape) -* [Linux] Fix `initialize()` returning null all the time instead of returning an appropriate boolean value to indicate if plugin has been initialised +* [Linux] Fix `initialize()` returning null all the time instead of returning an appropriate boolean value to indicate if plugin has been initialised # [9.1.5] @@ -825,7 +829,7 @@ Please note that there are a number of breaking changes in this release to impro * `BitmapSource.Drawable` -> `DrawableResourceAndroidBitmap` * `BitmapSource.FilePath` -> `FilePathAndroidBitmap` - Each of these subclasses has a constructor that an argument referring to the bitmap itself. For example, if you previously had the following code + Each of these subclasses has a constructor that an argument referring to the bitmap itself. For example, if you previously had the following code ```dart var androidPlatformChannelSpecifics = AndroidNotificationDetails( @@ -877,7 +881,7 @@ Please note that there are a number of breaking changes in this release to impro * The `DefaultStyleInformation` class now implements the `StyleInformation` class instead of extending it * Where possible, classes in the plugins have been updated to provide `const` constructors * Updates to API docs and readme -* Bump Android dependencies +* Bump Android dependencies * Fixed a grammar issue 0.9.1 changelog entry # [1.3.0] @@ -1153,7 +1157,7 @@ Please note that there are a number of breaking changes in this release to impro # [0.4.2] -* **Breaking change** Fix issue [127](https://github.com/MaikuB/flutter_local_notifications/issues/127) by changing plugin to Android Support Library version 27.1.1, compile and target SDK version to 27 due to issues Flutter has with API 28. +* **Breaking change** Fix issue [127](https://github.com/MaikuB/flutter_local_notifications/issues/127) by changing plugin to Android Support Library version 27.1.1, compile and target SDK version to 27 due to issues Flutter has with API 28. # [0.4.1+1] * Remove unused code in example app @@ -1163,7 +1167,7 @@ Please note that there are a number of breaking changes in this release to impro * **Breaking change** renamed the `selectNotification` callback exposed by the `initialize` function to `onSelectNotification` * **Breaking change** renamed the `MessageHandler` typedef to `SelectNotificationCallback` * **Breaking change** updated plugin to Android Support Library version 28.0, compile and target SDK version to 28 -* Address issue [115](https://github.com/MaikuB/flutter_local_notifications/issues/115) by adding validation to the notification ID values. This ensure they're within the range of a 32-bit integer as notification IDs on Android need to be within that range. Note that an `ArgumentError` is thrown when a value is out of range. +* Address issue [115](https://github.com/MaikuB/flutter_local_notifications/issues/115) by adding validation to the notification ID values. This ensure they're within the range of a 32-bit integer as notification IDs on Android need to be within that range. Note that an `ArgumentError` is thrown when a value is out of range. * Updated the Android Integration section around registering receivers via the Android manifest as per the suggestion in [116](https://github.com/MaikuB/flutter_local_notifications/issues/116) * Updated version of the http dependency for used by the example app diff --git a/flutter_local_notifications/android/src/main/java/com/dexterous/flutterlocalnotifications/FlutterLocalNotificationsPlugin.java b/flutter_local_notifications/android/src/main/java/com/dexterous/flutterlocalnotifications/FlutterLocalNotificationsPlugin.java index bd3bbd9ea..452741176 100644 --- a/flutter_local_notifications/android/src/main/java/com/dexterous/flutterlocalnotifications/FlutterLocalNotificationsPlugin.java +++ b/flutter_local_notifications/android/src/main/java/com/dexterous/flutterlocalnotifications/FlutterLocalNotificationsPlugin.java @@ -2171,17 +2171,16 @@ private Integer tryParseInt(String value) { private void startForegroundService(MethodCall call, Result result) { Map notificationData = call.argument("notificationData"); - Integer startType = call.argument("startType"); ArrayList foregroundServiceTypes = call.argument("foregroundServiceTypes"); if (foregroundServiceTypes == null || foregroundServiceTypes.size() != 0) { - if (notificationData != null && startType != null) { + if (notificationData != null) { NotificationDetails notificationDetails = extractNotificationDetails(result, notificationData); if (notificationDetails != null) { if (notificationDetails.id != 0) { ForegroundServiceStartParameter parameter = new ForegroundServiceStartParameter( - notificationDetails, startType, foregroundServiceTypes); + notificationDetails, foregroundServiceTypes); Intent intent = new Intent(applicationContext, ForegroundService.class); intent.putExtra(ForegroundServiceStartParameter.EXTRA, parameter); ContextCompat.startForegroundService(applicationContext, intent); diff --git a/flutter_local_notifications/android/src/main/java/com/dexterous/flutterlocalnotifications/ForegroundService.java b/flutter_local_notifications/android/src/main/java/com/dexterous/flutterlocalnotifications/ForegroundService.java index ce27856c2..08b0ceabe 100644 --- a/flutter_local_notifications/android/src/main/java/com/dexterous/flutterlocalnotifications/ForegroundService.java +++ b/flutter_local_notifications/android/src/main/java/com/dexterous/flutterlocalnotifications/ForegroundService.java @@ -36,7 +36,7 @@ public int onStartCommand(Intent intent, int flags, int startId) { } else { startForeground(parameter.notificationData.id, notification); } - return parameter.startMode; + return Service.START_NOT_STICKY; } private static int orCombineFlags(ArrayList flags) { diff --git a/flutter_local_notifications/android/src/main/java/com/dexterous/flutterlocalnotifications/ForegroundServiceStartParameter.java b/flutter_local_notifications/android/src/main/java/com/dexterous/flutterlocalnotifications/ForegroundServiceStartParameter.java index c0becb23c..23e0ab4ed 100644 --- a/flutter_local_notifications/android/src/main/java/com/dexterous/flutterlocalnotifications/ForegroundServiceStartParameter.java +++ b/flutter_local_notifications/android/src/main/java/com/dexterous/flutterlocalnotifications/ForegroundServiceStartParameter.java @@ -10,15 +10,12 @@ public class ForegroundServiceStartParameter implements Serializable { "com.dexterous.flutterlocalnotifications.ForegroundServiceStartParameter"; public final NotificationDetails notificationData; - public final int startMode; public final ArrayList foregroundServiceTypes; public ForegroundServiceStartParameter( NotificationDetails notificationData, - int startMode, ArrayList foregroundServiceTypes) { this.notificationData = notificationData; - this.startMode = startMode; this.foregroundServiceTypes = foregroundServiceTypes; } @@ -27,8 +24,7 @@ public String toString() { return "ForegroundServiceStartParameter{" + "notificationData=" + notificationData - + ", startMode=" - + startMode + + ", foregroundServiceTypes=" + foregroundServiceTypes + '}'; diff --git a/flutter_local_notifications/lib/src/platform_flutter_local_notifications.dart b/flutter_local_notifications/lib/src/platform_flutter_local_notifications.dart index 7781f4f21..4edc9c612 100644 --- a/flutter_local_notifications/lib/src/platform_flutter_local_notifications.dart +++ b/flutter_local_notifications/lib/src/platform_flutter_local_notifications.dart @@ -226,68 +226,49 @@ class AndroidFlutterLocalNotificationsPlugin ); } - /// Starts an Android foreground service with the given notification. - /// - /// The `id` must not be 0, since Android itself does not allow starting - /// a foreground service with a notification id of 0. - /// - /// Since not all users of this plugin need such a service, it was not - /// added to this plugins Android manifest. This means you have to add - /// it if you want to use the foreground service functionality. Add the - /// foreground service permission to your apps `AndroidManifest.xml` like - /// described in the [official Android documentation](https://developer.android.com/guide/components/foreground-services#request-foreground-service-permissions): - /// ```xml - /// - /// ``` - /// Furthermore, add the `service` itself to your `AndroidManifest.xml` - /// (inside the `` tag): - /// ```xml - /// - /// - /// ``` - /// While the `android:name` must exactly match this value, you can configure - /// the other parameters as you like, although it is recommended to copy the - /// value for `android:exported`. Suitable values for - /// `foregroundServiceType` can be found [here](https://developer.android.com/reference/android/app/Service#startForeground(int,%20android.app.Notification,%20int)). - /// - /// The notification of the foreground service can be updated by - /// simply calling this method multiple times. - /// - /// Information on selecting an appropriate `startType` for your app's use - /// case should be taken from the official Android documentation, check [`Service.onStartCommand`](https://developer.android.com/reference/android/app/Service#onStartCommand(android.content.Intent,%20int,%20int)). - /// The there mentioned constants can be found in [AndroidServiceStartType]. - /// - /// The notification for the foreground service will not be dismissible - /// and automatically removed when using [stopForegroundService]. - /// - /// `foregroundServiceType` is a set of foreground service types to apply to - /// the service start. It might be `null` or omitted, but it must never - /// be empty! - /// If `foregroundServiceType` is set, [`Service.startForeground(int id, Notification notification, int foregroundServiceType)`](https://developer.android.com/reference/android/app/Service#startForeground(int,%20android.app.Notification,%20int)) - /// will be invoked , else [`Service.startForeground(int id, Notification notification)`](https://developer.android.com/reference/android/app/Service#startForeground(int,%20android.app.Notification)) is used. - /// On devices older than [`Build.VERSION_CODES.Q`](https://developer.android.com/reference/android/os/Build.VERSION_CODES#Q), `foregroundServiceType` will be ignored. - /// Note that `foregroundServiceType` (the parameter in this method) - /// must be a subset of the `android:foregroundServiceType` - /// defined in your `AndroidManifest.xml` (the one from the section above)! + /// Promotes this app to a [foreground service](https://developer.android.com/develop/background-work/services/foreground-services) with the given notification. + /// + /// Calling this function will start an empty foreground service that lets + /// Android know your app is doing important work and while it may be moved to + /// the background, it should not be killed under normal circumstances. It is + /// still possible for the service to be killed in some circumstances, such + /// as if the service has been running for a while and the device is running + /// low on memory. The service is not stopped automatically -- you must call + /// [stopForegroundService] to stop it. + /// + /// Starting a foreground service requires extra setup. Refer to the [Android Setup docs](https://pub.dev/packages/flutter_local_notifications#androidmanifestxml-setup) + /// for details. A foreground service's ID must not be zero. + /// + /// The provided notification will be displayed to indicate to the user that + /// this service is running, and will be removed when [stopForegroundService] + /// is called. To update the notification contents, call [show] with the same + /// ID after this function returns. Starting with Android 13, the notification + /// will be dismissible by default. To change that, set + /// [AndroidNotificationDetails.ongoing] to true, but read the note there. + /// + /// `foregroundServiceType` is a set of [foreground service types](https://developer.android.com/develop/background-work/services/fg-service-types) + /// relevant to this service. This set may be null but must not be empty, and + /// any service types within must also have been registered in the + /// `` tag of your app's `AndroidManifest.xml` file (refer to the + /// Android Setup docs for more details). Future startForegroundService(int id, String? title, String? body, {AndroidNotificationDetails? notificationDetails, String? payload, - AndroidServiceStartType startType = AndroidServiceStartType.startSticky, Set? foregroundServiceTypes}) { validateId(id); if (id == 0) { - throw ArgumentError.value(id, 'id', - 'The id of a notification used for an Android foreground service must not be 0!'); // ignore: lines_longer_than_80_chars + throw ArgumentError.value( + id, + 'id', + 'The ID of a foreground service ID must not be 0!', + ); } if (foregroundServiceTypes?.isEmpty ?? false) { - throw ArgumentError.value(foregroundServiceTypes, 'foregroundServiceType', - 'foregroundServiceType may be null but it must never be empty!'); + throw ArgumentError.value( + foregroundServiceTypes, + 'foregroundServiceType', + 'foregroundServiceType may be null but it must never be empty!', + ); } return _channel.invokeMethod('startForegroundService', { 'notificationData': { @@ -297,7 +278,6 @@ class AndroidFlutterLocalNotificationsPlugin 'payload': payload ?? '', 'platformSpecifics': notificationDetails?.toMap(), }, - 'startType': startType.index, 'foregroundServiceTypes': foregroundServiceTypes ?.map((AndroidServiceForegroundType type) => type.value) .toList() diff --git a/flutter_local_notifications/lib/src/platform_specifics/android/enums.dart b/flutter_local_notifications/lib/src/platform_specifics/android/enums.dart index 33deb3780..c86967190 100644 --- a/flutter_local_notifications/lib/src/platform_specifics/android/enums.dart +++ b/flutter_local_notifications/lib/src/platform_specifics/android/enums.dart @@ -124,21 +124,6 @@ enum AndroidServiceForegroundType { final int value; } -/// The available start types for an Android service. -enum AndroidServiceStartType { - /// Corresponds to [`Service.START_STICKY_COMPATIBILITY`](https://developer.android.com/reference/android/app/Service#START_STICKY_COMPATIBILITY). - startStickyCompatibility, - - /// Corresponds to [`Service.START_STICKY`](https://developer.android.com/reference/android/app/Service#START_STICKY). - startSticky, - - /// Corresponds to [`Service.START_NOT_STICKY`](https://developer.android.com/reference/android/app/Service#START_NOT_STICKY). - startNotSticky, - - /// Corresponds to [`Service.START_REDELIVER_INTENT`](https://developer.android.com/reference/android/app/Service#START_REDELIVER_INTENT). - startRedeliverIntent -} - /// The available importance levels for Android notifications. /// /// Required for Android 8.0 or newer. diff --git a/flutter_local_notifications/lib/src/platform_specifics/android/notification_details.dart b/flutter_local_notifications/lib/src/platform_specifics/android/notification_details.dart index c3a23f1d2..f8f27e40b 100644 --- a/flutter_local_notifications/lib/src/platform_specifics/android/notification_details.dart +++ b/flutter_local_notifications/lib/src/platform_specifics/android/notification_details.dart @@ -239,6 +239,9 @@ class AndroidNotificationDetails { final bool autoCancel; /// Specifies if the notification will be "ongoing". + /// + /// This used to mean the notification would be non-dismissible, but as of + /// Android 14, [that has changed](https://developer.android.com/about/versions/14/behavior-changes-all#non-dismissable-notifications). final bool ongoing; /// Specifies if the notification will be "silent". diff --git a/flutter_local_notifications/pubspec.yaml b/flutter_local_notifications/pubspec.yaml index 99c2a6108..141f07b1f 100644 --- a/flutter_local_notifications/pubspec.yaml +++ b/flutter_local_notifications/pubspec.yaml @@ -2,7 +2,7 @@ name: flutter_local_notifications description: A cross platform plugin for displaying and scheduling local notifications for Flutter applications with the ability to customise for each platform. -version: 19.0.0-dev.1 +version: 19.0.0-dev.2 homepage: https://github.com/MaikuB/flutter_local_notifications/tree/master/flutter_local_notifications issue_tracker: https://github.com/MaikuB/flutter_local_notifications/issues diff --git a/flutter_local_notifications/test/android_flutter_local_notifications_test.dart b/flutter_local_notifications/test/android_flutter_local_notifications_test.dart index ebfc62797..42e1621db 100644 --- a/flutter_local_notifications/test/android_flutter_local_notifications_test.dart +++ b/flutter_local_notifications/test/android_flutter_local_notifications_test.dart @@ -2631,7 +2631,6 @@ void main() { 'payload': '', 'platformSpecifics': null, }, - 'startType': AndroidServiceStartType.startSticky.index, 'foregroundServiceTypes': null })); }); @@ -2747,7 +2746,6 @@ void main() { 'audioAttributesUsage': 5, }, }, - 'startType': AndroidServiceStartType.startSticky.index, 'foregroundServiceTypes': null }, ));