From b7c48e4c8f47b8fe8743c6a360214eccc5e3de64 Mon Sep 17 00:00:00 2001 From: Levi Lesches Date: Tue, 24 Dec 2024 10:51:46 -0500 Subject: [PATCH 1/9] Added pigeon to pubspec --- flutter_local_notifications/pubspec.yaml | 1 + 1 file changed, 1 insertion(+) diff --git a/flutter_local_notifications/pubspec.yaml b/flutter_local_notifications/pubspec.yaml index ef112b444..436b94bce 100644 --- a/flutter_local_notifications/pubspec.yaml +++ b/flutter_local_notifications/pubspec.yaml @@ -21,6 +21,7 @@ dev_dependencies: flutter_test: sdk: flutter mockito: ^5.3.2 + pigeon: ^0.2.4 plugin_platform_interface: ^2.0.0 flutter: From 58f4aa15ff583595068d368773d833ac559b0655 Mon Sep 17 00:00:00 2001 From: Levi Lesches Date: Tue, 24 Dec 2024 11:08:21 -0500 Subject: [PATCH 2/9] Test pigeon file --- flutter_local_notifications/pigeon/temp.dart | 26 ++++++++++++++++++++ flutter_local_notifications/pubspec.yaml | 2 +- 2 files changed, 27 insertions(+), 1 deletion(-) create mode 100644 flutter_local_notifications/pigeon/temp.dart diff --git a/flutter_local_notifications/pigeon/temp.dart b/flutter_local_notifications/pigeon/temp.dart new file mode 100644 index 000000000..53194dc7f --- /dev/null +++ b/flutter_local_notifications/pigeon/temp.dart @@ -0,0 +1,26 @@ +@ConfigurePigeon(PigeonOptions( + dartPackageName: 'flutter_local_notifications', + dartOut: 'lib/src/android_messages.g.dart', + dartOptions: DartOptions(), + javaOptions: JavaOptions(), + javaOut: 'android/src/main/java/com/dexterous/flutterlocalnotifications/Messages.java', +)) +library; + +import 'package:pigeon/pigeon.dart'; + +class MyMessage { + const MyMessage({ + required this.name, + required this.repeats, + }); + + final String name; + final bool repeats; +} + +@HostApi() +abstract class MyApi { + void show(MyMessage message); + void cancelAll(); +} diff --git a/flutter_local_notifications/pubspec.yaml b/flutter_local_notifications/pubspec.yaml index 436b94bce..aaef0e7de 100644 --- a/flutter_local_notifications/pubspec.yaml +++ b/flutter_local_notifications/pubspec.yaml @@ -21,7 +21,7 @@ dev_dependencies: flutter_test: sdk: flutter mockito: ^5.3.2 - pigeon: ^0.2.4 + pigeon: ^22.7.0 plugin_platform_interface: ^2.0.0 flutter: From 8d1cf41a62f540e6f55d4cc9853302ad9354739a Mon Sep 17 00:00:00 2001 From: Levi Lesches Date: Tue, 24 Dec 2024 13:44:21 -0500 Subject: [PATCH 3/9] Added pigeon code for Android --- flutter_local_notifications/.gitignore | 2 + .../pigeon/android.dart | 1431 +++++++++++++++++ flutter_local_notifications/pigeon/temp.dart | 26 - 3 files changed, 1433 insertions(+), 26 deletions(-) create mode 100644 flutter_local_notifications/pigeon/android.dart delete mode 100644 flutter_local_notifications/pigeon/temp.dart diff --git a/flutter_local_notifications/.gitignore b/flutter_local_notifications/.gitignore index 73d6d6c7b..e4c5f241a 100644 --- a/flutter_local_notifications/.gitignore +++ b/flutter_local_notifications/.gitignore @@ -30,6 +30,7 @@ .pub-cache/ .pub/ /build/ +*.g.dart # Android related **/android/**/gradle-wrapper.jar @@ -39,6 +40,7 @@ **/android/gradlew.bat **/android/local.properties **/android/**/GeneratedPluginRegistrant.java +*.g.java # iOS/XCode related **/ios/**/*.mode1v3 diff --git a/flutter_local_notifications/pigeon/android.dart b/flutter_local_notifications/pigeon/android.dart new file mode 100644 index 000000000..10756ed08 --- /dev/null +++ b/flutter_local_notifications/pigeon/android.dart @@ -0,0 +1,1431 @@ +@ConfigurePigeon(PigeonOptions( + dartPackageName: 'flutter_local_notifications', + dartOut: 'lib/src/platform_specifics/android/messages.g.dart', + dartOptions: DartOptions(), + javaOptions: JavaOptions(), + javaOut: 'android/src/main/java/com/dexterous/flutterlocalnotifications/models/Messages.g.java', +)) +library; + +import 'package:pigeon/pigeon.dart'; + +// ================== Person ================== + +/// Specifies the source for icons. +enum AndroidIconSource { + /// A drawable resource. + drawableResource, + + /// A file path to a bitmap. + bitmapFilePath, + + /// A content URI. + contentUri, + + /// A Flutter asset that is a bitmap. + flutterBitmapAsset, + + /// A byte array bitmap. + byteArray, +} + +/// Represents an icon on Android. +class AndroidIcon { + AndroidIcon({ + required this.data, + required this.source, + }); + + /// The location to the icon; + Object data; + + /// The subclass source type + AndroidIconSource source; +} + +/// Details of a person e.g. someone who sent a message. +class Person { + /// Constructs an instance of [Person]. + const Person({ + this.bot = false, + this.icon, + this.important = false, + this.key, + this.name, + this.uri, + }); + + /// Whether or not this person represents a machine rather than a human. + final bool bot; + + /// Icon for this person. + final AndroidIcon? icon; + + /// Whether or not this is an important person. + final bool important; + + /// Unique identifier for this person. + final String? key; + + /// Name of this person. + final String? name; + + /// Uri for this person. + final String? uri; +} + +// ================== Message ================== + +/// Represents a message used in Android messaging style notifications. +class Message { + /// Constructs an instance of [Message]. + const Message( + this.text, + this.timestamp, + this.person, { + this.dataMimeType, + this.dataUri, + }); + + /// The message text + final String text; + + /// Time at which the message arrived. + /// + /// Note that this is eventually converted to milliseconds since epoch as + /// required by Android. + final int timestamp; + + /// Person that sent this message. + /// + /// When this is set to `null` the `Person` given to + /// [MessagingStyleInformation.person] i.e. this would indicate that the + /// message was sent from the user. + final Person? person; + + /// MIME type for this message context when the [dataUri] is provided. + final String? dataMimeType; + + /// Uri containing the content. + /// + /// The original text will be used if the content or MIME type isn't supported + final String? dataUri; +} + +// ================== Initialization Settings ================== + +/// Plugin initialization settings for Android. +class AndroidInitializationSettings { + /// Constructs an instance of [AndroidInitializationSettings]. + const AndroidInitializationSettings(this.defaultIcon); + + /// Specifies the default icon for notifications. + final String defaultIcon; +} + +// ================== Notification Channel Group ================== + +/// A group of related Android notification channels. +class AndroidNotificationChannelGroup { + /// Constructs an instance of [AndroidNotificationChannelGroup]. + const AndroidNotificationChannelGroup( + this.id, + this.name, { + this.description, + }); + + /// The id of this group. + final String id; + + /// The name of this group. + final String name; + + /// The description of this group. + /// + /// Only applicable to Android 9.0 or newer. + final String? description; +} + +// ================== Notification Channel ================== + +/// The available importance levels for Android notifications. +/// +/// Required for Android 8.0 or newer. +enum Importance { + /// Corresponds to [`NotificationManagerCompat.IMPORTANCE_UNSPECIFIED`](https://developer.android.com/reference/androidx/core/app/NotificationManagerCompat#IMPORTANCE_UNSPECIFIED()). + unspecified, + + /// Corresponds to [`NotificationManagerCompat.IMPORTANCE_NONE](https://developer.android.com/reference/androidx/core/app/NotificationManagerCompat#IMPORTANCE_NONE()). + none, + + /// Corresponds to [`NotificationManagerCompat.IMPORTANCE_MIN`](https://developer.android.com/reference/androidx/core/app/NotificationManagerCompat#IMPORTANCE_MIN()). + min, + + /// Corresponds to [`NotificationManagerCompat#IMPORTANCE_LOW`](https://developer.android.com/reference/androidx/core/app/NotificationManagerCompat#IMPORTANCE_LOW()). + low, + + /// Corresponds to [`NotificationManagerCompat.IMPORTANCE_DEFAULT](https://developer.android.com/reference/androidx/core/app/NotificationManagerCompat#IMPORTANCE_DEFAULT()). + defaultImportance, + + /// Corresponds to [`NotificationManagerCompat.IMPORTANCE_HIGH`](https://developer.android.com/reference/androidx/core/app/NotificationManagerCompat#IMPORTANCE_HIGH()). + high, + + /// Corresponds to [`NotificationManagerCompat.IMPORTANCE_MAX](https://developer.android.com/reference/androidx/core/app/NotificationManagerCompat#IMPORTANCE_MAX()). + max; +} + +/// The available audio attributes usages for an Android service. +enum AudioAttributesUsage { + /// Corresponds to [`AudioAttributes.USAGE_ALARM`](https://developer.android.com/reference/android/media/AudioAttributes#USAGE_ALARM). + alarm, + + /// Corresponds to [`AudioAttributes.USAGE_ASSISTANCE_ACCESSIBILITY`](https://developer.android.com/reference/android/media/AudioAttributes#USAGE_ASSISTANCE_ACCESSIBILITY). + assistanceAccessibility, + + /// Corresponds to [`AudioAttributes.USAGE_ASSISTANCE_NAVIGATION_GUIDANCE`](https://developer.android.com/reference/android/media/AudioAttributes#USAGE_ASSISTANCE_NAVIGATION_GUIDANCE). + assistanceNavigationGuidance, + + /// Corresponds to [`AudioAttributes.USAGE_ASSISTANCE_SONIFICATION`](https://developer.android.com/reference/android/media/AudioAttributes#USAGE_ASSISTANCE_SONIFICATION). + assistanceSonification, + + /// Corresponds to [`AudioAttributes.USAGE_ASSISTANT`](https://developer.android.com/reference/android/media/AudioAttributes#USAGE_ASSISTANT). + assistant, + + /// Corresponds to [`AudioAttributes.USAGE_GAME`](https://developer.android.com/reference/android/media/AudioAttributes#USAGE_GAME). + game, + + /// Corresponds to [`AudioAttributes.USAGE_MEDIA`](https://developer.android.com/reference/android/media/AudioAttributes#USAGE_MEDIA). + media, + + /// Corresponds to [`AudioAttributes.USAGE_NOTIFICATION`](https://developer.android.com/reference/android/media/AudioAttributes#USAGE_NOTIFICATION). + notification, + + /// Corresponds to [`AudioAttributes.USAGE_NOTIFICATION_EVENT`](https://developer.android.com/reference/android/media/AudioAttributes#USAGE_NOTIFICATION_EVENT). + notificationEvent, + + /// Corresponds to [`AudioAttributes.USAGE_NOTIFICATION_RINGTONE`](https://developer.android.com/reference/android/media/AudioAttributes#USAGE_NOTIFICATION_RINGTONE). + notificationRingtone, + + /// Corresponds to [`AudioAttributes.USAGE_UNKNOWN`](https://developer.android.com/reference/android/media/AudioAttributes#USAGE_UNKNOWN). + unknown, + + /// Corresponds to [`AudioAttributes.USAGE_VOICE_COMMUNICATION`](https://developer.android.com/reference/android/media/AudioAttributes#USAGE_VOICE_COMMUNICATION). + voiceCommunication, + + /// Corresponds to [`AudioAttributes.USAGE_VOICE_COMMUNICATION_SIGNALLING`](https://developer.android.com/reference/android/media/AudioAttributes#USAGE_VOICE_COMMUNICATION_SIGNALLING). + voiceCommunicationSignalling; +} + +/// Represents an Android notification sound. +class AndroidNotificationSound { + AndroidNotificationSound(this.sound); + + /// The location of the sound. + final String sound; +} + +/// A color on Android. +class AndroidColor { + AndroidColor.fromARGB(this.a, this.r, this.g, this.b); + + final int a; + final int r; + final int g; + final int b; +} + +/// Settings for Android notification channels. +class AndroidNotificationChannel { + /// Constructs an instance of [AndroidNotificationChannel]. + const AndroidNotificationChannel( + this.id, + this.name, { + this.description, + this.groupId, + this.importance = Importance.defaultImportance, + this.playSound = true, + this.sound, + this.enableVibration = true, + this.vibrationPattern, + this.showBadge = true, + this.enableLights = false, + this.ledColor, + this.audioAttributesUsage = AudioAttributesUsage.notification, + }); + + /// The channel's id. + final String id; + + /// The channel's name. + final String name; + + /// The channel's description. + final String? description; + + /// The id of the group that the channel belongs to. + final String? groupId; + + /// The importance of the notification. + final Importance importance; + + /// Indicates if a sound should be played when the notification is displayed. + /// + /// Tied to the specified channel and cannot be changed after the channel has + /// been created for the first time. + final bool playSound; + + /// The sound to play for the notification. + /// + /// Requires setting [playSound] to true for it to work. + /// If [playSound] is set to true but this is not specified then the default + /// sound is played. Tied to the specified channel and cannot be changed + /// after the channel has been created for the first time. + final AndroidNotificationSound? sound; + + /// Indicates if vibration should be enabled when the notification is + /// displayed. + // + /// Tied to the specified channel and cannot be changed after the channel has + /// been created for the first time. + final bool enableVibration; + + /// Indicates if lights should be enabled when the notification is displayed. + /// + /// Tied to the specified channel and cannot be changed after the channel has + /// been created for the first time. + final bool enableLights; + + /// Configures the vibration pattern. + /// + /// Requires setting [enableVibration] to true for it to work. + /// Tied to the specified channel and cannot be changed after the channel has + /// been created for the first time. + final Int64List? vibrationPattern; + + /// Specifies the light color of the notification. + /// + /// Tied to the specified channel and cannot be changed after the channel has + /// been created for the first time. + final AndroidColor? ledColor; + + /// Whether notifications posted to this channel can appear as application + /// icon badges in a Launcher + final bool showBadge; + + /// The attribute describing what is the intended use of the audio signal, + /// such as alarm or ringtone set in [`AudioAttributes.Builder`](https://developer.android.com/reference/android/media/AudioAttributes.Builder#setUsage(int)) + /// https://developer.android.com/reference/android/media/AudioAttributes + final AudioAttributesUsage audioAttributesUsage; +} + +// ================== Notification Styles ================== + +sealed class StyleInformation { + const StyleInformation(); +} + +/// Used to pass the content for an Android notification displayed using the +/// big picture style. +class BigPictureStyleInformation extends StyleInformation { + /// Constructs an instance of [BigPictureStyleInformation]. + const BigPictureStyleInformation( + this.bigPicture, { + this.contentTitle, + this.summaryText, + this.htmlFormatContentTitle = false, + this.htmlFormatSummaryText = false, + this.largeIcon, + this.htmlFormatContent = false, + this.htmlFormatTitle = false, + this.hideExpandedLargeIcon = false, + }); + + /// Specifies if formatting should be applied to the content through HTML + /// markup. + final bool htmlFormatContent; + + /// Specifies if formatting should be applied to the title through HTML + /// markup. + final bool htmlFormatTitle; + + /// Overrides ContentTitle in the big form of the template. + final String? contentTitle; + + /// Set the first line of text after the detail section in the big form of + /// the template. + final String? summaryText; + + /// Specifies if the overridden ContentTitle should have formatting applied + /// through HTML markup. + final bool htmlFormatContentTitle; + + /// Specifies if formatting should be applied to the first line of text after + /// the detail section in the big form of the template. + final bool htmlFormatSummaryText; + + /// The bitmap that will override the large icon when the big notification is + /// shown. + final AndroidIcon? largeIcon; + + /// The bitmap to be used as the payload for the BigPicture notification. + final AndroidIcon bigPicture; + + /// Hides the large icon when showing the expanded notification. + final bool hideExpandedLargeIcon; +} + +/// Used to pass the content for an Android notification displayed using the +/// big text style. +class BigTextStyleInformation extends StyleInformation { + /// Constructs an instance of [BigTextStyleInformation]. + const BigTextStyleInformation( + this.bigText, { + this.htmlFormatBigText = false, + this.contentTitle, + this.htmlFormatContentTitle = false, + this.summaryText, + this.htmlFormatSummaryText = false, + this.htmlFormatContent = false, + this.htmlFormatTitle = false, + }); + + /// Specifies if formatting should be applied to the content through HTML + /// markup. + final bool htmlFormatContent; + + /// Specifies if formatting should be applied to the title through HTML + /// markup. + final bool htmlFormatTitle; + + /// Provide the longer text to be displayed in the big form of the template + /// in place of the content text. + final String bigText; + + /// Overrides ContentTitle in the big form of the template. + final String? contentTitle; + + /// Set the first line of text after the detail section in the big form of + /// the template. + final String? summaryText; + + /// Specifies if formatting should be applied to the longer text through + /// HTML markup. + final bool htmlFormatBigText; + + /// Specifies if the overridden ContentTitle should have formatting applies + /// through HTML markup. + final bool htmlFormatContentTitle; + + /// Specifies if formatting should be applied to the first line of text + /// after the detail section in the big form of the template. + final bool htmlFormatSummaryText; +} + +/// Used to pass the content for an Android notification displayed using the +/// inbox style. +class InboxStyleInformation extends StyleInformation { + /// Constructs an instance of [InboxStyleInformation]. + const InboxStyleInformation( + this.lines, { + this.htmlFormatLines = false, + this.contentTitle, + this.htmlFormatContentTitle = false, + this.summaryText, + this.htmlFormatSummaryText = false, + this.htmlFormatContent = false, + this.htmlFormatTitle = false, + }); + + /// Specifies if formatting should be applied to the content through HTML + /// markup. + final bool htmlFormatContent; + + /// Specifies if formatting should be applied to the title through HTML + /// markup. + final bool htmlFormatTitle; + + /// Overrides ContentTitle in the big form of the template. + final String? contentTitle; + + /// Set the first line of text after the detail section in the big form of + /// the template. + final String? summaryText; + + /// The lines that form part of the digest section for inbox-style + /// notifications. + final List lines; + + /// Specifies if the lines should have formatting applied through HTML markup. + final bool htmlFormatLines; + + /// Specifies if the overridden ContentTitle should have formatting applied + /// through HTML markup. + final bool htmlFormatContentTitle; + + /// Specifies if formatting should be applied to the first line of text after + /// the detail section in the big form of the template. + final bool htmlFormatSummaryText; +} + +/// Used to pass the content for an Android notification displayed using the +/// messaging style. +class MessagingStyleInformation extends StyleInformation { + /// Constructs an instance of [MessagingStyleInformation]. + MessagingStyleInformation( + this.person, { + this.conversationTitle, + this.groupConversation, + this.messages, + this.htmlFormatContent = false, + this.htmlFormatTitle = false, + }); + + /// Specifies if formatting should be applied to the content through HTML + /// markup. + final bool htmlFormatContent; + + /// Specifies if formatting should be applied to the title through HTML + /// markup. + final bool htmlFormatTitle; + + /// The person displayed for any messages that are sent by the user. + final Person person; + + /// The title to be displayed on this conversation. + final String? conversationTitle; + + /// Whether this conversation notification represents a group. + final bool? groupConversation; + + /// Messages to be displayed by this notification + final List? messages; +} + +// ================== Notification Details ================== + +/// Priority for notifications on Android 7.1 and lower. +enum Priority { + /// Corresponds to [`NotificationCompat.PRIORITY_MIN`](https://developer.android.com/reference/androidx/core/app/NotificationCompat#PRIORITY_MIN()). + min, + + /// Corresponds to [`NotificationCompat.PRIORITY_LOW()`](https://developer.android.com/reference/androidx/core/app/NotificationCompat#PRIORITY_LOW()). + low, + + /// Corresponds to [`NotificationCompat.PRIORITY_DEFAULT`](https://developer.android.com/reference/androidx/core/app/NotificationCompat#PRIORITY_DEFAULT()). + defaultPriority, + + /// Corresponds to [`NotificationCompat.PRIORITY_HIGH`](https://developer.android.com/reference/androidx/core/app/NotificationCompat#PRIORITY_HIGH()). + high, + + /// Corresponds to [`NotificationCompat.PRIORITY_MAX`](https://developer.android.com/reference/androidx/core/app/NotificationCompat#PRIORITY_MAX()). + max; +} + +/// The available alert behaviours for grouped notifications. +enum GroupAlertBehavior { + /// All notifications in a group with sound or vibration ought to make + /// sound or vibrate. + all, + + /// All children notification in a group should be silenced + summary, + + /// The summary notification in a group should be silenced. + children +} + +/// Mirrors the `RemoteInput` functionality available in NotificationCompat. +/// +/// See the official docs at +/// https://developer.android.com/reference/kotlin/androidx/core/app/RemoteInput?hl=en +/// for details. +class AndroidNotificationActionInput { + /// Constructs a [AndroidNotificationActionInput]. The platform will create + /// this object using `RemoteInput.Builder`. See the official docs + /// https://developer.android.com/reference/kotlin/androidx/core/app/RemoteInput.Builder?hl=en + /// for details. + const AndroidNotificationActionInput({ + this.choices = const [], + this.allowFreeFormInput = true, + this.label, + this.allowedMimeTypes = const [], + }); + + /// Specifies choices available to the user to satisfy this input. + final List choices; + + /// Specifies whether the user can provide arbitrary text values. + final bool allowFreeFormInput; + + /// Set a label to be displayed to the user when collecting this input. + final String? label; + + /// Specifies whether the user can provide arbitrary values. + final List allowedMimeTypes; +} + +/// Mirrors the `Action` class in AndroidX. +/// +/// See the offical docs at +/// https://developer.android.com/reference/kotlin/androidx/core/app/NotificationCompat.Action?hl=en +/// for details. +class AndroidNotificationAction { + /// Constructs a [AndroidNotificationAction] object. The platform will create + /// this object using `Action.Builder`. See the offical docs + /// https://developer.android.com/reference/kotlin/androidx/core/app/NotificationCompat.Action.Builder?hl=en + /// for details. + const AndroidNotificationAction( + this.id, + this.title, { + this.titleColor, + this.icon, + this.contextual = false, + this.showsUserInterface = false, + this.allowGeneratedReplies = false, + this.inputs = const [], + this.cancelNotification = true, + }); + + /// This ID will be sent back in the action handler defined in + /// [FlutterLocalNotificationsPlugin]. + final String id; + + /// The title of the action + final String title; + + /// The color of the title of the action + final AndroidColor? titleColor; + + /// Icon to show for this action. + final AndroidIcon? icon; + + /// Sets whether this Action is a contextual action, i.e. whether the action + /// is dependent on the notification message body. An example of a contextual + /// action could be an action opening a map application with an address shown + /// in the notification. + final bool contextual; + + /// Set whether or not this Action's PendingIntent will open a user interface. + final bool showsUserInterface; + + /// Set whether the platform should automatically generate possible replies to + /// add to RemoteInput#getChoices(). If the Action doesn't have a RemoteInput, + /// this has no effect. + /// + /// You need to specify [inputs] for this property to work. + final bool allowGeneratedReplies; + + /// Add an input to be collected from the user when this action is sent. + final List inputs; + + /// Set whether the notification should be canceled when this action is + /// selected. + final bool cancelNotification; +} + +/// Defines the notification visibility on the lockscreen. +enum NotificationVisibility { + /// Show this notification on all lockscreens, but conceal sensitive + /// or private information on secure lockscreens. + private, + + /// Show this notification in its entirety on all lockscreens. + public, + + /// Do not reveal any part of this notification on a secure lockscreen. + secret, +} + +/// The available actions for managing notification channels. +enum AndroidNotificationChannelAction { + /// Create a channel if it doesn't exist. + createIfNotExists, + + /// Updates the details of an existing channel. Note that some details can + /// not be changed once a channel has been created. + update +} + +/// The available categories for Android notifications. +enum AndroidNotificationCategory { + /// Alarm or timer. + /// + /// Corresponds to [`NotificationCompat.CATEGORY_ALARM`](https://developer.android.com/reference/androidx/core/app/NotificationCompat#CATEGORY_ALARM%28%29). + alarm('alarm'), + + /// Incoming call (voice or video) or similar + /// synchronous communication request. + /// + /// Corresponds to [`NotificationCompat.CATEGORY_CALL`](https://developer.android.com/reference/androidx/core/app/NotificationCompat#CATEGORY_CALL%28%29). + call('call'), + + /// Asynchronous bulk message (email). + /// + /// Corresponds to [`NotificationCompat.CATEGORY_EMAIL`](https://developer.android.com/reference/androidx/core/app/NotificationCompat#CATEGORY_EMAIL%28%29). + email('email'), + + /// Error in background operation or authentication status. + /// + /// Corresponds to [`NotificationCompat.CATEGORY_ERROR`](https://developer.android.com/reference/androidx/core/app/NotificationCompat#CATEGORY_ERROR%28%29). + error('err'), + + /// Calendar event. + /// + /// Corresponds to [`NotificationCompat.CATEGORY_EVENT`](https://developer.android.com/reference/androidx/core/app/NotificationCompat#CATEGORY_EVENT%28%29). + event('event'), + + /// Temporarily sharing location. + /// + /// Corresponds to [`NotificationCompat.CATEGORY_LOCATION_SHARING`](https://developer.android.com/reference/androidx/core/app/NotificationCompat#CATEGORY_LOCATION_SHARING%28%29). + locationSharing('location_sharing'), + + /// Incoming direct message like SMS and instant message. + /// + /// Corresponds to [`NotificationCompat.CATEGORY_MESSAGE`](https://developer.android.com/reference/androidx/core/app/NotificationCompat#CATEGORY_MESSAGE%28%29). + message('msg'), + + /// Missed call. + /// + /// Corresponds to [`NotificationCompat.CATEGORY_MISSED_CALL`](https://developer.android.com/reference/androidx/core/app/NotificationCompat#CATEGORY_MISSED_CALL%28%29). + missedCall('missed_call'), + + /// Map turn-by-turn navigation. + /// + /// Corresponds to [`NotificationCompat.CATEGORY_NAVIGATION`](https://developer.android.com/reference/androidx/core/app/NotificationCompat#CATEGORY_NAVIGATION%28%29). + navigation('navigation'), + + /// Progress of a long-running background operation. + /// + /// Corresponds to [`NotificationCompat.CATEGORY_PROGRESS`](https://developer.android.com/reference/androidx/core/app/NotificationCompat#CATEGORY_PROGRESS%28%29). + progress('progress'), + + /// Promotion or advertisement. + /// + /// Corresponds to [`NotificationCompat.CATEGORY_PROMO`](https://developer.android.com/reference/androidx/core/app/NotificationCompat#CATEGORY_PROMO%28%29). + promo('promo'), + + /// A specific, timely recommendation for a single thing. + /// + /// For example, a news app might want to recommend a + /// news story it believes the user will want to read next. + /// + /// Corresponds to [`NotificationCompat.CATEGORY_RECOMMENDATION`](https://developer.android.com/reference/androidx/core/app/NotificationCompat#CATEGORY_RECOMMENDATION%28%29). + recommendation('recommendation'), + + /// User-scheduled reminder. + /// + /// Corresponds to [`NotificationCompat.CATEGORY_REMINDER`](https://developer.android.com/reference/androidx/core/app/NotificationCompat#CATEGORY_REMINDER%28%29). + reminder('reminder'), + + /// Indication of running background service. + /// + /// Corresponds to [`NotificationCompat.CATEGORY_SERVICE`](https://developer.android.com/reference/androidx/core/app/NotificationCompat#CATEGORY_SERVICE%28%29). + service('service'), + + /// Social network or sharing update. + /// + /// Corresponds to [`NotificationCompat.CATEGORY_SOCIAL`](https://developer.android.com/reference/androidx/core/app/NotificationCompat#CATEGORY_SOCIAL%28%29). + social('social'), + + /// Ongoing information about device or contextual status. + /// + /// Corresponds to [`NotificationCompat.CATEGORY_STATUS`](https://developer.android.com/reference/androidx/core/app/NotificationCompat#CATEGORY_STATUS%28%29). + status('status'), + + /// Running stopwatch. + /// + /// Corresponds to [`NotificationCompat.CATEGORY_STOPWATCH`](https://developer.android.com/reference/androidx/core/app/NotificationCompat#CATEGORY_STOPWATCH%28%29). + stopwatch('stopwatch'), + + /// System or device status update. + /// + /// Reserved for system use. + /// + /// Corresponds to [`NotificationCompat.CATEGORY_SYSTEM`](https://developer.android.com/reference/androidx/core/app/NotificationCompat#CATEGORY_SYSTEM%28%29). + system('sys'), + + /// Media transport control for playback. + /// + /// Corresponds to [`NotificationCompat.CATEGORY_TRANSPORT`](https://developer.android.com/reference/androidx/core/app/NotificationCompat#CATEGORY_TRANSPORT%28%29). + transport('transport'), + + /// Tracking a user's workout. + /// + /// Corresponds to [`NotificationCompat.CATEGORY_WORKOUT`](https://developer.android.com/reference/androidx/core/app/NotificationCompat#CATEGORY_WORKOUT%28%29). + workout('workout'); + + /// Constructs an instance of [AndroidNotificationCategory] + /// with a given [name] of category. + const AndroidNotificationCategory(this.name); + + /// The name of category. + final String name; +} + +/// Contains notification details specific to Android. +class AndroidNotificationDetails { + /// Constructs an instance of [AndroidNotificationDetails]. + const AndroidNotificationDetails( + this.channelId, + this.channelName, { + this.channelDescription, + this.icon, + this.importance = Importance.defaultImportance, + this.priority = Priority.defaultPriority, + this.styleInformation, + this.playSound = true, + this.sound, + this.enableVibration = true, + this.vibrationPattern, + this.groupKey, + this.setAsGroupSummary = false, + this.groupAlertBehavior = GroupAlertBehavior.all, + this.autoCancel = true, + this.ongoing = false, + this.silent = false, + this.color, + this.largeIcon, + this.onlyAlertOnce = false, + this.showWhen = true, + this.when, + this.usesChronometer = false, + this.chronometerCountDown = false, + this.channelShowBadge = true, + this.showProgress = false, + this.maxProgress = 0, + this.progress = 0, + this.indeterminate = false, + this.channelAction = AndroidNotificationChannelAction.createIfNotExists, + this.enableLights = false, + this.ledColor, + this.ledOnMs, + this.ledOffMs, + this.ticker, + this.visibility, + this.timeoutAfter, + this.category, + this.fullScreenIntent = false, + this.shortcutId, + this.additionalFlags, + this.subText, + this.tag, + this.actions, + this.colorized = false, + this.number, + this.audioAttributesUsage = AudioAttributesUsage.notification, + }); + + /// The icon that should be used when displaying the notification. + /// + /// When this is set to `null`, the default icon given to + /// [AndroidInitializationSettings.defaultIcon] will be used. + final String? icon; + + /// The channel's id. + /// + /// Required for Android 8.0 or newer. + final String channelId; + + /// The channel's name. + /// + /// Required for Android 8.0 or newer. + final String channelName; + + /// The channel's description. + /// + /// This property is only applicable to Android versions 8.0 or newer. + final String? channelDescription; + + /// Whether notifications posted to this channel can appear as application + /// icon badges in a Launcher + final bool channelShowBadge; + + /// The importance of the notification. + final Importance importance; + + /// The priority of the notification + final Priority priority; + + /// Indicates if a sound should be played when the notification is displayed. + /// + /// For Android 8.0 or newer, this is tied to the specified channel and cannot + /// be changed after the channel has been created for the first time. + final bool playSound; + + /// The sound to play for the notification. + /// + /// Requires setting [playSound] to true for it to work. + /// If [playSound] is set to true but this is not specified then the default + /// sound is played. + /// + /// For Android 8.0 or newer, this is tied to the specified channel and cannot + /// be changed after the channel has been created for the first time. + final AndroidNotificationSound? sound; + + /// Indicates if vibration should be enabled when the notification is + /// displayed. + /// + /// For Android 8.0 or newer, this is tied to the specified channel and cannot + /// be changed after the channel has been created for the first time. + final bool enableVibration; + + /// Indicates if lights should be enabled when the notification is displayed. + /// + /// For Android 8.0 or newer, this is tied to the specified channel and cannot + /// be changed after the channel has been created for the first time. + final bool enableLights; + + /// Configures the vibration pattern. + /// + /// Requires setting [enableVibration] to true for it to work. + /// For Android 8.0 or newer, this is tied to the specified channel and cannot + /// be changed after the channel has been created for the first time. + final Int64List? vibrationPattern; + + /// Specifies the information of the rich notification style to apply to the + /// notification. + final StyleInformation? styleInformation; + + /// Specifies the group that this notification belongs to. + /// + /// For Android 7.0 or newer. + final String? groupKey; + + /// Specifies if this notification will function as the summary for grouped + /// notifications. + final bool setAsGroupSummary; + + /// Specifies the group alert behavior for this notification. + /// + /// Default is AlertAll. + /// See https://developer.android.com/reference/android/support/v4/app/NotificationCompat.Builder.html#setGroupAlertBehavior(int) for more details. + final GroupAlertBehavior groupAlertBehavior; + + /// Specifies if the notification should automatically dismissed upon tapping + /// on it. + final bool autoCancel; + + /// Specifies if the notification will be "ongoing". + final bool ongoing; + + /// Specifies if the notification will be "silent". + final bool silent; + + /// Specifies the color. + final AndroidColor? color; + + /// Specifics the large icon to use. + final AndroidIcon? largeIcon; + + /// Specifies if you would only like the sound, vibrate and ticker to be + /// played if the notification is not already showing. + final bool onlyAlertOnce; + + /// Specifies if the notification should display the timestamp of when it + /// occurred. + /// + /// To control the actual timestamp of the notification, use [when]. + final bool showWhen; + + /// Specifies the timestamp of the notification. + /// + /// To control whether the timestamp is shown in the notification, use + /// [showWhen]. + /// + /// The timestamp is expressed as the number of milliseconds since the + /// "Unix epoch" 1970-01-01T00:00:00Z (UTC). If it's not specified but a + /// timestamp should be shown (i.e. [showWhen] is set to `true`), + /// then Android will default to showing when the notification occurred. + final int? when; + + /// Show [when] as a stopwatch. + /// + /// Instead of presenting [when] as a timestamp, the notification will show an + /// automatically updating display of the minutes and seconds since [when]. + /// Useful when showing an elapsed time (like an ongoing phone call). + final bool usesChronometer; + + /// Sets the chronometer to count down instead of counting up. + /// + /// This property is only applicable to Android 7.0 and newer versions. + final bool chronometerCountDown; + + /// Specifies if the notification will be used to show progress. + final bool showProgress; + + /// The maximum progress value. + final int maxProgress; + + /// The current progress value. + final int progress; + + /// Specifies if an indeterminate progress bar will be shown. + final bool indeterminate; + + /// Specifies the light color of the notification. + /// + /// For Android 8.0 or newer, this is tied to the specified channel and cannot + /// be changed after the channel has been created for the first time. + final AndroidColor? ledColor; + + /// Specifies how long the light colour will remain on. + /// + /// This property is only applicable to Android versions older than 8.0. + final int? ledOnMs; + + /// Specifies how long the light colour will remain off. + /// + /// This property is only applicable to Android versions older than 8.0. + final int? ledOffMs; + + /// Specifies the "ticker" text which is sent to accessibility services. + final String? ticker; + + /// The action to take for managing notification channels. + /// + /// Defaults to creating the notification channel using the provided details + /// if it doesn't exist + final AndroidNotificationChannelAction channelAction; + + /// Defines the notification visibility on the lockscreen. + final NotificationVisibility? visibility; + + /// The duration in milliseconds after which the notification will be + /// cancelled if it hasn't already. + final int? timeoutAfter; + + /// The notification category. + final AndroidNotificationCategory? category; + + /// Specifies whether the notification should launch a full-screen intent as + /// soon as it triggers. + /// + /// Note: The system UI may choose to display a heads-up notification, + /// instead of launching your full-screen intent. This can occur while the + /// user is using the device or due the full-screen intent not being granted. + /// When the full-screen intent occurs, the plugin will act as though + /// the user has tapped on a notification so handle it the same way + /// (e.g. via `onSelectNotification` callback) to display the appropriate + /// page for your application. + final bool fullScreenIntent; + + /// Specifies the id of a published, long-lived sharing that the notification + /// will be linked to. + /// + /// From Android 11, this affects if a messaging-style notification appears + /// in the conversation space. + final String? shortcutId; + + /// Specifies the additional flags. + /// + /// These flags will get added to the native Android notification's flags field: https://developer.android.com/reference/android/app/Notification#flags + /// For a list of a values, refer to the documented constants prefixed with "FLAG_" (without the quotes) at https://developer.android.com/reference/android/app/Notification.html#constants_1. + /// For example, use a value of 4 to allow the audio to repeat as documented at https://developer.android.com/reference/android/app/Notification.html#FLAG_INSISTEN + final Int32List? additionalFlags; + + /// Specify a list of actions associated with this notifications. + /// + /// Users will be able tap on the actions without actually launching the App. + /// Note that tapping a action will spawn a separate isolate that runs + /// **independently** from the main app. + final List? actions; + + /// Provides some additional information that is displayed in the + /// notification. + /// + /// No guarantees are given where exactly it is displayed. This information + /// should only be provided if it provides an essential benefit to the + /// understanding of the notification. The more text you provide the less + /// readable it becomes. For example, an email client should only provide the + /// account name here if more than one email account has been added. + /// + /// As of Android 7.0 this information is displayed in the notification header + /// area. On Android versions before 7.0 this will be shown in the third line + /// of text in the platform notification template. You should not be using + /// setProgress(int, int, boolean) at the same time on those versions; they + /// occupy the same place. + final String? subText; + + /// The notification tag. + /// + /// Showing notification with the same (tag, id) pair as a currently visible + /// notification will replace the old notification with the new one, provided + /// the old notification was one that was not one that was scheduled. In other + /// words, the (tag, id) pair is only applicable for notifications that were + /// requested to be shown immediately. This is because the Android + /// AlarmManager APIs used for scheduling notifications only allow for using + /// the id to uniquely identify alarms. + final String? tag; + + /// Specify coloring background should be enabled, if false, color will be + /// applied to app icon. + /// + /// For most styles, the coloring will only be applied if the notification is + /// or a foreground service notification. + final bool colorized; + + /// Set custom notification count. + /// + /// Numbers are only displayed if the launcher application supports the + /// display of badges and numbers. If not supported, this value is ignored. + /// See https://developer.android.com/training/notify-user/badges#set_custom_notification_count + final int? number; + + /// The attribute describing what is the intended use of the audio signal, + /// such as alarm or ringtone set in [`AudioAttributes.Builder`](https://developer.android.com/reference/android/media/AudioAttributes.Builder#setUsage(int)) + /// https://developer.android.com/reference/android/media/AudioAttributes + final AudioAttributesUsage audioAttributesUsage; +} + +// ================== Notification Responses ================== + +/// The possible notification response types +enum NotificationResponseType { + /// Indicates that a user has selected a notification. + selectedNotification, + + /// Indicates the a user has selected a notification action. + selectedNotificationAction, +} + +/// Details of a Notification Action that was triggered. +class NotificationResponse { + /// Constructs an instance of [NotificationResponse] + const NotificationResponse({ + required this.notificationResponseType, + this.id, + this.actionId, + this.input, + this.payload, + this.data = const {}, + }); + + /// The notification's id. + /// + /// This is nullable as support for this only supported for notifications + /// created using version 10 or newer of this plugin. + final int? id; + + /// The id of the action that was triggered. + final String? actionId; + + /// The value of the input field if the notification action had an input + /// field. + /// + /// On Windows, this is always null. Instead, [data] holds the values of + /// each input with the input's ID as the key. + final String? input; + + /// The notification's payload. + final String? payload; + + /// Any other data returned by the platform. + /// + /// Returned only on Windows. + final Map data; + + /// The notification response type. + final NotificationResponseType notificationResponseType; +} + +/// Contains details on the notification that launched the application. +class NotificationAppLaunchDetails { + /// Constructs an instance of [NotificationAppLaunchDetails]. + const NotificationAppLaunchDetails( + this.didNotificationLaunchApp, { + this.notificationResponse, + }); + + /// Indicates if the app was launched via notification. + final bool didNotificationLaunchApp; + + /// Contains details of the notification that launched the app. + final NotificationResponse? notificationResponse; +} + +// ================== Notification Plugin ================== + +/// Details of a pending notification that has not been delivered. +class PendingNotificationRequest { + /// Constructs an instance of [PendingNotificationRequest]. + const PendingNotificationRequest(this.id, this.title, this.body, this.payload); + + /// The notification's id. + final int id; + + /// The notification's title. + final String? title; + + /// The notification's body. + final String? body; + + /// The notification's payload. + final String? payload; +} + + +/// Details of an active notification. +class ActiveNotification { + /// Constructs an instance of [ActiveNotification]. + const ActiveNotification({ + this.id, + this.groupKey, + this.channelId, + this.title, + this.body, + this.payload, + this.tag, + this.bigText, + }); + + /// The notification's id. + /// + /// This will be null if the notification was outsided of the plugin's + /// control e.g. on iOS and via Firebase Cloud Messaging. + final int? id; + + /// The notification's channel id. + /// + /// Returned only on Android 8.0 or newer. + final String? channelId; + + /// The notification's group. + /// + /// Returned only on Android. + final String? groupKey; + + /// The notification's title. + final String? title; + + /// The notification's body. + final String? body; + + /// The notification's payload. + /// + /// Returned only on iOS and macOS. + final String? payload; + + /// The notification's tag. + /// + /// Returned only on Android. + final String? tag; + + /// The notification's longer text displayed using big text style. + /// + /// Returned only on Android. + final String? bigText; +} + +class AndroidNotificationData { + const AndroidNotificationData({ + required this.id, + required this.title, + required this.body, + required this.details, + required this.payload, + }); + + final int id; + final String? title; + final String? body; + final String? payload; + final AndroidNotificationDetails? details; +} + +/// 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 +} + +enum AndroidServiceForegroundType { + /// Corresponds to [`ServiceInfo.FOREGROUND_SERVICE_TYPE_MANIFEST`](https://developer.android.com/reference/android/content/pm/ServiceInfo#FOREGROUND_SERVICE_TYPE_MANIFEST). + foregroundServiceTypeManifest, + + /// Corresponds to [`ServiceInfo.FOREGROUND_SERVICE_TYPE_NONE`](https://developer.android.com/reference/android/content/pm/ServiceInfo#FOREGROUND_SERVICE_TYPE_NONE). + foregroundServiceTypeNone, + + /// Corresponds to [`ServiceInfo.FOREGROUND_SERVICE_TYPE_DATA_SYNC`](https://developer.android.com/reference/android/content/pm/ServiceInfo#FOREGROUND_SERVICE_TYPE_DATA_SYNC). + foregroundServiceTypeDataSync, + + /// Corresponds to [`ServiceInfo.FOREGROUND_SERVICE_TYPE_MEDIA_PLAYBACK`](https://developer.android.com/reference/android/content/pm/ServiceInfo#FOREGROUND_SERVICE_TYPE_MEDIA_PLAYBACK). + foregroundServiceTypeMediaPlayback, + + /// Corresponds to [`ServiceInfo.FOREGROUND_SERVICE_TYPE_PHONE_CALL`](https://developer.android.com/reference/android/content/pm/ServiceInfo#FOREGROUND_SERVICE_TYPE_PHONE_CALL). + foregroundServiceTypePhoneCall, + + /// Corresponds to [`ServiceInfo.FOREGROUND_SERVICE_TYPE_LOCATION`](https://developer.android.com/reference/android/content/pm/ServiceInfo#FOREGROUND_SERVICE_TYPE_LOCATION). + foregroundServiceTypeLocation, + + /// Corresponds to [`ServiceInfo.FOREGROUND_SERVICE_TYPE_CONNECTED_DEVICE`](https://developer.android.com/reference/android/content/pm/ServiceInfo#FOREGROUND_SERVICE_TYPE_CONNECTED_DEVICE). + foregroundServiceTypeConnectedDevice, + + /// Corresponds to [`ServiceInfo.FOREGROUND_SERVICE_TYPE_MEDIA_PROJECTION`](https://developer.android.com/reference/android/content/pm/ServiceInfo#FOREGROUND_SERVICE_TYPE_MEDIA_PROJECTION). + foregroundServiceTypeMediaProjection, + + /// Corresponds to [`ServiceInfo.FOREGROUND_SERVICE_TYPE_CAMERA`](https://developer.android.com/reference/android/content/pm/ServiceInfo#FOREGROUND_SERVICE_TYPE_CAMERA). + foregroundServiceTypeCamera, + + /// Corresponds to [`ServiceInfo.FOREGROUND_SERVICE_TYPE_MICROPHONE`](https://developer.android.com/reference/android/content/pm/ServiceInfo#FOREGROUND_SERVICE_TYPE_MICROPHONE). + foregroundServiceTypeMicrophone, + + /// Corresponds to [`ServiceInfo.FOREGROUND_SERVICE_TYPE_HEALTH`](https://developer.android.com/reference/android/content/pm/ServiceInfo#FOREGROUND_SERVICE_TYPE_HEALTH). + foregroundServiceTypeHealth, + + /// Corresponds to [`ServiceInfo.FOREGROUND_SERVICE_TYPE_REMOTE_MESSAGING`](https://developer.android.com/reference/android/content/pm/ServiceInfo#FOREGROUND_SERVICE_TYPE_REMOTE_MESSAGING). + + foregroundServiceTypeRemoteMessaging, + + /// Corresponds to [`ServiceInfo.FOREGROUND_SERVICE_TYPE_SYSTEM_EXEMPTED`](https://developer.android.com/reference/android/content/pm/ServiceInfo#FOREGROUND_SERVICE_TYPE_SYSTEM_EXEMPTED). + foregroundServiceTypeSystemExempted, + + /// Corresponds to [`ServiceInfo.FOREGROUND_SERVICE_TYPE_SHORT_SERVICE`](https://developer.android.com/reference/android/content/pm/ServiceInfo#FOREGROUND_SERVICE_TYPE_SHORT_SERVICE). + foregroundServiceTypeShortService, + + /// Corresponds to [`ServiceInfo.FOREGROUND_SERVICE_TYPE_SPECIAL_USE`](https://developer.android.com/reference/android/content/pm/ServiceInfo#FOREGROUND_SERVICE_TYPE_SPECIAL_USE). + foregroundServiceTypeSpecialUse; +} + +class DateTimeWithTimezone { + const DateTimeWithTimezone({ + required this.scheduledDateTime, + required this.scheduledDateTimeIso8601, + required this.timezoneName, + }); + + final String timezoneName; + final String scheduledDateTime; + final String scheduledDateTimeIso8601; +} + +/// The components of a date and time representations. +enum DateTimeComponents { + /// The time. + time, + + /// The day of the week and time. + dayOfWeekAndTime, + + /// The day of the month and time. + dayOfMonthAndTime, + + /// The date and time. + dateAndTime, +} + +/// The available intervals for periodically showing notifications. +enum RepeatInterval { + /// An interval for every minute. + everyMinute, + + /// Hourly interval. + hourly, + + /// Daily interval. + daily, + + /// Weekly interval. + weekly +} + +/// Used to specify how notifications should be scheduled on Android. +/// +/// This leverages the use of alarms to schedule notifications as described +/// at https://developer.android.com/training/scheduling/alarms +enum AndroidScheduleMode { + /// Used to specify that the notification should be scheduled to be shown at + /// the exact time specified AND will execute whilst device is in + /// low-power idle mode. Requires SCHEDULE_EXACT_ALARM permission. + alarmClock, + + /// Used to specify that the notification should be scheduled to be shown at + /// the exact time specified but may not execute whilst device is in + /// low-power idle mode. + exact, + + /// Used to specify that the notification should be scheduled to be shown at + /// the exact time specified and will execute whilst device is in + /// low-power idle mode. + exactAllowWhileIdle, + + /// Used to specify that the notification should be scheduled to be shown at + /// at roughly specified time but may not execute whilst device is in + /// low-power idle mode. + inexact, + + /// Used to specify that the notification should be scheduled to be shown at + /// at roughly specified time and will execute whilst device is in + /// low-power idle mode. + inexactAllowWhileIdle, +} + +/// The Android implementation of the plugin. +@HostApi() +abstract class AndroidNotificationsPlugin { + // ================== Common APIs ================== + + void cancel(int id); + void cancelAll(); + + NotificationAppLaunchDetails getNotificationAppLaunchDetails(); + PendingNotificationRequest pendingNotificationRequests(); + List getActiveNotifications(); + + // ================== Android-Specific ================== + void stopForegroundService(); + + bool initialize(); + bool? requestExactAlarmsPermission(); + bool? requestFullScreenIntentPermission(); + bool? requestNotificationsPermission(); + bool? areNotificationsEnabled(); + bool? canScheduleExactNotifications(); + + List? getNotificationChannels(); + + void createNotificationChannelGroup(AndroidNotificationChannelGroup notificationChannelGroup); + void deleteNotificationChannelGroup(String groupId); + void createNotificationChannel(AndroidNotificationChannel notificationChannel); + void deleteNotificationChannel(String channelId); + + void show(AndroidNotificationData data); + + void periodicallyShow({ + required AndroidNotificationData data, + required RepeatInterval repeatInterval, + required int calledAtMillisecondsSinceEpoch, + AndroidScheduleMode scheduleMode = AndroidScheduleMode.exact, + }); + + void periodicallyShowWithDuration({ + required AndroidNotificationData data, + required int calledAtMillisecondsSinceEpoch, + required int repeatIntervalMilliseconds, + }); + + void zonedSchedule({ + required AndroidNotificationData data, + required DateTimeWithTimezone scheduledDate, + DateTimeComponents? matchDateTimeComponents, + }); + + void startForegroundService({ + required AndroidNotificationData data, + AndroidServiceStartType startType = AndroidServiceStartType.startSticky, + List? foregroundServiceTypes, + }); + + MessagingStyleInformation? getActiveNotificationMessagingStyle({ + required int id, + String? tag, + }); +} diff --git a/flutter_local_notifications/pigeon/temp.dart b/flutter_local_notifications/pigeon/temp.dart deleted file mode 100644 index 53194dc7f..000000000 --- a/flutter_local_notifications/pigeon/temp.dart +++ /dev/null @@ -1,26 +0,0 @@ -@ConfigurePigeon(PigeonOptions( - dartPackageName: 'flutter_local_notifications', - dartOut: 'lib/src/android_messages.g.dart', - dartOptions: DartOptions(), - javaOptions: JavaOptions(), - javaOut: 'android/src/main/java/com/dexterous/flutterlocalnotifications/Messages.java', -)) -library; - -import 'package:pigeon/pigeon.dart'; - -class MyMessage { - const MyMessage({ - required this.name, - required this.repeats, - }); - - final String name; - final bool repeats; -} - -@HostApi() -abstract class MyApi { - void show(MyMessage message); - void cancelAll(); -} From 8f9d79e11a296400316d3adbde55474e7baa1237 Mon Sep 17 00:00:00 2001 From: Levi Lesches Date: Tue, 24 Dec 2024 14:14:06 -0500 Subject: [PATCH 4/9] Deleted obsolete Android code --- .../flutter_local_notifications_test.dart | 2 +- .../lib/flutter_local_notifications.dart | 20 +- .../flutter_local_notifications_plugin.dart | 2 +- .../lib/src/notification_details.dart | 2 +- .../platform_flutter_local_notifications.dart | 13 +- .../platform_specifics/android/bitmap.dart | 66 --- .../src/platform_specifics/android/enums.dart | 386 ---------------- .../src/platform_specifics/android/icon.dart | 108 ----- .../android/initialization_settings.dart | 8 - .../platform_specifics/android/message.dart | 41 -- .../android/method_channel_mappers.dart | 327 -------------- .../android/notification_channel.dart | 89 ---- .../android/notification_channel_group.dart | 20 - .../android/notification_details.dart | 411 ------------------ .../android/notification_sound.dart | 37 -- .../platform_specifics/android/person.dart | 32 -- .../android/schedule_mode.dart | 30 -- .../styles/big_picture_style_information.dart | 44 -- .../styles/big_text_style_information.dart | 40 -- .../styles/default_style_information.dart | 18 - .../styles/inbox_style_information.dart | 39 -- .../styles/media_style_information.dart | 14 - .../styles/messaging_style_information.dart | 29 -- .../android/styles/style_information.dart | 2 - .../pigeon/android.dart | 46 +- ...roid_flutter_local_notifications_test.dart | 26 +- 26 files changed, 41 insertions(+), 1811 deletions(-) delete mode 100644 flutter_local_notifications/lib/src/platform_specifics/android/bitmap.dart delete mode 100644 flutter_local_notifications/lib/src/platform_specifics/android/enums.dart delete mode 100644 flutter_local_notifications/lib/src/platform_specifics/android/icon.dart delete mode 100644 flutter_local_notifications/lib/src/platform_specifics/android/initialization_settings.dart delete mode 100644 flutter_local_notifications/lib/src/platform_specifics/android/message.dart delete mode 100644 flutter_local_notifications/lib/src/platform_specifics/android/method_channel_mappers.dart delete mode 100644 flutter_local_notifications/lib/src/platform_specifics/android/notification_channel.dart delete mode 100644 flutter_local_notifications/lib/src/platform_specifics/android/notification_channel_group.dart delete mode 100644 flutter_local_notifications/lib/src/platform_specifics/android/notification_details.dart delete mode 100644 flutter_local_notifications/lib/src/platform_specifics/android/notification_sound.dart delete mode 100644 flutter_local_notifications/lib/src/platform_specifics/android/person.dart delete mode 100644 flutter_local_notifications/lib/src/platform_specifics/android/schedule_mode.dart delete mode 100644 flutter_local_notifications/lib/src/platform_specifics/android/styles/big_picture_style_information.dart delete mode 100644 flutter_local_notifications/lib/src/platform_specifics/android/styles/big_text_style_information.dart delete mode 100644 flutter_local_notifications/lib/src/platform_specifics/android/styles/default_style_information.dart delete mode 100644 flutter_local_notifications/lib/src/platform_specifics/android/styles/inbox_style_information.dart delete mode 100644 flutter_local_notifications/lib/src/platform_specifics/android/styles/media_style_information.dart delete mode 100644 flutter_local_notifications/lib/src/platform_specifics/android/styles/messaging_style_information.dart delete mode 100644 flutter_local_notifications/lib/src/platform_specifics/android/styles/style_information.dart diff --git a/flutter_local_notifications/example/integration_test/flutter_local_notifications_test.dart b/flutter_local_notifications/example/integration_test/flutter_local_notifications_test.dart index a6b83b525..634f07e27 100644 --- a/flutter_local_notifications/example/integration_test/flutter_local_notifications_test.dart +++ b/flutter_local_notifications/example/integration_test/flutter_local_notifications_test.dart @@ -7,7 +7,7 @@ import 'package:integration_test/integration_test.dart'; void main() { IntegrationTestWidgetsFlutterBinding.ensureInitialized(); const AndroidInitializationSettings initializationSettingsAndroid = - AndroidInitializationSettings('app_icon'); + AndroidInitializationSettings(defaultIcon: 'app_icon'); const DarwinInitializationSettings initializationSettingsIOS = DarwinInitializationSettings(); const DarwinInitializationSettings initializationSettingsMacOS = diff --git a/flutter_local_notifications/lib/flutter_local_notifications.dart b/flutter_local_notifications/lib/flutter_local_notifications.dart index c42e2ff4c..ad2bec180 100644 --- a/flutter_local_notifications/lib/flutter_local_notifications.dart +++ b/flutter_local_notifications/lib/flutter_local_notifications.dart @@ -9,25 +9,7 @@ export 'src/initialization_settings.dart'; export 'src/notification_details.dart'; export 'src/platform_flutter_local_notifications.dart' hide MethodChannelFlutterLocalNotificationsPlugin; -export 'src/platform_specifics/android/bitmap.dart'; -export 'src/platform_specifics/android/enums.dart' - hide AndroidBitmapSource, AndroidIconSource, AndroidNotificationSoundSource; -export 'src/platform_specifics/android/icon.dart' hide AndroidIcon; -export 'src/platform_specifics/android/initialization_settings.dart'; -export 'src/platform_specifics/android/message.dart'; -export 'src/platform_specifics/android/notification_channel.dart'; -export 'src/platform_specifics/android/notification_channel_group.dart'; -export 'src/platform_specifics/android/notification_details.dart'; -export 'src/platform_specifics/android/notification_sound.dart'; -export 'src/platform_specifics/android/person.dart'; -export 'src/platform_specifics/android/schedule_mode.dart'; -export 'src/platform_specifics/android/styles/big_picture_style_information.dart'; -export 'src/platform_specifics/android/styles/big_text_style_information.dart'; -export 'src/platform_specifics/android/styles/default_style_information.dart'; -export 'src/platform_specifics/android/styles/inbox_style_information.dart'; -export 'src/platform_specifics/android/styles/media_style_information.dart'; -export 'src/platform_specifics/android/styles/messaging_style_information.dart'; -export 'src/platform_specifics/android/styles/style_information.dart'; +export 'src/platform_specifics/android.g.dart' hide AndroidIcon; export 'src/platform_specifics/darwin/initialization_settings.dart'; export 'src/platform_specifics/darwin/interruption_level.dart'; export 'src/platform_specifics/darwin/notification_action.dart'; diff --git a/flutter_local_notifications/lib/src/flutter_local_notifications_plugin.dart b/flutter_local_notifications/lib/src/flutter_local_notifications_plugin.dart index bc866a073..fa99d6513 100644 --- a/flutter_local_notifications/lib/src/flutter_local_notifications_plugin.dart +++ b/flutter_local_notifications/lib/src/flutter_local_notifications_plugin.dart @@ -9,7 +9,7 @@ import 'package:timezone/timezone.dart'; import 'initialization_settings.dart'; import 'notification_details.dart'; import 'platform_flutter_local_notifications.dart'; -import 'platform_specifics/android/schedule_mode.dart'; +import 'platform_specifics/android.g.dart'; import 'types.dart'; /// Provides cross-platform functionality for displaying local notifications. diff --git a/flutter_local_notifications/lib/src/notification_details.dart b/flutter_local_notifications/lib/src/notification_details.dart index 070b03ae1..2e21b19c0 100644 --- a/flutter_local_notifications/lib/src/notification_details.dart +++ b/flutter_local_notifications/lib/src/notification_details.dart @@ -1,7 +1,7 @@ import 'package:flutter_local_notifications_linux/flutter_local_notifications_linux.dart'; import 'package:flutter_local_notifications_windows/flutter_local_notifications_windows.dart'; -import 'platform_specifics/android/notification_details.dart'; +import 'platform_specifics/android.g.dart'; import 'platform_specifics/darwin/notification_details.dart'; /// Contains notification details specific to each platform. 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..759d18f01 100644 --- a/flutter_local_notifications/lib/src/platform_flutter_local_notifications.dart +++ b/flutter_local_notifications/lib/src/platform_flutter_local_notifications.dart @@ -8,18 +8,7 @@ import 'package:timezone/timezone.dart'; import 'callback_dispatcher.dart'; import 'helpers.dart'; -import 'platform_specifics/android/enums.dart'; -import 'platform_specifics/android/icon.dart'; -import 'platform_specifics/android/initialization_settings.dart'; -import 'platform_specifics/android/message.dart'; -import 'platform_specifics/android/method_channel_mappers.dart'; -import 'platform_specifics/android/notification_channel.dart'; -import 'platform_specifics/android/notification_channel_group.dart'; -import 'platform_specifics/android/notification_details.dart'; -import 'platform_specifics/android/notification_sound.dart'; -import 'platform_specifics/android/person.dart'; -import 'platform_specifics/android/schedule_mode.dart'; -import 'platform_specifics/android/styles/messaging_style_information.dart'; +import 'platform_specifics/android.g.dart'; import 'platform_specifics/darwin/initialization_settings.dart'; import 'platform_specifics/darwin/mappers.dart'; import 'platform_specifics/darwin/notification_details.dart'; diff --git a/flutter_local_notifications/lib/src/platform_specifics/android/bitmap.dart b/flutter_local_notifications/lib/src/platform_specifics/android/bitmap.dart deleted file mode 100644 index c769a6050..000000000 --- a/flutter_local_notifications/lib/src/platform_specifics/android/bitmap.dart +++ /dev/null @@ -1,66 +0,0 @@ -import 'dart:convert'; -import 'dart:typed_data'; - -import 'enums.dart'; - -/// Represents a bitmap on Android. -abstract class AndroidBitmap { - /// The location of the bitmap. - T get data; - - /// The subclass source type - AndroidBitmapSource get source; -} - -/// Represents a drawable resource belonging to the Android application that -/// should be used as a bitmap on Android. -class DrawableResourceAndroidBitmap implements AndroidBitmap { - /// Constructs an instance of [DrawableResourceAndroidBitmap]. - const DrawableResourceAndroidBitmap(this._bitmap); - - final String _bitmap; - - /// The name of the drawable resource. - /// - /// For example if the drawable resource is located at `res/drawable/app_icon.png`, the bitmap should be `app_icon` - @override - String get data => _bitmap; - - @override - AndroidBitmapSource get source => AndroidBitmapSource.drawable; -} - -/// Represents a file path that should be used for a bitmap on Android. -class FilePathAndroidBitmap implements AndroidBitmap { - /// Constructs an instance of [FilePathAndroidBitmap]. - const FilePathAndroidBitmap(this._bitmap); - - final String _bitmap; - - /// A file path on the Android device that refers to the location of the - /// bitmap. - @override - String get data => _bitmap; - - @override - AndroidBitmapSource get source => AndroidBitmapSource.filePath; -} - -/// Represents a base64 encoded AndroidBitmap. -class ByteArrayAndroidBitmap implements AndroidBitmap { - /// Constructs an instance of [ByteArrayAndroidBitmap]. - const ByteArrayAndroidBitmap(this._bitmap); - - /// Constructs an instance of [ByteArrayAndroidBitmap] from a base64 string. - factory ByteArrayAndroidBitmap.fromBase64String(String base64Image) => - ByteArrayAndroidBitmap(base64Decode(base64Image)); - - final Uint8List _bitmap; - - /// A base64 encoded Bitmap string. - @override - Uint8List get data => _bitmap; - - @override - AndroidBitmapSource get source => AndroidBitmapSource.byteArray; -} diff --git a/flutter_local_notifications/lib/src/platform_specifics/android/enums.dart b/flutter_local_notifications/lib/src/platform_specifics/android/enums.dart deleted file mode 100644 index 33deb3780..000000000 --- a/flutter_local_notifications/lib/src/platform_specifics/android/enums.dart +++ /dev/null @@ -1,386 +0,0 @@ -/// Specifies the source for a bitmap used by Android notifications. -enum AndroidBitmapSource { - /// A drawable. - drawable, - - /// A file path. - filePath, - - /// A byte array bitmap. - byteArray, -} - -/// Specifies the source for icons. -enum AndroidIconSource { - /// A drawable resource. - drawableResource, - - /// A file path to a bitmap. - bitmapFilePath, - - /// A content URI. - contentUri, - - /// A Flutter asset that is a bitmap. - flutterBitmapAsset, - - /// A byte array bitmap. - byteArray, -} - -/// The available notification styles on Android. -enum AndroidNotificationStyle { - /// The default style. - defaultStyle, - - /// The big picture style. - bigPicture, - - /// The big text style. - bigText, - - /// The inbox style. - inbox, - - /// The messaging style. - messaging, - - /// The media style. - media -} - -/// Specifies the source for a sound used by Android notifications. -enum AndroidNotificationSoundSource { - /// A raw resource. - rawResource, - - /// An URI to a file on the Android device. - uri, -} - -/// The available actions for managing notification channels. -enum AndroidNotificationChannelAction { - /// Create a channel if it doesn't exist. - createIfNotExists, - - /// Updates the details of an existing channel. Note that some details can - /// not be changed once a channel has been created. - update -} - -/// The available foreground types for an Android service. - -enum AndroidServiceForegroundType { - /// Corresponds to [`ServiceInfo.FOREGROUND_SERVICE_TYPE_MANIFEST`](https://developer.android.com/reference/android/content/pm/ServiceInfo#FOREGROUND_SERVICE_TYPE_MANIFEST). - foregroundServiceTypeManifest(-1), - - /// Corresponds to [`ServiceInfo.FOREGROUND_SERVICE_TYPE_NONE`](https://developer.android.com/reference/android/content/pm/ServiceInfo#FOREGROUND_SERVICE_TYPE_NONE). - foregroundServiceTypeNone(0), - - /// Corresponds to [`ServiceInfo.FOREGROUND_SERVICE_TYPE_DATA_SYNC`](https://developer.android.com/reference/android/content/pm/ServiceInfo#FOREGROUND_SERVICE_TYPE_DATA_SYNC). - foregroundServiceTypeDataSync(1), - - /// Corresponds to [`ServiceInfo.FOREGROUND_SERVICE_TYPE_MEDIA_PLAYBACK`](https://developer.android.com/reference/android/content/pm/ServiceInfo#FOREGROUND_SERVICE_TYPE_MEDIA_PLAYBACK). - foregroundServiceTypeMediaPlayback(2), - - /// Corresponds to [`ServiceInfo.FOREGROUND_SERVICE_TYPE_PHONE_CALL`](https://developer.android.com/reference/android/content/pm/ServiceInfo#FOREGROUND_SERVICE_TYPE_PHONE_CALL). - foregroundServiceTypePhoneCall(4), - - /// Corresponds to [`ServiceInfo.FOREGROUND_SERVICE_TYPE_LOCATION`](https://developer.android.com/reference/android/content/pm/ServiceInfo#FOREGROUND_SERVICE_TYPE_LOCATION). - foregroundServiceTypeLocation(8), - - /// Corresponds to [`ServiceInfo.FOREGROUND_SERVICE_TYPE_CONNECTED_DEVICE`](https://developer.android.com/reference/android/content/pm/ServiceInfo#FOREGROUND_SERVICE_TYPE_CONNECTED_DEVICE). - foregroundServiceTypeConnectedDevice(16), - - /// Corresponds to [`ServiceInfo.FOREGROUND_SERVICE_TYPE_MEDIA_PROJECTION`](https://developer.android.com/reference/android/content/pm/ServiceInfo#FOREGROUND_SERVICE_TYPE_MEDIA_PROJECTION). - foregroundServiceTypeMediaProjection(32), - - /// Corresponds to [`ServiceInfo.FOREGROUND_SERVICE_TYPE_CAMERA`](https://developer.android.com/reference/android/content/pm/ServiceInfo#FOREGROUND_SERVICE_TYPE_CAMERA). - foregroundServiceTypeCamera(64), - - /// Corresponds to [`ServiceInfo.FOREGROUND_SERVICE_TYPE_MICROPHONE`](https://developer.android.com/reference/android/content/pm/ServiceInfo#FOREGROUND_SERVICE_TYPE_MICROPHONE). - foregroundServiceTypeMicrophone(128), - - /// Corresponds to [`ServiceInfo.FOREGROUND_SERVICE_TYPE_HEALTH`](https://developer.android.com/reference/android/content/pm/ServiceInfo#FOREGROUND_SERVICE_TYPE_HEALTH). - foregroundServiceTypeHealth(256), - - /// Corresponds to [`ServiceInfo.FOREGROUND_SERVICE_TYPE_REMOTE_MESSAGING`](https://developer.android.com/reference/android/content/pm/ServiceInfo#FOREGROUND_SERVICE_TYPE_REMOTE_MESSAGING). - - foregroundServiceTypeRemoteMessaging(512), - - /// Corresponds to [`ServiceInfo.FOREGROUND_SERVICE_TYPE_SYSTEM_EXEMPTED`](https://developer.android.com/reference/android/content/pm/ServiceInfo#FOREGROUND_SERVICE_TYPE_SYSTEM_EXEMPTED). - foregroundServiceTypeSystemExempted(1024), - - /// Corresponds to [`ServiceInfo.FOREGROUND_SERVICE_TYPE_SHORT_SERVICE`](https://developer.android.com/reference/android/content/pm/ServiceInfo#FOREGROUND_SERVICE_TYPE_SHORT_SERVICE). - foregroundServiceTypeShortService(2048), - - /// Corresponds to [`ServiceInfo.FOREGROUND_SERVICE_TYPE_SPECIAL_USE`](https://developer.android.com/reference/android/content/pm/ServiceInfo#FOREGROUND_SERVICE_TYPE_SPECIAL_USE). - foregroundServiceTypeSpecialUse(1073741824); - - /// Constructs an instance of [AndroidServiceForegroundType]. - const AndroidServiceForegroundType(this.value); - - /// The integer representation of [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. -enum Importance { - /// Corresponds to [`NotificationManagerCompat.IMPORTANCE_UNSPECIFIED`](https://developer.android.com/reference/androidx/core/app/NotificationManagerCompat#IMPORTANCE_UNSPECIFIED()). - unspecified(-1000), - - /// Corresponds to [`NotificationManagerCompat.IMPORTANCE_NONE](https://developer.android.com/reference/androidx/core/app/NotificationManagerCompat#IMPORTANCE_NONE()). - none(0), - - /// Corresponds to [`NotificationManagerCompat.IMPORTANCE_MIN`](https://developer.android.com/reference/androidx/core/app/NotificationManagerCompat#IMPORTANCE_MIN()). - min(1), - - /// Corresponds to [`NotificationManagerCompat#IMPORTANCE_LOW`](https://developer.android.com/reference/androidx/core/app/NotificationManagerCompat#IMPORTANCE_LOW()). - low(2), - - /// Corresponds to [`NotificationManagerCompat.IMPORTANCE_DEFAULT](https://developer.android.com/reference/androidx/core/app/NotificationManagerCompat#IMPORTANCE_DEFAULT()). - defaultImportance(3), - - /// Corresponds to [`NotificationManagerCompat.IMPORTANCE_HIGH`](https://developer.android.com/reference/androidx/core/app/NotificationManagerCompat#IMPORTANCE_HIGH()). - high(4), - - /// Corresponds to [`NotificationManagerCompat.IMPORTANCE_MAX](https://developer.android.com/reference/androidx/core/app/NotificationManagerCompat#IMPORTANCE_MAX()). - max(5); - - /// Constructs an instance of [Importance]. - const Importance(this.value); - - /// The integer representation of [Importance]. - final int value; -} - -/// Priority for notifications on Android 7.1 and lower. -enum Priority { - /// Corresponds to [`NotificationCompat.PRIORITY_MIN`](https://developer.android.com/reference/androidx/core/app/NotificationCompat#PRIORITY_MIN()). - min(-2), - - /// Corresponds to [`NotificationCompat.PRIORITY_LOW()`](https://developer.android.com/reference/androidx/core/app/NotificationCompat#PRIORITY_LOW()). - low(-1), - - /// Corresponds to [`NotificationCompat.PRIORITY_DEFAULT`](https://developer.android.com/reference/androidx/core/app/NotificationCompat#PRIORITY_DEFAULT()). - defaultPriority(0), - - /// Corresponds to [`NotificationCompat.PRIORITY_HIGH`](https://developer.android.com/reference/androidx/core/app/NotificationCompat#PRIORITY_HIGH()). - high(1), - - /// Corresponds to [`NotificationCompat.PRIORITY_MAX`](https://developer.android.com/reference/androidx/core/app/NotificationCompat#PRIORITY_MAX()). - max(2); - - /// Constructs an instance of [Priority]. - const Priority(this.value); - - /// The integer representation of [Priority]. - final int value; -} - -/// The available alert behaviours for grouped notifications. -enum GroupAlertBehavior { - /// All notifications in a group with sound or vibration ought to make - /// sound or vibrate. - all, - - /// All children notification in a group should be silenced - summary, - - /// The summary notification in a group should be silenced. - children -} - -/// Defines the notification visibility on the lockscreen. -enum NotificationVisibility { - /// Show this notification on all lockscreens, but conceal sensitive - /// or private information on secure lockscreens. - private, - - /// Show this notification in its entirety on all lockscreens. - public, - - /// Do not reveal any part of this notification on a secure lockscreen. - secret, -} - -/// The available audio attributes usages for an Android service. -enum AudioAttributesUsage { - /// Corresponds to [`AudioAttributes.USAGE_ALARM`](https://developer.android.com/reference/android/media/AudioAttributes#USAGE_ALARM). - alarm(4), - - /// Corresponds to [`AudioAttributes.USAGE_ASSISTANCE_ACCESSIBILITY`](https://developer.android.com/reference/android/media/AudioAttributes#USAGE_ASSISTANCE_ACCESSIBILITY). - assistanceAccessibility(11), - - /// Corresponds to [`AudioAttributes.USAGE_ASSISTANCE_NAVIGATION_GUIDANCE`](https://developer.android.com/reference/android/media/AudioAttributes#USAGE_ASSISTANCE_NAVIGATION_GUIDANCE). - assistanceNavigationGuidance(12), - - /// Corresponds to [`AudioAttributes.USAGE_ASSISTANCE_SONIFICATION`](https://developer.android.com/reference/android/media/AudioAttributes#USAGE_ASSISTANCE_SONIFICATION). - assistanceSonification(13), - - /// Corresponds to [`AudioAttributes.USAGE_ASSISTANT`](https://developer.android.com/reference/android/media/AudioAttributes#USAGE_ASSISTANT). - assistant(16), - - /// Corresponds to [`AudioAttributes.USAGE_GAME`](https://developer.android.com/reference/android/media/AudioAttributes#USAGE_GAME). - game(14), - - /// Corresponds to [`AudioAttributes.USAGE_MEDIA`](https://developer.android.com/reference/android/media/AudioAttributes#USAGE_MEDIA). - media(1), - - /// Corresponds to [`AudioAttributes.USAGE_NOTIFICATION`](https://developer.android.com/reference/android/media/AudioAttributes#USAGE_NOTIFICATION). - notification(5), - - /// Corresponds to [`AudioAttributes.USAGE_NOTIFICATION_EVENT`](https://developer.android.com/reference/android/media/AudioAttributes#USAGE_NOTIFICATION_EVENT). - notificationEvent(10), - - /// Corresponds to [`AudioAttributes.USAGE_NOTIFICATION_RINGTONE`](https://developer.android.com/reference/android/media/AudioAttributes#USAGE_NOTIFICATION_RINGTONE). - notificationRingtone(6), - - /// Corresponds to [`AudioAttributes.USAGE_UNKNOWN`](https://developer.android.com/reference/android/media/AudioAttributes#USAGE_UNKNOWN). - unknown(0), - - /// Corresponds to [`AudioAttributes.USAGE_VOICE_COMMUNICATION`](https://developer.android.com/reference/android/media/AudioAttributes#USAGE_VOICE_COMMUNICATION). - voiceCommunication(2), - - /// Corresponds to [`AudioAttributes.USAGE_VOICE_COMMUNICATION_SIGNALLING`](https://developer.android.com/reference/android/media/AudioAttributes#USAGE_VOICE_COMMUNICATION_SIGNALLING). - voiceCommunicationSignalling(3); - - /// Constructs an instance of [AudioAttributesUsage]. - const AudioAttributesUsage(this.value); - - /// The integer representation of [AudioAttributesUsage]. - final int value; -} - -/// The available categories for Android notifications. -enum AndroidNotificationCategory { - /// Alarm or timer. - /// - /// Corresponds to [`NotificationCompat.CATEGORY_ALARM`](https://developer.android.com/reference/androidx/core/app/NotificationCompat#CATEGORY_ALARM%28%29). - alarm('alarm'), - - /// Incoming call (voice or video) or similar - /// synchronous communication request. - /// - /// Corresponds to [`NotificationCompat.CATEGORY_CALL`](https://developer.android.com/reference/androidx/core/app/NotificationCompat#CATEGORY_CALL%28%29). - call('call'), - - /// Asynchronous bulk message (email). - /// - /// Corresponds to [`NotificationCompat.CATEGORY_EMAIL`](https://developer.android.com/reference/androidx/core/app/NotificationCompat#CATEGORY_EMAIL%28%29). - email('email'), - - /// Error in background operation or authentication status. - /// - /// Corresponds to [`NotificationCompat.CATEGORY_ERROR`](https://developer.android.com/reference/androidx/core/app/NotificationCompat#CATEGORY_ERROR%28%29). - error('err'), - - /// Calendar event. - /// - /// Corresponds to [`NotificationCompat.CATEGORY_EVENT`](https://developer.android.com/reference/androidx/core/app/NotificationCompat#CATEGORY_EVENT%28%29). - event('event'), - - /// Temporarily sharing location. - /// - /// Corresponds to [`NotificationCompat.CATEGORY_LOCATION_SHARING`](https://developer.android.com/reference/androidx/core/app/NotificationCompat#CATEGORY_LOCATION_SHARING%28%29). - locationSharing('location_sharing'), - - /// Incoming direct message like SMS and instant message. - /// - /// Corresponds to [`NotificationCompat.CATEGORY_MESSAGE`](https://developer.android.com/reference/androidx/core/app/NotificationCompat#CATEGORY_MESSAGE%28%29). - message('msg'), - - /// Missed call. - /// - /// Corresponds to [`NotificationCompat.CATEGORY_MISSED_CALL`](https://developer.android.com/reference/androidx/core/app/NotificationCompat#CATEGORY_MISSED_CALL%28%29). - missedCall('missed_call'), - - /// Map turn-by-turn navigation. - /// - /// Corresponds to [`NotificationCompat.CATEGORY_NAVIGATION`](https://developer.android.com/reference/androidx/core/app/NotificationCompat#CATEGORY_NAVIGATION%28%29). - navigation('navigation'), - - /// Progress of a long-running background operation. - /// - /// Corresponds to [`NotificationCompat.CATEGORY_PROGRESS`](https://developer.android.com/reference/androidx/core/app/NotificationCompat#CATEGORY_PROGRESS%28%29). - progress('progress'), - - /// Promotion or advertisement. - /// - /// Corresponds to [`NotificationCompat.CATEGORY_PROMO`](https://developer.android.com/reference/androidx/core/app/NotificationCompat#CATEGORY_PROMO%28%29). - promo('promo'), - - /// A specific, timely recommendation for a single thing. - /// - /// For example, a news app might want to recommend a - /// news story it believes the user will want to read next. - /// - /// Corresponds to [`NotificationCompat.CATEGORY_RECOMMENDATION`](https://developer.android.com/reference/androidx/core/app/NotificationCompat#CATEGORY_RECOMMENDATION%28%29). - recommendation('recommendation'), - - /// User-scheduled reminder. - /// - /// Corresponds to [`NotificationCompat.CATEGORY_REMINDER`](https://developer.android.com/reference/androidx/core/app/NotificationCompat#CATEGORY_REMINDER%28%29). - reminder('reminder'), - - /// Indication of running background service. - /// - /// Corresponds to [`NotificationCompat.CATEGORY_SERVICE`](https://developer.android.com/reference/androidx/core/app/NotificationCompat#CATEGORY_SERVICE%28%29). - service('service'), - - /// Social network or sharing update. - /// - /// Corresponds to [`NotificationCompat.CATEGORY_SOCIAL`](https://developer.android.com/reference/androidx/core/app/NotificationCompat#CATEGORY_SOCIAL%28%29). - social('social'), - - /// Ongoing information about device or contextual status. - /// - /// Corresponds to [`NotificationCompat.CATEGORY_STATUS`](https://developer.android.com/reference/androidx/core/app/NotificationCompat#CATEGORY_STATUS%28%29). - status('status'), - - /// Running stopwatch. - /// - /// Corresponds to [`NotificationCompat.CATEGORY_STOPWATCH`](https://developer.android.com/reference/androidx/core/app/NotificationCompat#CATEGORY_STOPWATCH%28%29). - stopwatch('stopwatch'), - - /// System or device status update. - /// - /// Reserved for system use. - /// - /// Corresponds to [`NotificationCompat.CATEGORY_SYSTEM`](https://developer.android.com/reference/androidx/core/app/NotificationCompat#CATEGORY_SYSTEM%28%29). - system('sys'), - - /// Media transport control for playback. - /// - /// Corresponds to [`NotificationCompat.CATEGORY_TRANSPORT`](https://developer.android.com/reference/androidx/core/app/NotificationCompat#CATEGORY_TRANSPORT%28%29). - transport('transport'), - - /// Tracking a user's workout. - /// - /// Corresponds to [`NotificationCompat.CATEGORY_WORKOUT`](https://developer.android.com/reference/androidx/core/app/NotificationCompat#CATEGORY_WORKOUT%28%29). - workout('workout'); - - /// Constructs an instance of [AndroidNotificationCategory] - /// with a given [name] of category. - const AndroidNotificationCategory(this.name); - - /// The name of category. - final String name; -} diff --git a/flutter_local_notifications/lib/src/platform_specifics/android/icon.dart b/flutter_local_notifications/lib/src/platform_specifics/android/icon.dart deleted file mode 100644 index 25f66fa9e..000000000 --- a/flutter_local_notifications/lib/src/platform_specifics/android/icon.dart +++ /dev/null @@ -1,108 +0,0 @@ -import 'dart:convert'; -import 'dart:typed_data'; - -import 'enums.dart'; - -/// Represents an icon on Android. -abstract class AndroidIcon { - /// The location to the icon; - T get data; - - /// The subclass source type - AndroidIconSource get source; -} - -/// Represents a drawable resource belonging to the Android application that -/// should be used as an icon on Android. -class DrawableResourceAndroidIcon implements AndroidIcon { - /// Constructs an instance of [DrawableResourceAndroidIcon]. - const DrawableResourceAndroidIcon(this._icon); - - final String _icon; - - /// The name of the drawable resource. - /// - /// For example if the drawable resource is located at `res/drawable/app_icon.png`, the icon should be `app_icon` - @override - String get data => _icon; - - @override - AndroidIconSource get source => AndroidIconSource.drawableResource; -} - -/// Represents a file path to a bitmap that should be used for as an icon on -/// Android. -class BitmapFilePathAndroidIcon implements AndroidIcon { - /// Constructs an instance of [BitmapFilePathAndroidIcon]. - const BitmapFilePathAndroidIcon(this._icon); - - final String _icon; - - /// A file path on the Android device that refers to the location of the icon. - @override - String get data => _icon; - - @override - AndroidIconSource get source => AndroidIconSource.bitmapFilePath; -} - -/// Represents a content URI that should be used for as an icon on Android. -class ContentUriAndroidIcon implements AndroidIcon { - /// Constructs an instance of [ContentUriAndroidIcon]. - const ContentUriAndroidIcon(this._icon); - - final String _icon; - - /// A content URI that refers to the location of the icon. - @override - String get data => _icon; - - @override - AndroidIconSource get source => AndroidIconSource.contentUri; -} - -/// Represents a bitmap asset belonging to the Flutter application that should -/// be used for as an icon on Android. -class FlutterBitmapAssetAndroidIcon implements AndroidIcon { - /// Constructs an instance of [FlutterBitmapAssetAndroidIcon]. - const FlutterBitmapAssetAndroidIcon(this._icon); - - final String _icon; - - /// Path to the Flutter asset that refers to the location of the icon. - /// - /// For example, if the following asset is declared in the Flutter - /// application's `pubspec.yaml` file - /// - /// ``` - /// assets: - /// - icons/coworker.png - /// ``` - /// - /// then the path to the asset would be `icons/coworker.png`. - @override - String get data => _icon; - - @override - AndroidIconSource get source => AndroidIconSource.flutterBitmapAsset; -} - -/// Represents a bitmap asset belonging to the Flutter application that should -/// be used for as an icon on Android. -class ByteArrayAndroidIcon implements AndroidIcon { - /// Constructs an instance of [FlutterBitmapAssetAndroidIcon]. - const ByteArrayAndroidIcon(this._icon); - - /// Constructs an instance of [ByteArrayAndroidIcon] from a base64 string. - factory ByteArrayAndroidIcon.fromBase64String(String base64Image) => - ByteArrayAndroidIcon(base64Decode(base64Image)); - - final Uint8List _icon; - - /// Byte array data of the icon. - @override - Uint8List get data => _icon; - - @override - AndroidIconSource get source => AndroidIconSource.byteArray; -} diff --git a/flutter_local_notifications/lib/src/platform_specifics/android/initialization_settings.dart b/flutter_local_notifications/lib/src/platform_specifics/android/initialization_settings.dart deleted file mode 100644 index f451264d1..000000000 --- a/flutter_local_notifications/lib/src/platform_specifics/android/initialization_settings.dart +++ /dev/null @@ -1,8 +0,0 @@ -/// Plugin initialization settings for Android. -class AndroidInitializationSettings { - /// Constructs an instance of [AndroidInitializationSettings]. - const AndroidInitializationSettings(this.defaultIcon); - - /// Specifies the default icon for notifications. - final String defaultIcon; -} diff --git a/flutter_local_notifications/lib/src/platform_specifics/android/message.dart b/flutter_local_notifications/lib/src/platform_specifics/android/message.dart deleted file mode 100644 index 4d42e2c49..000000000 --- a/flutter_local_notifications/lib/src/platform_specifics/android/message.dart +++ /dev/null @@ -1,41 +0,0 @@ -import 'person.dart'; - -/// Represents a message used in Android messaging style notifications. -class Message { - /// Constructs an instance of [Message]. - const Message( - this.text, - this.timestamp, - this.person, { - this.dataMimeType, - this.dataUri, - }) : assert( - (dataMimeType == null && dataUri == null) || - (dataMimeType != null && dataUri != null), - 'Must provide both dataMimeType and dataUri together or not at all.', - ); - - /// The message text - final String text; - - /// Time at which the message arrived. - /// - /// Note that this is eventually converted to milliseconds since epoch as - /// required by Android. - final DateTime timestamp; - - /// Person that sent this message. - /// - /// When this is set to `null` the `Person` given to - /// [MessagingStyleInformation.person] i.e. this would indicate that the - /// message was sent from the user. - final Person? person; - - /// MIME type for this message context when the [dataUri] is provided. - final String? dataMimeType; - - /// Uri containing the content. - /// - /// The original text will be used if the content or MIME type isn't supported - final String? dataUri; -} diff --git a/flutter_local_notifications/lib/src/platform_specifics/android/method_channel_mappers.dart b/flutter_local_notifications/lib/src/platform_specifics/android/method_channel_mappers.dart deleted file mode 100644 index cc1fa1994..000000000 --- a/flutter_local_notifications/lib/src/platform_specifics/android/method_channel_mappers.dart +++ /dev/null @@ -1,327 +0,0 @@ -import 'enums.dart'; -import 'initialization_settings.dart'; -import 'message.dart'; -import 'notification_channel.dart'; -import 'notification_channel_group.dart'; -import 'notification_details.dart'; -import 'notification_sound.dart'; -import 'person.dart'; -import 'styles/big_picture_style_information.dart'; -import 'styles/big_text_style_information.dart'; -import 'styles/default_style_information.dart'; -import 'styles/inbox_style_information.dart'; -import 'styles/media_style_information.dart'; -import 'styles/messaging_style_information.dart'; - -// ignore_for_file: avoid_as, public_member_api_docs -extension AndroidInitializationSettingsMapper on AndroidInitializationSettings { - Map toMap() => {'defaultIcon': defaultIcon}; -} - -extension MessageMapper on Message { - Map toMap() => { - 'text': text, - 'timestamp': timestamp.millisecondsSinceEpoch, - 'person': person?.toMap(), - 'dataMimeType': dataMimeType, - 'dataUri': dataUri - }; -} - -extension AndroidNotificationChannelGroupMapper - on AndroidNotificationChannelGroup { - Map toMap() => { - 'id': id, - 'name': name, - 'description': description, - }; -} - -extension AndroidNotificationChannelMapper on AndroidNotificationChannel { - Map toMap() => { - 'id': id, - 'name': name, - 'description': description, - 'groupId': groupId, - 'showBadge': showBadge, - 'importance': importance.value, - 'playSound': playSound, - 'enableVibration': enableVibration, - 'vibrationPattern': vibrationPattern, - 'enableLights': enableLights, - 'ledColorAlpha': ledColor?.alpha, - 'ledColorRed': ledColor?.red, - 'ledColorGreen': ledColor?.green, - 'ledColorBlue': ledColor?.blue, - 'audioAttributesUsage': audioAttributesUsage.value, - 'channelAction': - AndroidNotificationChannelAction.createIfNotExists.index, - }..addAll(_convertNotificationSoundToMap(sound)); -} - -Map _convertNotificationSoundToMap( - AndroidNotificationSound? sound) { - if (sound is RawResourceAndroidNotificationSound) { - return { - 'sound': sound.sound, - 'soundSource': AndroidNotificationSoundSource.rawResource.index, - }; - } else if (sound is UriAndroidNotificationSound) { - return { - 'sound': sound.sound, - 'soundSource': AndroidNotificationSoundSource.uri.index, - }; - } else { - return {}; - } -} - -extension PersonMapper on Person { - Map toMap() => { - 'bot': bot, - 'important': important, - 'key': key, - 'name': name, - 'uri': uri - }..addAll(_convertIconToMap()); - - Map _convertIconToMap() { - if (icon == null) { - return {}; - } - return { - 'icon': icon!.data, - 'iconSource': icon!.source.index, - }; - } -} - -extension DefaultStyleInformationMapper on DefaultStyleInformation { - Map toMap() => _convertDefaultStyleInformationToMap(this); -} - -Map _convertDefaultStyleInformationToMap( - DefaultStyleInformation styleInformation) => - { - 'htmlFormatContent': styleInformation.htmlFormatContent, - 'htmlFormatTitle': styleInformation.htmlFormatTitle - }; - -extension BigPictureStyleInformationMapper on BigPictureStyleInformation { - Map toMap() => _convertDefaultStyleInformationToMap(this) - ..addAll(_convertBigPictureToMap()) - ..addAll(_convertLargeIconToMap()) - ..addAll({ - 'contentTitle': contentTitle, - 'summaryText': summaryText, - 'htmlFormatContentTitle': htmlFormatContentTitle, - 'htmlFormatSummaryText': htmlFormatSummaryText, - 'hideExpandedLargeIcon': hideExpandedLargeIcon - }); - - Map _convertBigPictureToMap() => { - 'bigPicture': bigPicture.data, - 'bigPictureBitmapSource': bigPicture.source.index, - }; - - Map _convertLargeIconToMap() { - if (largeIcon == null) { - return {}; - } - return { - 'largeIcon': largeIcon!.data, - 'largeIconBitmapSource': largeIcon!.source.index, - }; - } -} - -extension BigTexStyleInformationMapper on BigTextStyleInformation { - Map toMap() => _convertDefaultStyleInformationToMap(this) - ..addAll({ - 'bigText': bigText, - 'htmlFormatBigText': htmlFormatBigText, - 'contentTitle': contentTitle, - 'htmlFormatContentTitle': htmlFormatContentTitle, - 'summaryText': summaryText, - 'htmlFormatSummaryText': htmlFormatSummaryText - }); -} - -extension InboxStyleInformationMapper on InboxStyleInformation { - Map toMap() => _convertDefaultStyleInformationToMap(this) - ..addAll({ - 'contentTitle': contentTitle, - 'htmlFormatContentTitle': htmlFormatContentTitle, - 'summaryText': summaryText, - 'htmlFormatSummaryText': htmlFormatSummaryText, - 'lines': lines, - 'htmlFormatLines': htmlFormatLines - }); -} - -extension MessagingStyleInformationMapper on MessagingStyleInformation { - Map toMap() => _convertDefaultStyleInformationToMap(this) - ..addAll({ - 'person': person.toMap(), - 'conversationTitle': conversationTitle, - 'groupConversation': groupConversation, - 'messages': messages - ?.map((m) => m.toMap()) // ignore: always_specify_types - .toList() - }); -} - -extension AndroidNotificationDetailsMapper on AndroidNotificationDetails { - Map toMap() => { - 'icon': icon, - 'channelId': channelId, - 'channelName': channelName, - 'channelDescription': channelDescription, - 'channelShowBadge': channelShowBadge, - 'channelAction': channelAction.index, - 'importance': importance.value, - 'priority': priority.value, - 'playSound': playSound, - 'enableVibration': enableVibration, - 'vibrationPattern': vibrationPattern, - 'groupKey': groupKey, - 'setAsGroupSummary': setAsGroupSummary, - 'groupAlertBehavior': groupAlertBehavior.index, - 'autoCancel': autoCancel, - 'ongoing': ongoing, - 'silent': silent, - 'colorAlpha': color?.alpha, - 'colorRed': color?.red, - 'colorGreen': color?.green, - 'colorBlue': color?.blue, - 'onlyAlertOnce': onlyAlertOnce, - 'showWhen': showWhen, - 'when': when, - 'usesChronometer': usesChronometer, - 'chronometerCountDown': chronometerCountDown, - 'showProgress': showProgress, - 'maxProgress': maxProgress, - 'progress': progress, - 'indeterminate': indeterminate, - 'enableLights': enableLights, - 'ledColorAlpha': ledColor?.alpha, - 'ledColorRed': ledColor?.red, - 'ledColorGreen': ledColor?.green, - 'ledColorBlue': ledColor?.blue, - 'ledOnMs': ledOnMs, - 'ledOffMs': ledOffMs, - 'ticker': ticker, - 'visibility': visibility?.index, - 'timeoutAfter': timeoutAfter, - 'category': category?.name, - 'fullScreenIntent': fullScreenIntent, - 'shortcutId': shortcutId, - 'additionalFlags': additionalFlags, - 'subText': subText, - 'tag': tag, - 'colorized': colorized, - 'number': number, - 'audioAttributesUsage': audioAttributesUsage.value, - } - ..addAll(_convertActionsToMap(actions)) - ..addAll(_convertStyleInformationToMap()) - ..addAll(_convertNotificationSoundToMap(sound)) - ..addAll(_convertLargeIconToMap()); - - Map _convertStyleInformationToMap() { - if (styleInformation is BigPictureStyleInformation) { - return { - 'style': AndroidNotificationStyle.bigPicture.index, - 'styleInformation': - (styleInformation as BigPictureStyleInformation?)?.toMap(), - }; - } else if (styleInformation is BigTextStyleInformation) { - return { - 'style': AndroidNotificationStyle.bigText.index, - 'styleInformation': - (styleInformation as BigTextStyleInformation?)?.toMap(), - }; - } else if (styleInformation is InboxStyleInformation) { - return { - 'style': AndroidNotificationStyle.inbox.index, - 'styleInformation': - (styleInformation as InboxStyleInformation?)?.toMap(), - }; - } else if (styleInformation is MessagingStyleInformation) { - return { - 'style': AndroidNotificationStyle.messaging.index, - 'styleInformation': - (styleInformation as MessagingStyleInformation?)?.toMap(), - }; - } else if (styleInformation is MediaStyleInformation) { - return { - 'style': AndroidNotificationStyle.media.index, - 'styleInformation': - (styleInformation as MediaStyleInformation?)?.toMap(), - }; - } else if (styleInformation is DefaultStyleInformation) { - return { - 'style': AndroidNotificationStyle.defaultStyle.index, - 'styleInformation': - (styleInformation as DefaultStyleInformation?)?.toMap(), - }; - } else { - return { - 'style': AndroidNotificationStyle.defaultStyle.index, - 'styleInformation': const DefaultStyleInformation(false, false).toMap(), - }; - } - } - - Map _convertLargeIconToMap() { - if (largeIcon == null) { - return {}; - } - return { - 'largeIcon': largeIcon!.data, - 'largeIconBitmapSource': largeIcon!.source.index, - }; - } - - Map _convertActionsToMap( - List? actions) { - if (actions == null) { - return {}; - } - return { - 'actions': actions - .map( - (AndroidNotificationAction e) => { - 'id': e.id, - 'title': e.title, - 'titleColorAlpha': e.titleColor?.alpha, - 'titleColorRed': e.titleColor?.red, - 'titleColorGreen': e.titleColor?.green, - 'titleColorBlue': e.titleColor?.blue, - if (e.icon != null) ...{ - 'icon': e.icon!.data, - 'iconBitmapSource': e.icon!.source.index, - }, - 'contextual': e.contextual, - 'showsUserInterface': e.showsUserInterface, - 'allowGeneratedReplies': e.allowGeneratedReplies, - 'inputs': e.inputs - .map((AndroidNotificationActionInput input) => - _convertInputToMap(input)) - .toList(), - 'cancelNotification': e.cancelNotification, - }, - ) - .toList(), - }; - } - - Map _convertInputToMap( - AndroidNotificationActionInput input) => - { - 'choices': input.choices, - 'allowFreeFormInput': input.allowFreeFormInput, - 'label': input.label, - 'allowedMimeType': input.allowedMimeTypes.toList(), - }; -} diff --git a/flutter_local_notifications/lib/src/platform_specifics/android/notification_channel.dart b/flutter_local_notifications/lib/src/platform_specifics/android/notification_channel.dart deleted file mode 100644 index a240d8c86..000000000 --- a/flutter_local_notifications/lib/src/platform_specifics/android/notification_channel.dart +++ /dev/null @@ -1,89 +0,0 @@ -import 'dart:typed_data'; -import 'dart:ui'; - -import 'enums.dart'; -import 'notification_sound.dart'; - -/// Settings for Android notification channels. -class AndroidNotificationChannel { - /// Constructs an instance of [AndroidNotificationChannel]. - const AndroidNotificationChannel( - this.id, - this.name, { - this.description, - this.groupId, - this.importance = Importance.defaultImportance, - this.playSound = true, - this.sound, - this.enableVibration = true, - this.vibrationPattern, - this.showBadge = true, - this.enableLights = false, - this.ledColor, - this.audioAttributesUsage = AudioAttributesUsage.notification, - }); - - /// The channel's id. - final String id; - - /// The channel's name. - final String name; - - /// The channel's description. - final String? description; - - /// The id of the group that the channel belongs to. - final String? groupId; - - /// The importance of the notification. - final Importance importance; - - /// Indicates if a sound should be played when the notification is displayed. - /// - /// Tied to the specified channel and cannot be changed after the channel has - /// been created for the first time. - final bool playSound; - - /// The sound to play for the notification. - /// - /// Requires setting [playSound] to true for it to work. - /// If [playSound] is set to true but this is not specified then the default - /// sound is played. Tied to the specified channel and cannot be changed - /// after the channel has been created for the first time. - final AndroidNotificationSound? sound; - - /// Indicates if vibration should be enabled when the notification is - /// displayed. - // - /// Tied to the specified channel and cannot be changed after the channel has - /// been created for the first time. - final bool enableVibration; - - /// Indicates if lights should be enabled when the notification is displayed. - /// - /// Tied to the specified channel and cannot be changed after the channel has - /// been created for the first time. - final bool enableLights; - - /// Configures the vibration pattern. - /// - /// Requires setting [enableVibration] to true for it to work. - /// Tied to the specified channel and cannot be changed after the channel has - /// been created for the first time. - final Int64List? vibrationPattern; - - /// Specifies the light color of the notification. - /// - /// Tied to the specified channel and cannot be changed after the channel has - /// been created for the first time. - final Color? ledColor; - - /// Whether notifications posted to this channel can appear as application - /// icon badges in a Launcher - final bool showBadge; - - /// The attribute describing what is the intended use of the audio signal, - /// such as alarm or ringtone set in [`AudioAttributes.Builder`](https://developer.android.com/reference/android/media/AudioAttributes.Builder#setUsage(int)) - /// https://developer.android.com/reference/android/media/AudioAttributes - final AudioAttributesUsage audioAttributesUsage; -} diff --git a/flutter_local_notifications/lib/src/platform_specifics/android/notification_channel_group.dart b/flutter_local_notifications/lib/src/platform_specifics/android/notification_channel_group.dart deleted file mode 100644 index 7a0559e71..000000000 --- a/flutter_local_notifications/lib/src/platform_specifics/android/notification_channel_group.dart +++ /dev/null @@ -1,20 +0,0 @@ -/// A group of related Android notification channels. -class AndroidNotificationChannelGroup { - /// Constructs an instance of [AndroidNotificationChannelGroup]. - const AndroidNotificationChannelGroup( - this.id, - this.name, { - this.description, - }); - - /// The id of this group. - final String id; - - /// The name of this group. - final String name; - - /// The description of this group. - /// - /// Only applicable to Android 9.0 or newer. - final String? description; -} 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 deleted file mode 100644 index c3a23f1d2..000000000 --- a/flutter_local_notifications/lib/src/platform_specifics/android/notification_details.dart +++ /dev/null @@ -1,411 +0,0 @@ -import 'dart:typed_data'; -import 'dart:ui'; - -import 'bitmap.dart'; -import 'enums.dart'; -import 'notification_sound.dart'; -import 'styles/style_information.dart'; - -/// Mirrors the `RemoteInput` functionality available in NotificationCompat. -/// -/// See the official docs at -/// https://developer.android.com/reference/kotlin/androidx/core/app/RemoteInput?hl=en -/// for details. -class AndroidNotificationActionInput { - /// Constructs a [AndroidNotificationActionInput]. The platform will create - /// this object using `RemoteInput.Builder`. See the official docs - /// https://developer.android.com/reference/kotlin/androidx/core/app/RemoteInput.Builder?hl=en - /// for details. - const AndroidNotificationActionInput({ - this.choices = const [], - this.allowFreeFormInput = true, - this.label, - this.allowedMimeTypes = const {}, - }); - - /// Specifies choices available to the user to satisfy this input. - final List choices; - - /// Specifies whether the user can provide arbitrary text values. - final bool allowFreeFormInput; - - /// Set a label to be displayed to the user when collecting this input. - final String? label; - - /// Specifies whether the user can provide arbitrary values. - final Set allowedMimeTypes; -} - -/// Mirrors the `Action` class in AndroidX. -/// -/// See the offical docs at -/// https://developer.android.com/reference/kotlin/androidx/core/app/NotificationCompat.Action?hl=en -/// for details. -class AndroidNotificationAction { - /// Constructs a [AndroidNotificationAction] object. The platform will create - /// this object using `Action.Builder`. See the offical docs - /// https://developer.android.com/reference/kotlin/androidx/core/app/NotificationCompat.Action.Builder?hl=en - /// for details. - const AndroidNotificationAction( - this.id, - this.title, { - this.titleColor, - this.icon, - this.contextual = false, - this.showsUserInterface = false, - this.allowGeneratedReplies = false, - this.inputs = const [], - this.cancelNotification = true, - }); - - /// This ID will be sent back in the action handler defined in - /// [FlutterLocalNotificationsPlugin]. - final String id; - - /// The title of the action - final String title; - - /// The color of the title of the action - final Color? titleColor; - - /// Icon to show for this action. - final AndroidBitmap? icon; - - /// Sets whether this Action is a contextual action, i.e. whether the action - /// is dependent on the notification message body. An example of a contextual - /// action could be an action opening a map application with an address shown - /// in the notification. - final bool contextual; - - /// Set whether or not this Action's PendingIntent will open a user interface. - final bool showsUserInterface; - - /// Set whether the platform should automatically generate possible replies to - /// add to RemoteInput#getChoices(). If the Action doesn't have a RemoteInput, - /// this has no effect. - /// - /// You need to specify [inputs] for this property to work. - final bool allowGeneratedReplies; - - /// Add an input to be collected from the user when this action is sent. - final List inputs; - - /// Set whether the notification should be canceled when this action is - /// selected. - final bool cancelNotification; -} - -/// Contains notification details specific to Android. -class AndroidNotificationDetails { - /// Constructs an instance of [AndroidNotificationDetails]. - const AndroidNotificationDetails( - this.channelId, - this.channelName, { - this.channelDescription, - this.icon, - this.importance = Importance.defaultImportance, - this.priority = Priority.defaultPriority, - this.styleInformation, - this.playSound = true, - this.sound, - this.enableVibration = true, - this.vibrationPattern, - this.groupKey, - this.setAsGroupSummary = false, - this.groupAlertBehavior = GroupAlertBehavior.all, - this.autoCancel = true, - this.ongoing = false, - this.silent = false, - this.color, - this.largeIcon, - this.onlyAlertOnce = false, - this.showWhen = true, - this.when, - this.usesChronometer = false, - this.chronometerCountDown = false, - this.channelShowBadge = true, - this.showProgress = false, - this.maxProgress = 0, - this.progress = 0, - this.indeterminate = false, - this.channelAction = AndroidNotificationChannelAction.createIfNotExists, - this.enableLights = false, - this.ledColor, - this.ledOnMs, - this.ledOffMs, - this.ticker, - this.visibility, - this.timeoutAfter, - this.category, - this.fullScreenIntent = false, - this.shortcutId, - this.additionalFlags, - this.subText, - this.tag, - this.actions, - this.colorized = false, - this.number, - this.audioAttributesUsage = AudioAttributesUsage.notification, - }); - - /// The icon that should be used when displaying the notification. - /// - /// When this is set to `null`, the default icon given to - /// [AndroidInitializationSettings.defaultIcon] will be used. - final String? icon; - - /// The channel's id. - /// - /// Required for Android 8.0 or newer. - final String channelId; - - /// The channel's name. - /// - /// Required for Android 8.0 or newer. - final String channelName; - - /// The channel's description. - /// - /// This property is only applicable to Android versions 8.0 or newer. - final String? channelDescription; - - /// Whether notifications posted to this channel can appear as application - /// icon badges in a Launcher - final bool channelShowBadge; - - /// The importance of the notification. - final Importance importance; - - /// The priority of the notification - final Priority priority; - - /// Indicates if a sound should be played when the notification is displayed. - /// - /// For Android 8.0 or newer, this is tied to the specified channel and cannot - /// be changed after the channel has been created for the first time. - final bool playSound; - - /// The sound to play for the notification. - /// - /// Requires setting [playSound] to true for it to work. - /// If [playSound] is set to true but this is not specified then the default - /// sound is played. - /// - /// For Android 8.0 or newer, this is tied to the specified channel and cannot - /// be changed after the channel has been created for the first time. - final AndroidNotificationSound? sound; - - /// Indicates if vibration should be enabled when the notification is - /// displayed. - /// - /// For Android 8.0 or newer, this is tied to the specified channel and cannot - /// be changed after the channel has been created for the first time. - final bool enableVibration; - - /// Indicates if lights should be enabled when the notification is displayed. - /// - /// For Android 8.0 or newer, this is tied to the specified channel and cannot - /// be changed after the channel has been created for the first time. - final bool enableLights; - - /// Configures the vibration pattern. - /// - /// Requires setting [enableVibration] to true for it to work. - /// For Android 8.0 or newer, this is tied to the specified channel and cannot - /// be changed after the channel has been created for the first time. - final Int64List? vibrationPattern; - - /// Specifies the information of the rich notification style to apply to the - /// notification. - final StyleInformation? styleInformation; - - /// Specifies the group that this notification belongs to. - /// - /// For Android 7.0 or newer. - final String? groupKey; - - /// Specifies if this notification will function as the summary for grouped - /// notifications. - final bool setAsGroupSummary; - - /// Specifies the group alert behavior for this notification. - /// - /// Default is AlertAll. - /// See https://developer.android.com/reference/android/support/v4/app/NotificationCompat.Builder.html#setGroupAlertBehavior(int) for more details. - final GroupAlertBehavior groupAlertBehavior; - - /// Specifies if the notification should automatically dismissed upon tapping - /// on it. - final bool autoCancel; - - /// Specifies if the notification will be "ongoing". - final bool ongoing; - - /// Specifies if the notification will be "silent". - final bool silent; - - /// Specifies the color. - final Color? color; - - /// Specifics the large icon to use. - final AndroidBitmap? largeIcon; - - /// Specifies if you would only like the sound, vibrate and ticker to be - /// played if the notification is not already showing. - final bool onlyAlertOnce; - - /// Specifies if the notification should display the timestamp of when it - /// occurred. - /// - /// To control the actual timestamp of the notification, use [when]. - final bool showWhen; - - /// Specifies the timestamp of the notification. - /// - /// To control whether the timestamp is shown in the notification, use - /// [showWhen]. - /// - /// The timestamp is expressed as the number of milliseconds since the - /// "Unix epoch" 1970-01-01T00:00:00Z (UTC). If it's not specified but a - /// timestamp should be shown (i.e. [showWhen] is set to `true`), - /// then Android will default to showing when the notification occurred. - final int? when; - - /// Show [when] as a stopwatch. - /// - /// Instead of presenting [when] as a timestamp, the notification will show an - /// automatically updating display of the minutes and seconds since [when]. - /// Useful when showing an elapsed time (like an ongoing phone call). - final bool usesChronometer; - - /// Sets the chronometer to count down instead of counting up. - /// - /// This property is only applicable to Android 7.0 and newer versions. - final bool chronometerCountDown; - - /// Specifies if the notification will be used to show progress. - final bool showProgress; - - /// The maximum progress value. - final int maxProgress; - - /// The current progress value. - final int progress; - - /// Specifies if an indeterminate progress bar will be shown. - final bool indeterminate; - - /// Specifies the light color of the notification. - /// - /// For Android 8.0 or newer, this is tied to the specified channel and cannot - /// be changed after the channel has been created for the first time. - final Color? ledColor; - - /// Specifies how long the light colour will remain on. - /// - /// This property is only applicable to Android versions older than 8.0. - final int? ledOnMs; - - /// Specifies how long the light colour will remain off. - /// - /// This property is only applicable to Android versions older than 8.0. - final int? ledOffMs; - - /// Specifies the "ticker" text which is sent to accessibility services. - final String? ticker; - - /// The action to take for managing notification channels. - /// - /// Defaults to creating the notification channel using the provided details - /// if it doesn't exist - final AndroidNotificationChannelAction channelAction; - - /// Defines the notification visibility on the lockscreen. - final NotificationVisibility? visibility; - - /// The duration in milliseconds after which the notification will be - /// cancelled if it hasn't already. - final int? timeoutAfter; - - /// The notification category. - final AndroidNotificationCategory? category; - - /// Specifies whether the notification should launch a full-screen intent as - /// soon as it triggers. - /// - /// Note: The system UI may choose to display a heads-up notification, - /// instead of launching your full-screen intent. This can occur while the - /// user is using the device or due the full-screen intent not being granted. - /// When the full-screen intent occurs, the plugin will act as though - /// the user has tapped on a notification so handle it the same way - /// (e.g. via `onSelectNotification` callback) to display the appropriate - /// page for your application. - final bool fullScreenIntent; - - /// Specifies the id of a published, long-lived sharing that the notification - /// will be linked to. - /// - /// From Android 11, this affects if a messaging-style notification appears - /// in the conversation space. - final String? shortcutId; - - /// Specifies the additional flags. - /// - /// These flags will get added to the native Android notification's flags field: https://developer.android.com/reference/android/app/Notification#flags - /// For a list of a values, refer to the documented constants prefixed with "FLAG_" (without the quotes) at https://developer.android.com/reference/android/app/Notification.html#constants_1. - /// For example, use a value of 4 to allow the audio to repeat as documented at https://developer.android.com/reference/android/app/Notification.html#FLAG_INSISTEN - final Int32List? additionalFlags; - - /// Specify a list of actions associated with this notifications. - /// - /// Users will be able tap on the actions without actually launching the App. - /// Note that tapping a action will spawn a separate isolate that runs - /// **independently** from the main app. - final List? actions; - - /// Provides some additional information that is displayed in the - /// notification. - /// - /// No guarantees are given where exactly it is displayed. This information - /// should only be provided if it provides an essential benefit to the - /// understanding of the notification. The more text you provide the less - /// readable it becomes. For example, an email client should only provide the - /// account name here if more than one email account has been added. - /// - /// As of Android 7.0 this information is displayed in the notification header - /// area. On Android versions before 7.0 this will be shown in the third line - /// of text in the platform notification template. You should not be using - /// setProgress(int, int, boolean) at the same time on those versions; they - /// occupy the same place. - final String? subText; - - /// The notification tag. - /// - /// Showing notification with the same (tag, id) pair as a currently visible - /// notification will replace the old notification with the new one, provided - /// the old notification was one that was not one that was scheduled. In other - /// words, the (tag, id) pair is only applicable for notifications that were - /// requested to be shown immediately. This is because the Android - /// AlarmManager APIs used for scheduling notifications only allow for using - /// the id to uniquely identify alarms. - final String? tag; - - /// Specify coloring background should be enabled, if false, color will be - /// applied to app icon. - /// - /// For most styles, the coloring will only be applied if the notification is - /// or a foreground service notification. - final bool colorized; - - /// Set custom notification count. - /// - /// Numbers are only displayed if the launcher application supports the - /// display of badges and numbers. If not supported, this value is ignored. - /// See https://developer.android.com/training/notify-user/badges#set_custom_notification_count - final int? number; - - /// The attribute describing what is the intended use of the audio signal, - /// such as alarm or ringtone set in [`AudioAttributes.Builder`](https://developer.android.com/reference/android/media/AudioAttributes.Builder#setUsage(int)) - /// https://developer.android.com/reference/android/media/AudioAttributes - final AudioAttributesUsage audioAttributesUsage; -} diff --git a/flutter_local_notifications/lib/src/platform_specifics/android/notification_sound.dart b/flutter_local_notifications/lib/src/platform_specifics/android/notification_sound.dart deleted file mode 100644 index a43af0f89..000000000 --- a/flutter_local_notifications/lib/src/platform_specifics/android/notification_sound.dart +++ /dev/null @@ -1,37 +0,0 @@ -/// Represents an Android notification sound. -abstract class AndroidNotificationSound { - /// The location of the sound. - String get sound; -} - -/// Represents a raw resource belonging to the Android application that should -/// be used for the notification sound. -/// -/// These resources would be found in the `res/raw` directory of the Android application -class RawResourceAndroidNotificationSound implements AndroidNotificationSound { - /// Constructs an instance of [RawResourceAndroidNotificationSound]. - const RawResourceAndroidNotificationSound(this._sound); - - final String? _sound; - - /// The name of the raw resource for the notification sound. - @override - String get sound => _sound!; -} - -/// Represents a URI on the Android device that should be used for the -/// notification sound. -/// -/// One way of obtaining such URIs is to use the native Android RingtoneManager -/// APIs, which may require developers to write their own code that makes use -/// of platform channels. -class UriAndroidNotificationSound implements AndroidNotificationSound { - /// Constructs an instance of [UriAndroidNotificationSound]. - const UriAndroidNotificationSound(this._sound); - - final String _sound; - - /// The URI for the notification sound. - @override - String get sound => _sound; -} diff --git a/flutter_local_notifications/lib/src/platform_specifics/android/person.dart b/flutter_local_notifications/lib/src/platform_specifics/android/person.dart deleted file mode 100644 index c57933c94..000000000 --- a/flutter_local_notifications/lib/src/platform_specifics/android/person.dart +++ /dev/null @@ -1,32 +0,0 @@ -import 'icon.dart'; - -/// Details of a person e.g. someone who sent a message. -class Person { - /// Constructs an instance of [Person]. - const Person({ - this.bot = false, - this.icon, - this.important = false, - this.key, - this.name, - this.uri, - }); - - /// Whether or not this person represents a machine rather than a human. - final bool bot; - - /// Icon for this person. - final AndroidIcon? icon; - - /// Whether or not this is an important person. - final bool important; - - /// Unique identifier for this person. - final String? key; - - /// Name of this person. - final String? name; - - /// Uri for this person. - final String? uri; -} diff --git a/flutter_local_notifications/lib/src/platform_specifics/android/schedule_mode.dart b/flutter_local_notifications/lib/src/platform_specifics/android/schedule_mode.dart deleted file mode 100644 index 68110e229..000000000 --- a/flutter_local_notifications/lib/src/platform_specifics/android/schedule_mode.dart +++ /dev/null @@ -1,30 +0,0 @@ -/// Used to specify how notifications should be scheduled on Android. -/// -/// This leverages the use of alarms to schedule notifications as described -/// at https://developer.android.com/training/scheduling/alarms -enum AndroidScheduleMode { - /// Used to specify that the notification should be scheduled to be shown at - /// the exact time specified AND will execute whilst device is in - /// low-power idle mode. Requires SCHEDULE_EXACT_ALARM permission. - alarmClock, - - /// Used to specify that the notification should be scheduled to be shown at - /// the exact time specified but may not execute whilst device is in - /// low-power idle mode. - exact, - - /// Used to specify that the notification should be scheduled to be shown at - /// the exact time specified and will execute whilst device is in - /// low-power idle mode. - exactAllowWhileIdle, - - /// Used to specify that the notification should be scheduled to be shown at - /// at roughly specified time but may not execute whilst device is in - /// low-power idle mode. - inexact, - - /// Used to specify that the notification should be scheduled to be shown at - /// at roughly specified time and will execute whilst device is in - /// low-power idle mode. - inexactAllowWhileIdle, -} diff --git a/flutter_local_notifications/lib/src/platform_specifics/android/styles/big_picture_style_information.dart b/flutter_local_notifications/lib/src/platform_specifics/android/styles/big_picture_style_information.dart deleted file mode 100644 index 57c965e78..000000000 --- a/flutter_local_notifications/lib/src/platform_specifics/android/styles/big_picture_style_information.dart +++ /dev/null @@ -1,44 +0,0 @@ -import '../bitmap.dart'; -import 'default_style_information.dart'; - -/// Used to pass the content for an Android notification displayed using the -/// big picture style. -class BigPictureStyleInformation extends DefaultStyleInformation { - /// Constructs an instance of [BigPictureStyleInformation]. - const BigPictureStyleInformation( - this.bigPicture, { - this.contentTitle, - this.summaryText, - this.htmlFormatContentTitle = false, - this.htmlFormatSummaryText = false, - this.largeIcon, - bool htmlFormatContent = false, - bool htmlFormatTitle = false, - this.hideExpandedLargeIcon = false, - }) : super(htmlFormatContent, htmlFormatTitle); - - /// Overrides ContentTitle in the big form of the template. - final String? contentTitle; - - /// Set the first line of text after the detail section in the big form of - /// the template. - final String? summaryText; - - /// Specifies if the overridden ContentTitle should have formatting applied - /// through HTML markup. - final bool htmlFormatContentTitle; - - /// Specifies if formatting should be applied to the first line of text after - /// the detail section in the big form of the template. - final bool htmlFormatSummaryText; - - /// The bitmap that will override the large icon when the big notification is - /// shown. - final AndroidBitmap? largeIcon; - - /// The bitmap to be used as the payload for the BigPicture notification. - final AndroidBitmap bigPicture; - - /// Hides the large icon when showing the expanded notification. - final bool hideExpandedLargeIcon; -} diff --git a/flutter_local_notifications/lib/src/platform_specifics/android/styles/big_text_style_information.dart b/flutter_local_notifications/lib/src/platform_specifics/android/styles/big_text_style_information.dart deleted file mode 100644 index ccd2be6f8..000000000 --- a/flutter_local_notifications/lib/src/platform_specifics/android/styles/big_text_style_information.dart +++ /dev/null @@ -1,40 +0,0 @@ -import 'default_style_information.dart'; - -/// Used to pass the content for an Android notification displayed using the -/// big text style. -class BigTextStyleInformation extends DefaultStyleInformation { - /// Constructs an instance of [BigTextStyleInformation]. - const BigTextStyleInformation( - this.bigText, { - this.htmlFormatBigText = false, - this.contentTitle, - this.htmlFormatContentTitle = false, - this.summaryText, - this.htmlFormatSummaryText = false, - bool htmlFormatContent = false, - bool htmlFormatTitle = false, - }) : super(htmlFormatContent, htmlFormatTitle); - - /// Provide the longer text to be displayed in the big form of the template - /// in place of the content text. - final String bigText; - - /// Overrides ContentTitle in the big form of the template. - final String? contentTitle; - - /// Set the first line of text after the detail section in the big form of - /// the template. - final String? summaryText; - - /// Specifies if formatting should be applied to the longer text through - /// HTML markup. - final bool htmlFormatBigText; - - /// Specifies if the overridden ContentTitle should have formatting applies - /// through HTML markup. - final bool htmlFormatContentTitle; - - /// Specifies if formatting should be applied to the first line of text - /// after the detail section in the big form of the template. - final bool htmlFormatSummaryText; -} diff --git a/flutter_local_notifications/lib/src/platform_specifics/android/styles/default_style_information.dart b/flutter_local_notifications/lib/src/platform_specifics/android/styles/default_style_information.dart deleted file mode 100644 index e35b880b1..000000000 --- a/flutter_local_notifications/lib/src/platform_specifics/android/styles/default_style_information.dart +++ /dev/null @@ -1,18 +0,0 @@ -import 'style_information.dart'; - -/// The default Android notification style. -class DefaultStyleInformation implements StyleInformation { - /// Constructs an instance of [DefaultStyleInformation]. - const DefaultStyleInformation( - this.htmlFormatContent, - this.htmlFormatTitle, - ); - - /// Specifies if formatting should be applied to the content through HTML - /// markup. - final bool htmlFormatContent; - - /// Specifies if formatting should be applied to the title through HTML - /// markup. - final bool htmlFormatTitle; -} diff --git a/flutter_local_notifications/lib/src/platform_specifics/android/styles/inbox_style_information.dart b/flutter_local_notifications/lib/src/platform_specifics/android/styles/inbox_style_information.dart deleted file mode 100644 index a20e4d358..000000000 --- a/flutter_local_notifications/lib/src/platform_specifics/android/styles/inbox_style_information.dart +++ /dev/null @@ -1,39 +0,0 @@ -import 'default_style_information.dart'; - -/// Used to pass the content for an Android notification displayed using the -/// inbox style. -class InboxStyleInformation extends DefaultStyleInformation { - /// Constructs an instance of [InboxStyleInformation]. - const InboxStyleInformation( - this.lines, { - this.htmlFormatLines = false, - this.contentTitle, - this.htmlFormatContentTitle = false, - this.summaryText, - this.htmlFormatSummaryText = false, - bool htmlFormatContent = false, - bool htmlFormatTitle = false, - }) : super(htmlFormatContent, htmlFormatTitle); - - /// Overrides ContentTitle in the big form of the template. - final String? contentTitle; - - /// Set the first line of text after the detail section in the big form of - /// the template. - final String? summaryText; - - /// The lines that form part of the digest section for inbox-style - /// notifications. - final List lines; - - /// Specifies if the lines should have formatting applied through HTML markup. - final bool htmlFormatLines; - - /// Specifies if the overridden ContentTitle should have formatting applied - /// through HTML markup. - final bool htmlFormatContentTitle; - - /// Specifies if formatting should be applied to the first line of text after - /// the detail section in the big form of the template. - final bool htmlFormatSummaryText; -} diff --git a/flutter_local_notifications/lib/src/platform_specifics/android/styles/media_style_information.dart b/flutter_local_notifications/lib/src/platform_specifics/android/styles/media_style_information.dart deleted file mode 100644 index d1472c1ca..000000000 --- a/flutter_local_notifications/lib/src/platform_specifics/android/styles/media_style_information.dart +++ /dev/null @@ -1,14 +0,0 @@ -import 'default_style_information.dart'; - -/// Used to pass the content for an Android notification displayed using the -/// media style. -/// -/// When used, the bitmap given to [AndroidNotificationDetails.largeIcon] will -/// be treated as album artwork. -class MediaStyleInformation extends DefaultStyleInformation { - /// Constructs an instance of [MediaStyleInformation]. - const MediaStyleInformation({ - bool htmlFormatContent = false, - bool htmlFormatTitle = false, - }) : super(htmlFormatContent, htmlFormatTitle); -} diff --git a/flutter_local_notifications/lib/src/platform_specifics/android/styles/messaging_style_information.dart b/flutter_local_notifications/lib/src/platform_specifics/android/styles/messaging_style_information.dart deleted file mode 100644 index 1e4bdaf6a..000000000 --- a/flutter_local_notifications/lib/src/platform_specifics/android/styles/messaging_style_information.dart +++ /dev/null @@ -1,29 +0,0 @@ -import '../message.dart'; -import '../person.dart'; -import 'default_style_information.dart'; - -/// Used to pass the content for an Android notification displayed using the -/// messaging style. -class MessagingStyleInformation extends DefaultStyleInformation { - /// Constructs an instance of [MessagingStyleInformation]. - MessagingStyleInformation( - this.person, { - this.conversationTitle, - this.groupConversation, - this.messages, - bool htmlFormatContent = false, - bool htmlFormatTitle = false, - }) : super(htmlFormatContent, htmlFormatTitle); - - /// The person displayed for any messages that are sent by the user. - final Person person; - - /// The title to be displayed on this conversation. - final String? conversationTitle; - - /// Whether this conversation notification represents a group. - final bool? groupConversation; - - /// Messages to be displayed by this notification - final List? messages; -} diff --git a/flutter_local_notifications/lib/src/platform_specifics/android/styles/style_information.dart b/flutter_local_notifications/lib/src/platform_specifics/android/styles/style_information.dart deleted file mode 100644 index 69bfb63eb..000000000 --- a/flutter_local_notifications/lib/src/platform_specifics/android/styles/style_information.dart +++ /dev/null @@ -1,2 +0,0 @@ -/// Abstract class for defining an Android notification style -abstract class StyleInformation {} diff --git a/flutter_local_notifications/pigeon/android.dart b/flutter_local_notifications/pigeon/android.dart index 10756ed08..a28b3c240 100644 --- a/flutter_local_notifications/pigeon/android.dart +++ b/flutter_local_notifications/pigeon/android.dart @@ -1,6 +1,6 @@ @ConfigurePigeon(PigeonOptions( dartPackageName: 'flutter_local_notifications', - dartOut: 'lib/src/platform_specifics/android/messages.g.dart', + dartOut: 'lib/src/platform_specifics/android.g.dart', dartOptions: DartOptions(), javaOptions: JavaOptions(), javaOut: 'android/src/main/java/com/dexterous/flutterlocalnotifications/models/Messages.g.java', @@ -1080,7 +1080,7 @@ class AndroidNotificationDetails { // ================== Notification Responses ================== /// The possible notification response types -enum NotificationResponseType { +enum AndroidNotificationResponseType { /// Indicates that a user has selected a notification. selectedNotification, @@ -1089,9 +1089,9 @@ enum NotificationResponseType { } /// Details of a Notification Action that was triggered. -class NotificationResponse { - /// Constructs an instance of [NotificationResponse] - const NotificationResponse({ +class AndroidNotificationResponse { + /// Constructs an instance of [AndroidNotificationResponse] + const AndroidNotificationResponse({ required this.notificationResponseType, this.id, this.actionId, @@ -1125,13 +1125,13 @@ class NotificationResponse { final Map data; /// The notification response type. - final NotificationResponseType notificationResponseType; + final AndroidNotificationResponseType notificationResponseType; } /// Contains details on the notification that launched the application. -class NotificationAppLaunchDetails { - /// Constructs an instance of [NotificationAppLaunchDetails]. - const NotificationAppLaunchDetails( +class AndroidNotificationAppLaunchDetails { + /// Constructs an instance of [AndroidNotificationAppLaunchDetails]. + const AndroidNotificationAppLaunchDetails( this.didNotificationLaunchApp, { this.notificationResponse, }); @@ -1140,15 +1140,15 @@ class NotificationAppLaunchDetails { final bool didNotificationLaunchApp; /// Contains details of the notification that launched the app. - final NotificationResponse? notificationResponse; + final AndroidNotificationResponse? notificationResponse; } // ================== Notification Plugin ================== /// Details of a pending notification that has not been delivered. -class PendingNotificationRequest { - /// Constructs an instance of [PendingNotificationRequest]. - const PendingNotificationRequest(this.id, this.title, this.body, this.payload); +class AndroidPendingNotificationRequest { + /// Constructs an instance of [AndroidPendingNotificationRequest]. + const AndroidPendingNotificationRequest(this.id, this.title, this.body, this.payload); /// The notification's id. final int id; @@ -1165,9 +1165,9 @@ class PendingNotificationRequest { /// Details of an active notification. -class ActiveNotification { - /// Constructs an instance of [ActiveNotification]. - const ActiveNotification({ +class AndroidActiveNotification { + /// Constructs an instance of [AndroidActiveNotification]. + const AndroidActiveNotification({ this.id, this.groupKey, this.channelId, @@ -1308,7 +1308,7 @@ class DateTimeWithTimezone { } /// The components of a date and time representations. -enum DateTimeComponents { +enum AndroidDateTimeComponents { /// The time. time, @@ -1323,7 +1323,7 @@ enum DateTimeComponents { } /// The available intervals for periodically showing notifications. -enum RepeatInterval { +enum AndroidRepeatInterval { /// An interval for every minute. everyMinute, @@ -1376,9 +1376,9 @@ abstract class AndroidNotificationsPlugin { void cancel(int id); void cancelAll(); - NotificationAppLaunchDetails getNotificationAppLaunchDetails(); - PendingNotificationRequest pendingNotificationRequests(); - List getActiveNotifications(); + AndroidNotificationAppLaunchDetails getNotificationAppLaunchDetails(); + AndroidPendingNotificationRequest pendingNotificationRequests(); + List getActiveNotifications(); // ================== Android-Specific ================== void stopForegroundService(); @@ -1401,7 +1401,7 @@ abstract class AndroidNotificationsPlugin { void periodicallyShow({ required AndroidNotificationData data, - required RepeatInterval repeatInterval, + required AndroidRepeatInterval repeatInterval, required int calledAtMillisecondsSinceEpoch, AndroidScheduleMode scheduleMode = AndroidScheduleMode.exact, }); @@ -1415,7 +1415,7 @@ abstract class AndroidNotificationsPlugin { void zonedSchedule({ required AndroidNotificationData data, required DateTimeWithTimezone scheduledDate, - DateTimeComponents? matchDateTimeComponents, + AndroidDateTimeComponents? matchDateTimeComponents, }); void startForegroundService({ 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..2d6179dda 100644 --- a/flutter_local_notifications/test/android_flutter_local_notifications_test.dart +++ b/flutter_local_notifications/test/android_flutter_local_notifications_test.dart @@ -6,7 +6,7 @@ import 'package:flutter/foundation.dart'; import 'package:flutter/material.dart'; import 'package:flutter/services.dart'; import 'package:flutter_local_notifications/flutter_local_notifications.dart'; -import 'package:flutter_local_notifications/src/platform_specifics/android/enums.dart'; +import 'package:flutter_local_notifications/src/platform_specifics/android.g.dart'; import 'package:flutter_test/flutter_test.dart'; import 'package:timezone/data/latest.dart' as tz; import 'package:timezone/timezone.dart' as tz; @@ -47,9 +47,9 @@ void main() { }); test('initialize', () async { - const AndroidInitializationSettings androidInitializationSettings = - AndroidInitializationSettings('app_icon'); - const InitializationSettings initializationSettings = + final AndroidInitializationSettings androidInitializationSettings = + AndroidInitializationSettings(defaultIcon: 'app_icon'); + final InitializationSettings initializationSettings = InitializationSettings(android: androidInitializationSettings); await flutterLocalNotificationsPlugin.initialize(initializationSettings); expect(log, [ @@ -60,9 +60,9 @@ void main() { }); test('show without Android-specific details', () async { - const AndroidInitializationSettings androidInitializationSettings = - AndroidInitializationSettings('app_icon'); - const InitializationSettings initializationSettings = + final AndroidInitializationSettings androidInitializationSettings = + AndroidInitializationSettings(defaultIcon: 'app_icon'); + final InitializationSettings initializationSettings = InitializationSettings(android: androidInitializationSettings); await flutterLocalNotificationsPlugin.initialize(initializationSettings); await flutterLocalNotificationsPlugin.show( @@ -79,16 +79,16 @@ void main() { }); test('show with Android actions', () async { - const AndroidNotificationDetails androidNotificationDetails = + final AndroidNotificationDetails androidNotificationDetails = AndroidNotificationDetails( - 'channelId', - 'channelName', + channelId: 'channelId', + channelName: 'channelName', channelDescription: 'channelDescription', actions: [ AndroidNotificationAction( - 'action1', - 'Action 1', - titleColor: Color.fromARGB(255, 0, 127, 16), + id: 'action1', + name: 'Action 1', + titleColor: AndroidColor.fromARGB(255, 0, 127, 16), contextual: true, showsUserInterface: true, allowGeneratedReplies: true, From 2093dae4e14f185e3bf39ccf54089f45d898d32e Mon Sep 17 00:00:00 2001 From: Levi Lesches Date: Tue, 24 Dec 2024 14:33:09 -0500 Subject: [PATCH 5/9] Updated Android plugin in Dart --- .../platform_flutter_local_notifications.dart | 238 ++++-------------- .../lib/src/tz_datetime_mapper.dart | 46 ++++ .../pigeon/android.dart | 12 +- 3 files changed, 95 insertions(+), 201 deletions(-) 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 759d18f01..2f530716e 100644 --- a/flutter_local_notifications/lib/src/platform_flutter_local_notifications.dart +++ b/flutter_local_notifications/lib/src/platform_flutter_local_notifications.dart @@ -96,8 +96,7 @@ class MethodChannelFlutterLocalNotificationsPlugin } /// Android implementation of the local notifications plugin. -class AndroidFlutterLocalNotificationsPlugin - extends MethodChannelFlutterLocalNotificationsPlugin { +class AndroidFlutterLocalNotificationsPlugin extends FlutterLocalNotificationsPlatform { /// Registers this implementation as the plugin instance. static void registerWith() { FlutterLocalNotificationsPlatform.instance = @@ -105,6 +104,7 @@ class AndroidFlutterLocalNotificationsPlugin } DidReceiveNotificationResponseCallback? _onDidReceiveNotificationResponse; + final _android = AndroidNotificationsPlugin(); /// Initializes the plugin. /// @@ -128,15 +128,12 @@ class AndroidFlutterLocalNotificationsPlugin DidReceiveBackgroundNotificationResponseCallback? onDidReceiveBackgroundNotificationResponse, }) async { + // TODO: Handle the callback case _onDidReceiveNotificationResponse = onDidReceiveNotificationResponse; _channel.setMethodCallHandler(_handleMethod); + _evaluateBackgroundNotificationCallback(onDidReceiveBackgroundNotificationResponse, {}); - final Map arguments = initializationSettings.toMap(); - - _evaluateBackgroundNotificationCallback( - onDidReceiveBackgroundNotificationResponse, arguments); - - return await _channel.invokeMethod('initialize', arguments); + return _android.initialize(initializationSettings); } /// Requests the permission to schedule exact alarms. @@ -149,7 +146,7 @@ class AndroidFlutterLocalNotificationsPlugin /// require the user to grant permission. See [here](https://developer.android.com/about/versions/14/changes/schedule-exact-alarms) /// for official Android documentation. Future requestExactAlarmsPermission() async => - _channel.invokeMethod('requestExactAlarmsPermission'); + _android.requestExactAlarmsPermission(); /// Requests the permission to send/use full-screen intents. /// @@ -163,7 +160,7 @@ class AndroidFlutterLocalNotificationsPlugin /// [here](https://source.android.com/docs/core/permissions/fsi-limits) /// for official Android documentation. Future requestFullScreenIntentPermission() async => - _channel.invokeMethod('requestFullScreenIntentPermission'); + _android.requestFullScreenIntentPermission(); /// Requests the permission for sending notifications. Returns whether the /// permission was granted. @@ -175,7 +172,7 @@ class AndroidFlutterLocalNotificationsPlugin /// /// * https://developer.android.com/about/versions/13/changes/notification-permission Future requestNotificationsPermission() async => - _channel.invokeMethod('requestNotificationsPermission'); + _android.requestNotificationsPermission(); /// Schedules a notification to be shown at the specified date and time /// relative to a specific time zone. @@ -198,20 +195,17 @@ class AndroidFlutterLocalNotificationsPlugin }) async { validateId(id); validateDateIsInTheFuture(scheduledDate, matchDateTimeComponents); - - await _channel.invokeMethod( - 'zonedSchedule', - { - 'id': id, - 'title': title, - 'body': body, - 'platformSpecifics': - _buildPlatformSpecifics(notificationDetails, scheduleMode), - 'payload': payload ?? '', - ...scheduledDate.toMap(), - if (matchDateTimeComponents != null) - 'matchDateTimeComponents': matchDateTimeComponents.index - }, + final data = AndroidNotificationData( + id: id, + title: title, + body: body, + details: notificationDetails, + payload: payload, + ); + await _android.zonedSchedule( + data: data, + scheduledDate: scheduledDate.toAndroid(), + matchDateTimeComponents: matchDateTimeComponents?.toAndroid(), ); } @@ -268,7 +262,7 @@ class AndroidFlutterLocalNotificationsPlugin {AndroidNotificationDetails? notificationDetails, String? payload, AndroidServiceStartType startType = AndroidServiceStartType.startSticky, - Set? foregroundServiceTypes}) { + Set? foregroundServiceTypes}) async { validateId(id); if (id == 0) { throw ArgumentError.value(id, 'id', @@ -278,19 +272,9 @@ class AndroidFlutterLocalNotificationsPlugin throw ArgumentError.value(foregroundServiceTypes, 'foregroundServiceType', 'foregroundServiceType may be null but it must never be empty!'); } - return _channel.invokeMethod('startForegroundService', { - 'notificationData': { - 'id': id, - 'title': title, - 'body': body, - 'payload': payload ?? '', - 'platformSpecifics': notificationDetails?.toMap(), - }, - 'startType': startType.index, - 'foregroundServiceTypes': foregroundServiceTypes - ?.map((AndroidServiceForegroundType type) => type.value) - .toList() - }); + + final data = AndroidNotificationData(id: id, title: title, body: body, details: notificationDetails, payload: payload); + await _android.startForegroundService(data: data, startType: startType, foregroundServiceTypes: foregroundServiceTypes?.toList()); } /// Stops a foreground service. @@ -302,7 +286,7 @@ class AndroidFlutterLocalNotificationsPlugin /// foreground service, even if [startForegroundService] was called /// multiple times. Future stopForegroundService() => - _channel.invokeMethod('stopForegroundService'); + _android.stopForegroundService(); @override Future show( @@ -311,18 +295,10 @@ class AndroidFlutterLocalNotificationsPlugin String? body, { AndroidNotificationDetails? notificationDetails, String? payload, - }) { + }) async { validateId(id); - return _channel.invokeMethod( - 'show', - { - 'id': id, - 'title': title, - 'body': body, - 'payload': payload ?? '', - 'platformSpecifics': notificationDetails?.toMap(), - }, - ); + final data = AndroidNotificationData(id: id, title: title, body: body, details: notificationDetails, payload: payload); + await _android.show(data); } /// Periodically show a notification using the specified interval. @@ -345,16 +321,8 @@ class AndroidFlutterLocalNotificationsPlugin AndroidScheduleMode scheduleMode = AndroidScheduleMode.exact, }) async { validateId(id); - await _channel.invokeMethod('periodicallyShow', { - 'id': id, - 'title': title, - 'body': body, - 'calledAt': clock.now().millisecondsSinceEpoch, - 'repeatInterval': repeatInterval.index, - 'platformSpecifics': - _buildPlatformSpecifics(notificationDetails, scheduleMode), - 'payload': payload ?? '', - }); + final data = AndroidNotificationData(id: id, title: title, body: body, details: notificationDetails, payload: payload); + await _android.periodicallyShow(data: data, repeatInterval: repeatInterval.toAndroid(), calledAtMillisecondsSinceEpoch: clock.now().millisecondsSinceEpoch, scheduleMode: scheduleMode); } @override @@ -369,28 +337,10 @@ class AndroidFlutterLocalNotificationsPlugin }) async { validateId(id); validateRepeatDurationInterval(repeatDurationInterval); - await _channel - .invokeMethod('periodicallyShowWithDuration', { - 'id': id, - 'title': title, - 'body': body, - 'calledAt': clock.now().millisecondsSinceEpoch, - 'repeatIntervalMilliseconds': repeatDurationInterval.inMilliseconds, - 'platformSpecifics': - _buildPlatformSpecifics(notificationDetails, scheduleMode), - 'payload': payload ?? '', - }); + final data = AndroidNotificationData(id: id, title: title, body: body, details: notificationDetails, payload: payload); + await _android.periodicallyShowWithDuration(data: data, calledAtMillisecondsSinceEpoch: clock.now().millisecondsSinceEpoch, repeatIntervalMilliseconds: repeatDurationInterval.inMilliseconds, scheduleMode: scheduleMode); } - Map _buildPlatformSpecifics( - AndroidNotificationDetails? notificationDetails, - AndroidScheduleMode scheduleMode, - ) => - { - if (notificationDetails != null) ...notificationDetails.toMap(), - 'scheduleMode': scheduleMode.name, - }; - /// Cancel/remove the notification with the specified id. /// /// This applies to notifications that have been scheduled and those that @@ -402,41 +352,33 @@ class AndroidFlutterLocalNotificationsPlugin @override Future cancel(int id, {String? tag}) async { validateId(id); - - return _channel.invokeMethod('cancel', { - 'id': id, - 'tag': tag, - }); + await _android.cancel(id); } /// Creates a notification channel group. /// /// This method is only applicable to Android versions 8.0 or newer. - Future createNotificationChannelGroup( - AndroidNotificationChannelGroup notificationChannelGroup) => - _channel.invokeMethod( - 'createNotificationChannelGroup', notificationChannelGroup.toMap()); + Future createNotificationChannelGroup(AndroidNotificationChannelGroup notificationChannelGroup) => + _android.createNotificationChannelGroup(notificationChannelGroup); /// Deletes the notification channel group with the specified [groupId] /// as well as all of the channels belonging to the group. /// /// This method is only applicable to Android versions 8.0 or newer. Future deleteNotificationChannelGroup(String groupId) => - _channel.invokeMethod('deleteNotificationChannelGroup', groupId); + _android.deleteNotificationChannelGroup(groupId); /// Creates a notification channel. /// /// This method is only applicable to Android versions 8.0 or newer. - Future createNotificationChannel( - AndroidNotificationChannel notificationChannel) => - _channel.invokeMethod( - 'createNotificationChannel', notificationChannel.toMap()); + Future createNotificationChannel(AndroidNotificationChannel notificationChannel) => + _android.createNotificationChannel(notificationChannel); /// Deletes the notification channel with the specified [channelId]. /// /// This method is only applicable to Android versions 8.0 or newer. Future deleteNotificationChannel(String channelId) => - _channel.invokeMethod('deleteNotificationChannel', channelId); + _android.deleteNotificationChannel(channelId); /// Returns the messaging style information of an active notification shown /// by the application that hasn't been dismissed/removed. @@ -450,93 +392,14 @@ class AndroidFlutterLocalNotificationsPlugin Future getActiveNotificationMessagingStyle( int id, { String? tag, - }) async { - final Map? m = await _channel - .invokeMethod('getActiveNotificationMessagingStyle', { - 'id': id, - 'tag': tag, - }); - if (m == null) { - return null; - } - - return MessagingStyleInformation( - _personFromMap(m['person'])!, - conversationTitle: m['conversationTitle'], - groupConversation: m['groupConversation'], - messages: - // ignore: always_specify_types - m['messages']?.map((m) => _messageFromMap(m))?.toList(), - ); - } - - Person? _personFromMap(Map? m) { - if (m == null) { - return null; - } - return Person( - bot: m['bot'], - icon: _iconFromMap(m['icon']), - important: m['important'], - key: m['key'], - name: m['name'], - uri: m['uri'], - ); - } - - Message _messageFromMap(Map m) => Message( - m['text'], - DateTime.fromMillisecondsSinceEpoch(m['timestamp']), - _personFromMap(m['person']), - ); - - AndroidIcon? _iconFromMap(Map? m) { - if (m == null) { - return null; - } - switch (AndroidIconSource.values[m['source']]) { - case AndroidIconSource.drawableResource: - return DrawableResourceAndroidIcon(m['data']); - case AndroidIconSource.contentUri: - return ContentUriAndroidIcon(m['data']); - default: - return null; - } - } + }) => _android.getActiveNotificationMessagingStyle(id: id, tag: tag); /// Returns the list of all notification channels. /// /// This method is only applicable on Android 8.0 or newer. On older versions, /// it will return an empty list. - Future?> getNotificationChannels() async { - final List>? notificationChannels = - await _channel.invokeListMethod('getNotificationChannels'); - - return notificationChannels - // ignore: always_specify_types - ?.map((a) => AndroidNotificationChannel( - a['id'], - a['name'], - description: a['description'], - groupId: a['groupId'], - showBadge: a['showBadge'], - importance: Importance.values - // ignore: always_specify_types - .firstWhere((i) => i.value == a['importance']), - playSound: a['playSound'], - sound: _getNotificationChannelSound(a), - enableLights: a['enableLights'], - enableVibration: a['enableVibration'], - vibrationPattern: a['vibrationPattern'], - ledColor: Color(a['ledColor']), - audioAttributesUsage: AudioAttributesUsage.values.firstWhere( - // ignore: always_specify_types - (e) => e.value == a['audioAttributesUsage'], - orElse: () => AudioAttributesUsage.notification, - ), - )) - .toList(); - } + Future?> getNotificationChannels() => + _android.getNotificationChannels(); /// Returns whether the app can post notifications. /// @@ -548,26 +411,11 @@ class AndroidFlutterLocalNotificationsPlugin /// /// * https://developer.android.com/about/versions/13/changes/notification-permission Future areNotificationsEnabled() async => - await _channel.invokeMethod('areNotificationsEnabled'); + _android.areNotificationsEnabled(); /// Returns whether the app can schedule exact notifications. Future canScheduleExactNotifications() async => - await _channel.invokeMethod('canScheduleExactNotifications'); - - AndroidNotificationSound? _getNotificationChannelSound( - Map channelMap) { - final int? soundSourceIndex = channelMap['soundSource']; - AndroidNotificationSound? sound; - if (soundSourceIndex != null) { - if (soundSourceIndex == - AndroidNotificationSoundSource.rawResource.index) { - sound = RawResourceAndroidNotificationSound(channelMap['sound']); - } else if (soundSourceIndex == AndroidNotificationSoundSource.uri.index) { - sound = UriAndroidNotificationSound(channelMap['sound']); - } - } - return sound; - } + _android.canScheduleExactNotifications(); Future _handleMethod(MethodCall call) async { switch (call.method) { diff --git a/flutter_local_notifications/lib/src/tz_datetime_mapper.dart b/flutter_local_notifications/lib/src/tz_datetime_mapper.dart index 6e009819e..9595dcea0 100644 --- a/flutter_local_notifications/lib/src/tz_datetime_mapper.dart +++ b/flutter_local_notifications/lib/src/tz_datetime_mapper.dart @@ -1,5 +1,7 @@ import 'package:timezone/timezone.dart'; +import '../flutter_local_notifications.dart'; + // ignore_for_file: public_member_api_docs extension TZDateTimeMapper on TZDateTime { Map toMap() { @@ -27,4 +29,48 @@ extension TZDateTimeMapper on TZDateTime { 'scheduledDateTimeISO8601': toIso8601String(), }; } + + AndroidDateTime toAndroid() { + String twoDigits(int n) { + if (n >= 10) { + return '$n'; + } + return '0$n'; + } + + final String offsetMinutesComponent = + twoDigits(timeZoneOffset.inMinutes.remainder(60)); + final int offsetHoursComponent = + (timeZoneOffset.inMicroseconds ~/ Duration.microsecondsPerHour).abs(); + final String iso8601OffsetComponent = + '${timeZoneOffset.isNegative ? '-' : '+'}${twoDigits(offsetHoursComponent)}$offsetMinutesComponent'; // ignore: lines_longer_than_80_chars + final String iso8601DateComponent = toIso8601String() + .split('.')[0] + .replaceAll(iso8601OffsetComponent, '') + .replaceAll('Z', ''); + + return AndroidDateTime( + scheduledDateTime: iso8601DateComponent, + scheduledDateTimeIso8601: toIso8601String(), + timezoneName: location.name, + ); + } +} + +extension DateTimeComponentsUtils on DateTimeComponents { + AndroidDateTimeComponents toAndroid() => switch (this) { + DateTimeComponents.dateAndTime => AndroidDateTimeComponents.dateAndTime, + DateTimeComponents.dayOfMonthAndTime => AndroidDateTimeComponents.dayOfMonthAndTime, + DateTimeComponents.dayOfWeekAndTime => AndroidDateTimeComponents.dayOfWeekAndTime, + DateTimeComponents.time => AndroidDateTimeComponents.time, + }; +} + +extension RepeatIntervalUtils on RepeatInterval { + AndroidRepeatInterval toAndroid() => switch (this) { + RepeatInterval.daily => AndroidRepeatInterval.daily, + RepeatInterval.everyMinute => AndroidRepeatInterval.everyMinute, + RepeatInterval.hourly => AndroidRepeatInterval.hourly, + RepeatInterval.weekly => AndroidRepeatInterval.weekly, + }; } diff --git a/flutter_local_notifications/pigeon/android.dart b/flutter_local_notifications/pigeon/android.dart index a28b3c240..22dbfa057 100644 --- a/flutter_local_notifications/pigeon/android.dart +++ b/flutter_local_notifications/pigeon/android.dart @@ -1163,7 +1163,6 @@ class AndroidPendingNotificationRequest { final String? payload; } - /// Details of an active notification. class AndroidActiveNotification { /// Constructs an instance of [AndroidActiveNotification]. @@ -1295,8 +1294,8 @@ enum AndroidServiceForegroundType { foregroundServiceTypeSpecialUse; } -class DateTimeWithTimezone { - const DateTimeWithTimezone({ +class AndroidDateTime { + const AndroidDateTime({ required this.scheduledDateTime, required this.scheduledDateTimeIso8601, required this.timezoneName, @@ -1383,7 +1382,7 @@ abstract class AndroidNotificationsPlugin { // ================== Android-Specific ================== void stopForegroundService(); - bool initialize(); + bool initialize(AndroidInitializationSettings settings); bool? requestExactAlarmsPermission(); bool? requestFullScreenIntentPermission(); bool? requestNotificationsPermission(); @@ -1403,18 +1402,19 @@ abstract class AndroidNotificationsPlugin { required AndroidNotificationData data, required AndroidRepeatInterval repeatInterval, required int calledAtMillisecondsSinceEpoch, - AndroidScheduleMode scheduleMode = AndroidScheduleMode.exact, + required AndroidScheduleMode scheduleMode, }); void periodicallyShowWithDuration({ required AndroidNotificationData data, required int calledAtMillisecondsSinceEpoch, required int repeatIntervalMilliseconds, + required AndroidScheduleMode scheduleMode, }); void zonedSchedule({ required AndroidNotificationData data, - required DateTimeWithTimezone scheduledDate, + required AndroidDateTime scheduledDate, AndroidDateTimeComponents? matchDateTimeComponents, }); From 39588da44479bd713c544afc5f8f51cb09c3b533 Mon Sep 17 00:00:00 2001 From: Levi Lesches Date: Tue, 24 Dec 2024 14:39:11 -0500 Subject: [PATCH 6/9] Reset tests to master --- .../flutter_local_notifications_test.dart | 2 +- ...roid_flutter_local_notifications_test.dart | 26 +++++++++---------- 2 files changed, 14 insertions(+), 14 deletions(-) diff --git a/flutter_local_notifications/example/integration_test/flutter_local_notifications_test.dart b/flutter_local_notifications/example/integration_test/flutter_local_notifications_test.dart index 634f07e27..a6b83b525 100644 --- a/flutter_local_notifications/example/integration_test/flutter_local_notifications_test.dart +++ b/flutter_local_notifications/example/integration_test/flutter_local_notifications_test.dart @@ -7,7 +7,7 @@ import 'package:integration_test/integration_test.dart'; void main() { IntegrationTestWidgetsFlutterBinding.ensureInitialized(); const AndroidInitializationSettings initializationSettingsAndroid = - AndroidInitializationSettings(defaultIcon: 'app_icon'); + AndroidInitializationSettings('app_icon'); const DarwinInitializationSettings initializationSettingsIOS = DarwinInitializationSettings(); const DarwinInitializationSettings initializationSettingsMacOS = 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 2d6179dda..ebfc62797 100644 --- a/flutter_local_notifications/test/android_flutter_local_notifications_test.dart +++ b/flutter_local_notifications/test/android_flutter_local_notifications_test.dart @@ -6,7 +6,7 @@ import 'package:flutter/foundation.dart'; import 'package:flutter/material.dart'; import 'package:flutter/services.dart'; import 'package:flutter_local_notifications/flutter_local_notifications.dart'; -import 'package:flutter_local_notifications/src/platform_specifics/android.g.dart'; +import 'package:flutter_local_notifications/src/platform_specifics/android/enums.dart'; import 'package:flutter_test/flutter_test.dart'; import 'package:timezone/data/latest.dart' as tz; import 'package:timezone/timezone.dart' as tz; @@ -47,9 +47,9 @@ void main() { }); test('initialize', () async { - final AndroidInitializationSettings androidInitializationSettings = - AndroidInitializationSettings(defaultIcon: 'app_icon'); - final InitializationSettings initializationSettings = + const AndroidInitializationSettings androidInitializationSettings = + AndroidInitializationSettings('app_icon'); + const InitializationSettings initializationSettings = InitializationSettings(android: androidInitializationSettings); await flutterLocalNotificationsPlugin.initialize(initializationSettings); expect(log, [ @@ -60,9 +60,9 @@ void main() { }); test('show without Android-specific details', () async { - final AndroidInitializationSettings androidInitializationSettings = - AndroidInitializationSettings(defaultIcon: 'app_icon'); - final InitializationSettings initializationSettings = + const AndroidInitializationSettings androidInitializationSettings = + AndroidInitializationSettings('app_icon'); + const InitializationSettings initializationSettings = InitializationSettings(android: androidInitializationSettings); await flutterLocalNotificationsPlugin.initialize(initializationSettings); await flutterLocalNotificationsPlugin.show( @@ -79,16 +79,16 @@ void main() { }); test('show with Android actions', () async { - final AndroidNotificationDetails androidNotificationDetails = + const AndroidNotificationDetails androidNotificationDetails = AndroidNotificationDetails( - channelId: 'channelId', - channelName: 'channelName', + 'channelId', + 'channelName', channelDescription: 'channelDescription', actions: [ AndroidNotificationAction( - id: 'action1', - name: 'Action 1', - titleColor: AndroidColor.fromARGB(255, 0, 127, 16), + 'action1', + 'Action 1', + titleColor: Color.fromARGB(255, 0, 127, 16), contextual: true, showsUserInterface: true, allowGeneratedReplies: true, From cf0d78e7729654690988b88004a25887307033e6 Mon Sep 17 00:00:00 2001 From: Levi Lesches Date: Tue, 24 Dec 2024 14:58:00 -0500 Subject: [PATCH 7/9] Working, but public APIs have changed --- .../example/lib/main.dart | 8 +- .../platform_flutter_local_notifications.dart | 89 +- .../lib/src/tz_datetime_mapper.dart | 22 +- .../pigeon/android.dart | 16 +- ...roid_flutter_local_notifications_test.dart | 2774 ----------------- 5 files changed, 89 insertions(+), 2820 deletions(-) delete mode 100644 flutter_local_notifications/test/android_flutter_local_notifications_test.dart diff --git a/flutter_local_notifications/example/lib/main.dart b/flutter_local_notifications/example/lib/main.dart index bdb1122f3..11623ebec 100644 --- a/flutter_local_notifications/example/lib/main.dart +++ b/flutter_local_notifications/example/lib/main.dart @@ -2209,7 +2209,7 @@ class _HomePageState extends State { await showDialog( context: context, builder: (BuildContext context) => AlertDialog( - content: Text('Channel group with name ' + content: const Text('Channel group with name ' '${androidNotificationChannelGroup.name} created'), actions: [ TextButton( @@ -2304,9 +2304,9 @@ class _HomePageState extends State { await showDialog( context: context, builder: (BuildContext context) => AlertDialog( - content: - Text('Channel with name ${androidNotificationChannel.name} ' - 'created'), + content: const Text( + 'Channel with name ${androidNotificationChannel.name} ' + 'created'), actions: [ TextButton( onPressed: () { 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 2f530716e..66d7a89c6 100644 --- a/flutter_local_notifications/lib/src/platform_flutter_local_notifications.dart +++ b/flutter_local_notifications/lib/src/platform_flutter_local_notifications.dart @@ -96,7 +96,8 @@ class MethodChannelFlutterLocalNotificationsPlugin } /// Android implementation of the local notifications plugin. -class AndroidFlutterLocalNotificationsPlugin extends FlutterLocalNotificationsPlatform { +class AndroidFlutterLocalNotificationsPlugin + extends FlutterLocalNotificationsPlatform { /// Registers this implementation as the plugin instance. static void registerWith() { FlutterLocalNotificationsPlatform.instance = @@ -104,7 +105,7 @@ class AndroidFlutterLocalNotificationsPlugin extends FlutterLocalNotificationsPl } DidReceiveNotificationResponseCallback? _onDidReceiveNotificationResponse; - final _android = AndroidNotificationsPlugin(); + final AndroidNotificationsPlugin _android = AndroidNotificationsPlugin(); /// Initializes the plugin. /// @@ -128,10 +129,11 @@ class AndroidFlutterLocalNotificationsPlugin extends FlutterLocalNotificationsPl DidReceiveBackgroundNotificationResponseCallback? onDidReceiveBackgroundNotificationResponse, }) async { - // TODO: Handle the callback case + // TODO(Levi-Lesches): Handle the callback case _onDidReceiveNotificationResponse = onDidReceiveNotificationResponse; _channel.setMethodCallHandler(_handleMethod); - _evaluateBackgroundNotificationCallback(onDidReceiveBackgroundNotificationResponse, {}); + _evaluateBackgroundNotificationCallback( + onDidReceiveBackgroundNotificationResponse, {}); return _android.initialize(initializationSettings); } @@ -146,7 +148,7 @@ class AndroidFlutterLocalNotificationsPlugin extends FlutterLocalNotificationsPl /// require the user to grant permission. See [here](https://developer.android.com/about/versions/14/changes/schedule-exact-alarms) /// for official Android documentation. Future requestExactAlarmsPermission() async => - _android.requestExactAlarmsPermission(); + _android.requestExactAlarmsPermission(); /// Requests the permission to send/use full-screen intents. /// @@ -160,7 +162,7 @@ class AndroidFlutterLocalNotificationsPlugin extends FlutterLocalNotificationsPl /// [here](https://source.android.com/docs/core/permissions/fsi-limits) /// for official Android documentation. Future requestFullScreenIntentPermission() async => - _android.requestFullScreenIntentPermission(); + _android.requestFullScreenIntentPermission(); /// Requests the permission for sending notifications. Returns whether the /// permission was granted. @@ -172,7 +174,7 @@ class AndroidFlutterLocalNotificationsPlugin extends FlutterLocalNotificationsPl /// /// * https://developer.android.com/about/versions/13/changes/notification-permission Future requestNotificationsPermission() async => - _android.requestNotificationsPermission(); + _android.requestNotificationsPermission(); /// Schedules a notification to be shown at the specified date and time /// relative to a specific time zone. @@ -195,7 +197,7 @@ class AndroidFlutterLocalNotificationsPlugin extends FlutterLocalNotificationsPl }) async { validateId(id); validateDateIsInTheFuture(scheduledDate, matchDateTimeComponents); - final data = AndroidNotificationData( + final AndroidNotificationData data = AndroidNotificationData( id: id, title: title, body: body, @@ -273,8 +275,16 @@ class AndroidFlutterLocalNotificationsPlugin extends FlutterLocalNotificationsPl 'foregroundServiceType may be null but it must never be empty!'); } - final data = AndroidNotificationData(id: id, title: title, body: body, details: notificationDetails, payload: payload); - await _android.startForegroundService(data: data, startType: startType, foregroundServiceTypes: foregroundServiceTypes?.toList()); + final AndroidNotificationData data = AndroidNotificationData( + id: id, + title: title, + body: body, + details: notificationDetails, + payload: payload); + await _android.startForegroundService( + data: data, + startType: startType, + foregroundServiceTypes: foregroundServiceTypes?.toList()); } /// Stops a foreground service. @@ -285,8 +295,7 @@ class AndroidFlutterLocalNotificationsPlugin extends FlutterLocalNotificationsPl /// It is sufficient to call this method once to stop the /// foreground service, even if [startForegroundService] was called /// multiple times. - Future stopForegroundService() => - _android.stopForegroundService(); + Future stopForegroundService() => _android.stopForegroundService(); @override Future show( @@ -297,7 +306,12 @@ class AndroidFlutterLocalNotificationsPlugin extends FlutterLocalNotificationsPl String? payload, }) async { validateId(id); - final data = AndroidNotificationData(id: id, title: title, body: body, details: notificationDetails, payload: payload); + final AndroidNotificationData data = AndroidNotificationData( + id: id, + title: title, + body: body, + details: notificationDetails, + payload: payload); await _android.show(data); } @@ -321,8 +335,17 @@ class AndroidFlutterLocalNotificationsPlugin extends FlutterLocalNotificationsPl AndroidScheduleMode scheduleMode = AndroidScheduleMode.exact, }) async { validateId(id); - final data = AndroidNotificationData(id: id, title: title, body: body, details: notificationDetails, payload: payload); - await _android.periodicallyShow(data: data, repeatInterval: repeatInterval.toAndroid(), calledAtMillisecondsSinceEpoch: clock.now().millisecondsSinceEpoch, scheduleMode: scheduleMode); + final AndroidNotificationData data = AndroidNotificationData( + id: id, + title: title, + body: body, + details: notificationDetails, + payload: payload); + await _android.periodicallyShow( + data: data, + repeatInterval: repeatInterval.toAndroid(), + calledAtMillisecondsSinceEpoch: clock.now().millisecondsSinceEpoch, + scheduleMode: scheduleMode); } @override @@ -337,8 +360,17 @@ class AndroidFlutterLocalNotificationsPlugin extends FlutterLocalNotificationsPl }) async { validateId(id); validateRepeatDurationInterval(repeatDurationInterval); - final data = AndroidNotificationData(id: id, title: title, body: body, details: notificationDetails, payload: payload); - await _android.periodicallyShowWithDuration(data: data, calledAtMillisecondsSinceEpoch: clock.now().millisecondsSinceEpoch, repeatIntervalMilliseconds: repeatDurationInterval.inMilliseconds, scheduleMode: scheduleMode); + final AndroidNotificationData data = AndroidNotificationData( + id: id, + title: title, + body: body, + details: notificationDetails, + payload: payload); + await _android.periodicallyShowWithDuration( + data: data, + calledAtMillisecondsSinceEpoch: clock.now().millisecondsSinceEpoch, + repeatIntervalMilliseconds: repeatDurationInterval.inMilliseconds, + scheduleMode: scheduleMode); } /// Cancel/remove the notification with the specified id. @@ -358,27 +390,29 @@ class AndroidFlutterLocalNotificationsPlugin extends FlutterLocalNotificationsPl /// Creates a notification channel group. /// /// This method is only applicable to Android versions 8.0 or newer. - Future createNotificationChannelGroup(AndroidNotificationChannelGroup notificationChannelGroup) => - _android.createNotificationChannelGroup(notificationChannelGroup); + Future createNotificationChannelGroup( + AndroidNotificationChannelGroup notificationChannelGroup) => + _android.createNotificationChannelGroup(notificationChannelGroup); /// Deletes the notification channel group with the specified [groupId] /// as well as all of the channels belonging to the group. /// /// This method is only applicable to Android versions 8.0 or newer. Future deleteNotificationChannelGroup(String groupId) => - _android.deleteNotificationChannelGroup(groupId); + _android.deleteNotificationChannelGroup(groupId); /// Creates a notification channel. /// /// This method is only applicable to Android versions 8.0 or newer. - Future createNotificationChannel(AndroidNotificationChannel notificationChannel) => - _android.createNotificationChannel(notificationChannel); + Future createNotificationChannel( + AndroidNotificationChannel notificationChannel) => + _android.createNotificationChannel(notificationChannel); /// Deletes the notification channel with the specified [channelId]. /// /// This method is only applicable to Android versions 8.0 or newer. Future deleteNotificationChannel(String channelId) => - _android.deleteNotificationChannel(channelId); + _android.deleteNotificationChannel(channelId); /// Returns the messaging style information of an active notification shown /// by the application that hasn't been dismissed/removed. @@ -392,14 +426,15 @@ class AndroidFlutterLocalNotificationsPlugin extends FlutterLocalNotificationsPl Future getActiveNotificationMessagingStyle( int id, { String? tag, - }) => _android.getActiveNotificationMessagingStyle(id: id, tag: tag); + }) => + _android.getActiveNotificationMessagingStyle(id: id, tag: tag); /// Returns the list of all notification channels. /// /// This method is only applicable on Android 8.0 or newer. On older versions, /// it will return an empty list. Future?> getNotificationChannels() => - _android.getNotificationChannels(); + _android.getNotificationChannels(); /// Returns whether the app can post notifications. /// @@ -411,11 +446,11 @@ class AndroidFlutterLocalNotificationsPlugin extends FlutterLocalNotificationsPl /// /// * https://developer.android.com/about/versions/13/changes/notification-permission Future areNotificationsEnabled() async => - _android.areNotificationsEnabled(); + _android.areNotificationsEnabled(); /// Returns whether the app can schedule exact notifications. Future canScheduleExactNotifications() async => - _android.canScheduleExactNotifications(); + _android.canScheduleExactNotifications(); Future _handleMethod(MethodCall call) async { switch (call.method) { diff --git a/flutter_local_notifications/lib/src/tz_datetime_mapper.dart b/flutter_local_notifications/lib/src/tz_datetime_mapper.dart index 9595dcea0..59c02b138 100644 --- a/flutter_local_notifications/lib/src/tz_datetime_mapper.dart +++ b/flutter_local_notifications/lib/src/tz_datetime_mapper.dart @@ -59,18 +59,20 @@ extension TZDateTimeMapper on TZDateTime { extension DateTimeComponentsUtils on DateTimeComponents { AndroidDateTimeComponents toAndroid() => switch (this) { - DateTimeComponents.dateAndTime => AndroidDateTimeComponents.dateAndTime, - DateTimeComponents.dayOfMonthAndTime => AndroidDateTimeComponents.dayOfMonthAndTime, - DateTimeComponents.dayOfWeekAndTime => AndroidDateTimeComponents.dayOfWeekAndTime, - DateTimeComponents.time => AndroidDateTimeComponents.time, - }; + DateTimeComponents.dateAndTime => AndroidDateTimeComponents.dateAndTime, + DateTimeComponents.dayOfMonthAndTime => + AndroidDateTimeComponents.dayOfMonthAndTime, + DateTimeComponents.dayOfWeekAndTime => + AndroidDateTimeComponents.dayOfWeekAndTime, + DateTimeComponents.time => AndroidDateTimeComponents.time, + }; } extension RepeatIntervalUtils on RepeatInterval { AndroidRepeatInterval toAndroid() => switch (this) { - RepeatInterval.daily => AndroidRepeatInterval.daily, - RepeatInterval.everyMinute => AndroidRepeatInterval.everyMinute, - RepeatInterval.hourly => AndroidRepeatInterval.hourly, - RepeatInterval.weekly => AndroidRepeatInterval.weekly, - }; + RepeatInterval.daily => AndroidRepeatInterval.daily, + RepeatInterval.everyMinute => AndroidRepeatInterval.everyMinute, + RepeatInterval.hourly => AndroidRepeatInterval.hourly, + RepeatInterval.weekly => AndroidRepeatInterval.weekly, + }; } diff --git a/flutter_local_notifications/pigeon/android.dart b/flutter_local_notifications/pigeon/android.dart index 22dbfa057..eb51b32d7 100644 --- a/flutter_local_notifications/pigeon/android.dart +++ b/flutter_local_notifications/pigeon/android.dart @@ -1,9 +1,12 @@ @ConfigurePigeon(PigeonOptions( dartPackageName: 'flutter_local_notifications', dartOut: 'lib/src/platform_specifics/android.g.dart', - dartOptions: DartOptions(), + dartOptions: DartOptions( + copyrightHeader: ['ignore_for_file: type=lint'], + ), javaOptions: JavaOptions(), - javaOut: 'android/src/main/java/com/dexterous/flutterlocalnotifications/models/Messages.g.java', + javaOut: + 'android/src/main/java/com/dexterous/flutterlocalnotifications/models/Messages.g.java', )) library; @@ -1148,7 +1151,8 @@ class AndroidNotificationAppLaunchDetails { /// Details of a pending notification that has not been delivered. class AndroidPendingNotificationRequest { /// Constructs an instance of [AndroidPendingNotificationRequest]. - const AndroidPendingNotificationRequest(this.id, this.title, this.body, this.payload); + const AndroidPendingNotificationRequest( + this.id, this.title, this.body, this.payload); /// The notification's id. final int id; @@ -1391,9 +1395,11 @@ abstract class AndroidNotificationsPlugin { List? getNotificationChannels(); - void createNotificationChannelGroup(AndroidNotificationChannelGroup notificationChannelGroup); + void createNotificationChannelGroup( + AndroidNotificationChannelGroup notificationChannelGroup); void deleteNotificationChannelGroup(String groupId); - void createNotificationChannel(AndroidNotificationChannel notificationChannel); + void createNotificationChannel( + AndroidNotificationChannel notificationChannel); void deleteNotificationChannel(String channelId); void show(AndroidNotificationData data); diff --git a/flutter_local_notifications/test/android_flutter_local_notifications_test.dart b/flutter_local_notifications/test/android_flutter_local_notifications_test.dart deleted file mode 100644 index ebfc62797..000000000 --- a/flutter_local_notifications/test/android_flutter_local_notifications_test.dart +++ /dev/null @@ -1,2774 +0,0 @@ -// ignore: unnecessary_import -import 'dart:typed_data'; - -import 'package:clock/clock.dart'; -import 'package:flutter/foundation.dart'; -import 'package:flutter/material.dart'; -import 'package:flutter/services.dart'; -import 'package:flutter_local_notifications/flutter_local_notifications.dart'; -import 'package:flutter_local_notifications/src/platform_specifics/android/enums.dart'; -import 'package:flutter_test/flutter_test.dart'; -import 'package:timezone/data/latest.dart' as tz; -import 'package:timezone/timezone.dart' as tz; - -import 'utils/date_formatter.dart'; - -void main() { - AndroidFlutterLocalNotificationsPlugin.registerWith(); - TestWidgetsFlutterBinding.ensureInitialized(); - late FlutterLocalNotificationsPlugin flutterLocalNotificationsPlugin; - - group('Android', () { - const MethodChannel channel = - MethodChannel('dexterous.com/flutter/local_notifications'); - final List log = []; - - setUp(() { - debugDefaultTargetPlatformOverride = TargetPlatform.android; - flutterLocalNotificationsPlugin = FlutterLocalNotificationsPlugin(); - TestDefaultBinaryMessengerBinding.instance.defaultBinaryMessenger - .setMockMethodCallHandler(channel, (MethodCall methodCall) async { - log.add(methodCall); - if (methodCall.method == 'initialize') { - return true; - } else if (methodCall.method == 'pendingNotificationRequests') { - return >[]; - } else if (methodCall.method == 'getActiveNotifications') { - return >[]; - } else if (methodCall.method == 'getNotificationAppLaunchDetails') { - return null; - } - return null; - }); - }); - - tearDown(() { - log.clear(); - }); - - test('initialize', () async { - const AndroidInitializationSettings androidInitializationSettings = - AndroidInitializationSettings('app_icon'); - const InitializationSettings initializationSettings = - InitializationSettings(android: androidInitializationSettings); - await flutterLocalNotificationsPlugin.initialize(initializationSettings); - expect(log, [ - isMethodCall('initialize', arguments: { - 'defaultIcon': 'app_icon', - }) - ]); - }); - - test('show without Android-specific details', () async { - const AndroidInitializationSettings androidInitializationSettings = - AndroidInitializationSettings('app_icon'); - const InitializationSettings initializationSettings = - InitializationSettings(android: androidInitializationSettings); - await flutterLocalNotificationsPlugin.initialize(initializationSettings); - await flutterLocalNotificationsPlugin.show( - 1, 'notification title', 'notification body', null); - expect( - log.last, - isMethodCall('show', arguments: { - 'id': 1, - 'title': 'notification title', - 'body': 'notification body', - 'payload': '', - 'platformSpecifics': null, - })); - }); - - test('show with Android actions', () async { - const AndroidNotificationDetails androidNotificationDetails = - AndroidNotificationDetails( - 'channelId', - 'channelName', - channelDescription: 'channelDescription', - actions: [ - AndroidNotificationAction( - 'action1', - 'Action 1', - titleColor: Color.fromARGB(255, 0, 127, 16), - contextual: true, - showsUserInterface: true, - allowGeneratedReplies: true, - cancelNotification: false, - ), - AndroidNotificationAction( - 'action2', - 'Action 2', - titleColor: Color.fromARGB(255, 0, 127, 16), - inputs: [ - AndroidNotificationActionInput( - choices: ['choice1', 'choice2'], - label: 'Select something', - allowedMimeTypes: {'text/plain'}, - ), - ], - ) - ], - ); - - await flutterLocalNotificationsPlugin.show( - 1, - 'notification title', - 'notification body', - const NotificationDetails(android: androidNotificationDetails), - ); - expect( - log.last, - isMethodCall( - 'show', - arguments: { - 'id': 1, - 'title': 'notification title', - 'body': 'notification body', - 'payload': '', - 'platformSpecifics': { - 'icon': null, - 'channelId': 'channelId', - 'channelName': 'channelName', - 'channelDescription': 'channelDescription', - 'channelShowBadge': true, - 'channelAction': - AndroidNotificationChannelAction.createIfNotExists.index, - 'importance': Importance.defaultImportance.value, - 'priority': Priority.defaultPriority.value, - 'playSound': true, - 'enableVibration': true, - 'vibrationPattern': null, - 'groupKey': null, - 'setAsGroupSummary': false, - 'groupAlertBehavior': GroupAlertBehavior.all.index, - 'autoCancel': true, - 'ongoing': false, - 'silent': false, - 'colorAlpha': null, - 'colorRed': null, - 'colorGreen': null, - 'colorBlue': null, - 'onlyAlertOnce': false, - 'showWhen': true, - 'when': null, - 'usesChronometer': false, - 'chronometerCountDown': false, - 'showProgress': false, - 'maxProgress': 0, - 'progress': 0, - 'indeterminate': false, - 'enableLights': false, - 'ledColorAlpha': null, - 'ledColorRed': null, - 'ledColorGreen': null, - 'ledColorBlue': null, - 'ledOnMs': null, - 'ledOffMs': null, - 'ticker': null, - 'visibility': null, - 'timeoutAfter': null, - 'category': null, - 'additionalFlags': null, - 'fullScreenIntent': false, - 'shortcutId': null, - 'subText': null, - 'style': AndroidNotificationStyle.defaultStyle.index, - 'styleInformation': { - 'htmlFormatContent': false, - 'htmlFormatTitle': false, - }, - 'tag': null, - 'colorized': false, - 'number': null, - 'audioAttributesUsage': 5, - 'actions': >[ - { - 'id': 'action1', - 'title': 'Action 1', - 'titleColorAlpha': 255, - 'titleColorRed': 0, - 'titleColorGreen': 127, - 'titleColorBlue': 16, - 'contextual': true, - 'showsUserInterface': true, - 'allowGeneratedReplies': true, - 'inputs': [], - 'cancelNotification': false - }, - { - 'id': 'action2', - 'title': 'Action 2', - 'titleColorAlpha': 255, - 'titleColorRed': 0, - 'titleColorGreen': 127, - 'titleColorBlue': 16, - 'contextual': false, - 'showsUserInterface': false, - 'allowGeneratedReplies': false, - 'inputs': >[ - { - 'choices': ['choice1', 'choice2'], - 'allowFreeFormInput': true, - 'label': 'Select something', - 'allowedMimeType': ['text/plain'] - } - ], - 'cancelNotification': true, - } - ], - }, - }, - ), - ); - }); - - test('show with default Android-specific details', () async { - const AndroidInitializationSettings androidInitializationSettings = - AndroidInitializationSettings('app_icon'); - const InitializationSettings initializationSettings = - InitializationSettings(android: androidInitializationSettings); - await flutterLocalNotificationsPlugin.initialize(initializationSettings); - const AndroidNotificationDetails androidNotificationDetails = - AndroidNotificationDetails( - 'channelId', - 'channelName', - channelDescription: 'channelDescription', - ); - - await flutterLocalNotificationsPlugin.show( - 1, - 'notification title', - 'notification body', - const NotificationDetails(android: androidNotificationDetails)); - expect( - log.last, - isMethodCall('show', arguments: { - 'id': 1, - 'title': 'notification title', - 'body': 'notification body', - 'payload': '', - 'platformSpecifics': { - 'icon': null, - 'channelId': 'channelId', - 'channelName': 'channelName', - 'channelDescription': 'channelDescription', - 'channelShowBadge': true, - 'channelAction': - AndroidNotificationChannelAction.createIfNotExists.index, - 'importance': Importance.defaultImportance.value, - 'priority': Priority.defaultPriority.value, - 'playSound': true, - 'enableVibration': true, - 'vibrationPattern': null, - 'groupKey': null, - 'setAsGroupSummary': false, - 'groupAlertBehavior': GroupAlertBehavior.all.index, - 'autoCancel': true, - 'ongoing': false, - 'silent': false, - 'colorAlpha': null, - 'colorRed': null, - 'colorGreen': null, - 'colorBlue': null, - 'onlyAlertOnce': false, - 'showWhen': true, - 'when': null, - 'usesChronometer': false, - 'chronometerCountDown': false, - 'showProgress': false, - 'maxProgress': 0, - 'progress': 0, - 'indeterminate': false, - 'enableLights': false, - 'ledColorAlpha': null, - 'ledColorRed': null, - 'ledColorGreen': null, - 'ledColorBlue': null, - 'ledOnMs': null, - 'ledOffMs': null, - 'ticker': null, - 'visibility': null, - 'timeoutAfter': null, - 'category': null, - 'additionalFlags': null, - 'fullScreenIntent': false, - 'shortcutId': null, - 'subText': null, - 'style': AndroidNotificationStyle.defaultStyle.index, - 'styleInformation': { - 'htmlFormatContent': false, - 'htmlFormatTitle': false, - }, - 'tag': null, - 'colorized': false, - 'number': null, - 'audioAttributesUsage': 5, - }, - })); - }); - - test('show with default Android-specific details and additional flags', - () async { - const AndroidInitializationSettings androidInitializationSettings = - AndroidInitializationSettings('app_icon'); - const InitializationSettings initializationSettings = - InitializationSettings(android: androidInitializationSettings); - await flutterLocalNotificationsPlugin.initialize(initializationSettings); - final AndroidNotificationDetails androidNotificationDetails = - AndroidNotificationDetails('channelId', 'channelName', - channelDescription: 'channelDescription', - additionalFlags: Int32List.fromList([4, 32])); - - await flutterLocalNotificationsPlugin.show( - 1, - 'notification title', - 'notification body', - NotificationDetails(android: androidNotificationDetails)); - expect( - log.last, - isMethodCall('show', arguments: { - 'id': 1, - 'title': 'notification title', - 'body': 'notification body', - 'payload': '', - 'platformSpecifics': { - 'icon': null, - 'channelId': 'channelId', - 'channelName': 'channelName', - 'channelDescription': 'channelDescription', - 'channelShowBadge': true, - 'channelAction': - AndroidNotificationChannelAction.createIfNotExists.index, - 'importance': Importance.defaultImportance.value, - 'priority': Priority.defaultPriority.value, - 'playSound': true, - 'enableVibration': true, - 'vibrationPattern': null, - 'groupKey': null, - 'setAsGroupSummary': false, - 'groupAlertBehavior': GroupAlertBehavior.all.index, - 'autoCancel': true, - 'ongoing': false, - 'silent': false, - 'colorAlpha': null, - 'colorRed': null, - 'colorGreen': null, - 'colorBlue': null, - 'onlyAlertOnce': false, - 'showWhen': true, - 'when': null, - 'usesChronometer': false, - 'chronometerCountDown': false, - 'showProgress': false, - 'maxProgress': 0, - 'progress': 0, - 'indeterminate': false, - 'enableLights': false, - 'ledColorAlpha': null, - 'ledColorRed': null, - 'ledColorGreen': null, - 'ledColorBlue': null, - 'ledOnMs': null, - 'ledOffMs': null, - 'ticker': null, - 'visibility': null, - 'timeoutAfter': null, - 'category': null, - 'fullScreenIntent': false, - 'shortcutId': null, - 'subText': null, - 'additionalFlags': [4, 32], - 'style': AndroidNotificationStyle.defaultStyle.index, - 'styleInformation': { - 'htmlFormatContent': false, - 'htmlFormatTitle': false, - }, - 'tag': null, - 'colorized': false, - 'number': null, - 'audioAttributesUsage': 5, - }, - })); - }); - - test( - 'show with default Android-specific details with a timestamp specified', - () async { - const AndroidInitializationSettings androidInitializationSettings = - AndroidInitializationSettings('app_icon'); - const InitializationSettings initializationSettings = - InitializationSettings(android: androidInitializationSettings); - await flutterLocalNotificationsPlugin.initialize(initializationSettings); - final int timestamp = clock.now().millisecondsSinceEpoch; - - final AndroidNotificationDetails androidNotificationDetails = - AndroidNotificationDetails('channelId', 'channelName', - channelDescription: 'channelDescription', when: timestamp); - await flutterLocalNotificationsPlugin.show( - 1, - 'notification title', - 'notification body', - NotificationDetails(android: androidNotificationDetails)); - expect( - log.last, - isMethodCall('show', arguments: { - 'id': 1, - 'title': 'notification title', - 'body': 'notification body', - 'payload': '', - 'platformSpecifics': { - 'icon': null, - 'channelId': 'channelId', - 'channelName': 'channelName', - 'channelDescription': 'channelDescription', - 'channelShowBadge': true, - 'channelAction': - AndroidNotificationChannelAction.createIfNotExists.index, - 'importance': Importance.defaultImportance.value, - 'priority': Priority.defaultPriority.value, - 'playSound': true, - 'enableVibration': true, - 'vibrationPattern': null, - 'groupKey': null, - 'setAsGroupSummary': false, - 'groupAlertBehavior': GroupAlertBehavior.all.index, - 'autoCancel': true, - 'ongoing': false, - 'silent': false, - 'colorAlpha': null, - 'colorRed': null, - 'colorGreen': null, - 'colorBlue': null, - 'onlyAlertOnce': false, - 'showWhen': true, - 'when': timestamp, - 'usesChronometer': false, - 'chronometerCountDown': false, - 'showProgress': false, - 'maxProgress': 0, - 'progress': 0, - 'indeterminate': false, - 'enableLights': false, - 'ledColorAlpha': null, - 'ledColorRed': null, - 'ledColorGreen': null, - 'ledColorBlue': null, - 'ledOnMs': null, - 'ledOffMs': null, - 'ticker': null, - 'visibility': null, - 'timeoutAfter': null, - 'category': null, - 'additionalFlags': null, - 'fullScreenIntent': false, - 'shortcutId': null, - 'subText': null, - 'style': AndroidNotificationStyle.defaultStyle.index, - 'styleInformation': { - 'htmlFormatContent': false, - 'htmlFormatTitle': false, - }, - 'tag': null, - 'colorized': false, - 'number': null, - 'audioAttributesUsage': 5, - }, - })); - }); - - test('show with default Android-specific details with a chronometer', - () async { - const AndroidInitializationSettings androidInitializationSettings = - AndroidInitializationSettings('app_icon'); - const InitializationSettings initializationSettings = - InitializationSettings(android: androidInitializationSettings); - await flutterLocalNotificationsPlugin.initialize(initializationSettings); - final int timestamp = clock.now().millisecondsSinceEpoch; - - final AndroidNotificationDetails androidNotificationDetails = - AndroidNotificationDetails('channelId', 'channelName', - channelDescription: 'channelDescription', - when: timestamp, - usesChronometer: true); - await flutterLocalNotificationsPlugin.show( - 1, - 'notification title', - 'notification body', - NotificationDetails(android: androidNotificationDetails)); - expect( - log.last, - isMethodCall('show', arguments: { - 'id': 1, - 'title': 'notification title', - 'body': 'notification body', - 'payload': '', - 'platformSpecifics': { - 'icon': null, - 'channelId': 'channelId', - 'channelName': 'channelName', - 'channelDescription': 'channelDescription', - 'channelShowBadge': true, - 'channelAction': - AndroidNotificationChannelAction.createIfNotExists.index, - 'importance': Importance.defaultImportance.value, - 'priority': Priority.defaultPriority.value, - 'playSound': true, - 'enableVibration': true, - 'vibrationPattern': null, - 'groupKey': null, - 'setAsGroupSummary': false, - 'groupAlertBehavior': GroupAlertBehavior.all.index, - 'autoCancel': true, - 'ongoing': false, - 'silent': false, - 'colorAlpha': null, - 'colorRed': null, - 'colorGreen': null, - 'colorBlue': null, - 'onlyAlertOnce': false, - 'showWhen': true, - 'when': timestamp, - 'usesChronometer': true, - 'chronometerCountDown': false, - 'showProgress': false, - 'maxProgress': 0, - 'progress': 0, - 'indeterminate': false, - 'enableLights': false, - 'ledColorAlpha': null, - 'ledColorRed': null, - 'ledColorGreen': null, - 'ledColorBlue': null, - 'ledOnMs': null, - 'ledOffMs': null, - 'ticker': null, - 'visibility': null, - 'timeoutAfter': null, - 'category': null, - 'additionalFlags': null, - 'fullScreenIntent': false, - 'shortcutId': null, - 'subText': null, - 'style': AndroidNotificationStyle.defaultStyle.index, - 'styleInformation': { - 'htmlFormatContent': false, - 'htmlFormatTitle': false, - }, - 'tag': null, - 'colorized': false, - 'number': null, - 'audioAttributesUsage': 5, - }, - })); - }); - - test( - 'show with default Android-specific details and custom sound from raw ' - 'resource', () async { - const AndroidInitializationSettings androidInitializationSettings = - AndroidInitializationSettings('app_icon'); - const InitializationSettings initializationSettings = - InitializationSettings(android: androidInitializationSettings); - await flutterLocalNotificationsPlugin.initialize(initializationSettings); - const AndroidNotificationDetails androidNotificationDetails = - AndroidNotificationDetails( - 'channelId', - 'channelName', - channelDescription: 'channelDescription', - sound: RawResourceAndroidNotificationSound('sound.mp3'), - ); - - await flutterLocalNotificationsPlugin.show( - 1, - 'notification title', - 'notification body', - const NotificationDetails(android: androidNotificationDetails)); - expect( - log.last, - isMethodCall('show', arguments: { - 'id': 1, - 'title': 'notification title', - 'body': 'notification body', - 'payload': '', - 'platformSpecifics': { - 'icon': null, - 'channelId': 'channelId', - 'channelName': 'channelName', - 'channelDescription': 'channelDescription', - 'channelShowBadge': true, - 'channelAction': - AndroidNotificationChannelAction.createIfNotExists.index, - 'importance': Importance.defaultImportance.value, - 'priority': Priority.defaultPriority.value, - 'playSound': true, - 'sound': 'sound.mp3', - 'soundSource': AndroidNotificationSoundSource.rawResource.index, - 'enableVibration': true, - 'vibrationPattern': null, - 'groupKey': null, - 'setAsGroupSummary': false, - 'groupAlertBehavior': GroupAlertBehavior.all.index, - 'autoCancel': true, - 'ongoing': false, - 'silent': false, - 'colorAlpha': null, - 'colorRed': null, - 'colorGreen': null, - 'colorBlue': null, - 'onlyAlertOnce': false, - 'showWhen': true, - 'when': null, - 'usesChronometer': false, - 'chronometerCountDown': false, - 'showProgress': false, - 'maxProgress': 0, - 'progress': 0, - 'indeterminate': false, - 'enableLights': false, - 'ledColorAlpha': null, - 'ledColorRed': null, - 'ledColorGreen': null, - 'ledColorBlue': null, - 'ledOnMs': null, - 'ledOffMs': null, - 'ticker': null, - 'visibility': null, - 'timeoutAfter': null, - 'category': null, - 'additionalFlags': null, - 'fullScreenIntent': false, - 'shortcutId': null, - 'subText': null, - 'style': AndroidNotificationStyle.defaultStyle.index, - 'styleInformation': { - 'htmlFormatContent': false, - 'htmlFormatTitle': false, - }, - 'tag': null, - 'colorized': false, - 'number': null, - 'audioAttributesUsage': 5, - }, - })); - }); - - test('show with default Android-specific details and custom sound from uri', - () async { - const AndroidInitializationSettings androidInitializationSettings = - AndroidInitializationSettings('app_icon'); - const InitializationSettings initializationSettings = - InitializationSettings(android: androidInitializationSettings); - await flutterLocalNotificationsPlugin.initialize(initializationSettings); - const AndroidNotificationDetails androidNotificationDetails = - AndroidNotificationDetails( - 'channelId', - 'channelName', - channelDescription: 'channelDescription', - sound: UriAndroidNotificationSound('uri'), - ); - - await flutterLocalNotificationsPlugin.show( - 1, - 'notification title', - 'notification body', - const NotificationDetails(android: androidNotificationDetails)); - expect( - log.last, - isMethodCall('show', arguments: { - 'id': 1, - 'title': 'notification title', - 'body': 'notification body', - 'payload': '', - 'platformSpecifics': { - 'icon': null, - 'channelId': 'channelId', - 'channelName': 'channelName', - 'channelDescription': 'channelDescription', - 'channelShowBadge': true, - 'channelAction': - AndroidNotificationChannelAction.createIfNotExists.index, - 'importance': Importance.defaultImportance.value, - 'priority': Priority.defaultPriority.value, - 'playSound': true, - 'sound': 'uri', - 'soundSource': AndroidNotificationSoundSource.uri.index, - 'enableVibration': true, - 'vibrationPattern': null, - 'groupKey': null, - 'setAsGroupSummary': false, - 'groupAlertBehavior': GroupAlertBehavior.all.index, - 'autoCancel': true, - 'ongoing': false, - 'silent': false, - 'colorAlpha': null, - 'colorRed': null, - 'colorGreen': null, - 'colorBlue': null, - 'onlyAlertOnce': false, - 'showWhen': true, - 'when': null, - 'usesChronometer': false, - 'chronometerCountDown': false, - 'showProgress': false, - 'maxProgress': 0, - 'progress': 0, - 'indeterminate': false, - 'enableLights': false, - 'ledColorAlpha': null, - 'ledColorRed': null, - 'ledColorGreen': null, - 'ledColorBlue': null, - 'ledOnMs': null, - 'ledOffMs': null, - 'ticker': null, - 'visibility': null, - 'timeoutAfter': null, - 'category': null, - 'additionalFlags': null, - 'fullScreenIntent': false, - 'shortcutId': null, - 'subText': null, - 'style': AndroidNotificationStyle.defaultStyle.index, - 'styleInformation': { - 'htmlFormatContent': false, - 'htmlFormatTitle': false, - }, - 'tag': null, - 'colorized': false, - 'number': null, - 'audioAttributesUsage': 5, - }, - })); - }); - - test('show with default Android-specific details and silent enabled', - () async { - const AndroidInitializationSettings androidInitializationSettings = - AndroidInitializationSettings('app_icon'); - const InitializationSettings initializationSettings = - InitializationSettings(android: androidInitializationSettings); - await flutterLocalNotificationsPlugin.initialize(initializationSettings); - const AndroidNotificationDetails androidNotificationDetails = - AndroidNotificationDetails( - 'channelId', - 'channelName', - channelDescription: 'channelDescription', - silent: true, - ); - - await flutterLocalNotificationsPlugin.show( - 1, - 'notification title', - 'notification body', - const NotificationDetails(android: androidNotificationDetails)); - expect( - log.last, - isMethodCall('show', arguments: { - 'id': 1, - 'title': 'notification title', - 'body': 'notification body', - 'payload': '', - 'platformSpecifics': { - 'icon': null, - 'channelId': 'channelId', - 'channelName': 'channelName', - 'channelDescription': 'channelDescription', - 'channelShowBadge': true, - 'channelAction': - AndroidNotificationChannelAction.createIfNotExists.index, - 'importance': Importance.defaultImportance.value, - 'priority': Priority.defaultPriority.value, - 'playSound': true, - 'enableVibration': true, - 'vibrationPattern': null, - 'groupKey': null, - 'setAsGroupSummary': false, - 'groupAlertBehavior': GroupAlertBehavior.all.index, - 'autoCancel': true, - 'ongoing': false, - 'silent': true, - 'colorAlpha': null, - 'colorRed': null, - 'colorGreen': null, - 'colorBlue': null, - 'onlyAlertOnce': false, - 'showWhen': true, - 'when': null, - 'usesChronometer': false, - 'chronometerCountDown': false, - 'showProgress': false, - 'maxProgress': 0, - 'progress': 0, - 'indeterminate': false, - 'enableLights': false, - 'ledColorAlpha': null, - 'ledColorRed': null, - 'ledColorGreen': null, - 'ledColorBlue': null, - 'ledOnMs': null, - 'ledOffMs': null, - 'ticker': null, - 'visibility': null, - 'timeoutAfter': null, - 'category': null, - 'additionalFlags': null, - 'fullScreenIntent': false, - 'shortcutId': null, - 'subText': null, - 'style': AndroidNotificationStyle.defaultStyle.index, - 'styleInformation': { - 'htmlFormatContent': false, - 'htmlFormatTitle': false, - }, - 'tag': null, - 'colorized': false, - 'number': null, - 'audioAttributesUsage': 5, - }, - })); - }); - - test( - 'show with default Android-specific details and html formatted title and content/body', - () async { - const AndroidInitializationSettings androidInitializationSettings = - AndroidInitializationSettings('app_icon'); - const InitializationSettings initializationSettings = - InitializationSettings(android: androidInitializationSettings); - await flutterLocalNotificationsPlugin.initialize(initializationSettings); - const AndroidNotificationDetails androidNotificationDetails = - AndroidNotificationDetails( - 'channelId', - 'channelName', - channelDescription: 'channelDescription', - styleInformation: DefaultStyleInformation(true, true), - ); - - await flutterLocalNotificationsPlugin.show( - 1, - 'notification title', - 'notification body', - const NotificationDetails(android: androidNotificationDetails)); - expect( - log.last, - isMethodCall('show', arguments: { - 'id': 1, - 'title': 'notification title', - 'body': 'notification body', - 'payload': '', - 'platformSpecifics': { - 'icon': null, - 'channelId': 'channelId', - 'channelName': 'channelName', - 'channelDescription': 'channelDescription', - 'channelShowBadge': true, - 'channelAction': - AndroidNotificationChannelAction.createIfNotExists.index, - 'importance': Importance.defaultImportance.value, - 'priority': Priority.defaultPriority.value, - 'playSound': true, - 'enableVibration': true, - 'vibrationPattern': null, - 'groupKey': null, - 'setAsGroupSummary': false, - 'groupAlertBehavior': GroupAlertBehavior.all.index, - 'autoCancel': true, - 'ongoing': false, - 'silent': false, - 'colorAlpha': null, - 'colorRed': null, - 'colorGreen': null, - 'colorBlue': null, - 'onlyAlertOnce': false, - 'showWhen': true, - 'when': null, - 'usesChronometer': false, - 'chronometerCountDown': false, - 'showProgress': false, - 'maxProgress': 0, - 'progress': 0, - 'indeterminate': false, - 'enableLights': false, - 'ledColorAlpha': null, - 'ledColorRed': null, - 'ledColorGreen': null, - 'ledColorBlue': null, - 'ledOnMs': null, - 'ledOffMs': null, - 'ticker': null, - 'visibility': null, - 'timeoutAfter': null, - 'category': null, - 'additionalFlags': null, - 'fullScreenIntent': false, - 'shortcutId': null, - 'subText': null, - 'style': AndroidNotificationStyle.defaultStyle.index, - 'styleInformation': { - 'htmlFormatContent': true, - 'htmlFormatTitle': true, - }, - 'tag': null, - 'colorized': false, - 'number': null, - 'audioAttributesUsage': 5, - }, - })); - }); - - test( - 'show with default Android big picture style settings using a drawable ' - 'resource', () async { - const AndroidInitializationSettings androidInitializationSettings = - AndroidInitializationSettings('app_icon'); - const InitializationSettings initializationSettings = - InitializationSettings(android: androidInitializationSettings); - await flutterLocalNotificationsPlugin.initialize(initializationSettings); - const AndroidNotificationDetails androidNotificationDetails = - AndroidNotificationDetails( - 'channelId', - 'channelName', - channelDescription: 'channelDescription', - styleInformation: BigPictureStyleInformation( - DrawableResourceAndroidBitmap('bigPictureDrawable'), - ), - ); - - await flutterLocalNotificationsPlugin.show( - 1, - 'notification title', - 'notification body', - const NotificationDetails(android: androidNotificationDetails)); - expect( - log.last, - isMethodCall('show', arguments: { - 'id': 1, - 'title': 'notification title', - 'body': 'notification body', - 'payload': '', - 'platformSpecifics': { - 'icon': null, - 'channelId': 'channelId', - 'channelName': 'channelName', - 'channelDescription': 'channelDescription', - 'channelShowBadge': true, - 'channelAction': - AndroidNotificationChannelAction.createIfNotExists.index, - 'importance': Importance.defaultImportance.value, - 'priority': Priority.defaultPriority.value, - 'playSound': true, - 'enableVibration': true, - 'vibrationPattern': null, - 'groupKey': null, - 'setAsGroupSummary': false, - 'groupAlertBehavior': GroupAlertBehavior.all.index, - 'autoCancel': true, - 'ongoing': false, - 'silent': false, - 'colorAlpha': null, - 'colorRed': null, - 'colorGreen': null, - 'colorBlue': null, - 'onlyAlertOnce': false, - 'showWhen': true, - 'when': null, - 'usesChronometer': false, - 'chronometerCountDown': false, - 'showProgress': false, - 'maxProgress': 0, - 'progress': 0, - 'indeterminate': false, - 'enableLights': false, - 'ledColorAlpha': null, - 'ledColorRed': null, - 'ledColorGreen': null, - 'ledColorBlue': null, - 'ledOnMs': null, - 'ledOffMs': null, - 'ticker': null, - 'visibility': null, - 'timeoutAfter': null, - 'category': null, - 'additionalFlags': null, - 'fullScreenIntent': false, - 'shortcutId': null, - 'subText': null, - 'style': AndroidNotificationStyle.bigPicture.index, - 'styleInformation': { - 'htmlFormatContent': false, - 'htmlFormatTitle': false, - 'bigPicture': 'bigPictureDrawable', - 'bigPictureBitmapSource': AndroidBitmapSource.drawable.index, - 'contentTitle': null, - 'summaryText': null, - 'htmlFormatContentTitle': false, - 'htmlFormatSummaryText': false, - 'hideExpandedLargeIcon': false, - }, - 'tag': null, - 'colorized': false, - 'number': null, - 'audioAttributesUsage': 5, - }, - })); - }); - - test( - 'show with non-default Android big picture style settings using a ' - 'drawable resource', () async { - const AndroidInitializationSettings androidInitializationSettings = - AndroidInitializationSettings('app_icon'); - const InitializationSettings initializationSettings = - InitializationSettings(android: androidInitializationSettings); - await flutterLocalNotificationsPlugin.initialize(initializationSettings); - const AndroidNotificationDetails androidNotificationDetails = - AndroidNotificationDetails( - 'channelId', - 'channelName', - channelDescription: 'channelDescription', - styleInformation: BigPictureStyleInformation( - DrawableResourceAndroidBitmap('bigPictureDrawable'), - contentTitle: 'contentTitle', - summaryText: 'summaryText', - htmlFormatContentTitle: true, - htmlFormatSummaryText: true, - largeIcon: DrawableResourceAndroidBitmap('largeDrawableIcon'), - htmlFormatContent: true, - htmlFormatTitle: true, - hideExpandedLargeIcon: true, - ), - ); - - await flutterLocalNotificationsPlugin.show( - 1, - 'notification title', - 'notification body', - const NotificationDetails(android: androidNotificationDetails)); - expect( - log.last, - isMethodCall('show', arguments: { - 'id': 1, - 'title': 'notification title', - 'body': 'notification body', - 'payload': '', - 'platformSpecifics': { - 'icon': null, - 'channelId': 'channelId', - 'channelName': 'channelName', - 'channelDescription': 'channelDescription', - 'channelShowBadge': true, - 'channelAction': - AndroidNotificationChannelAction.createIfNotExists.index, - 'importance': Importance.defaultImportance.value, - 'priority': Priority.defaultPriority.value, - 'playSound': true, - 'enableVibration': true, - 'vibrationPattern': null, - 'groupKey': null, - 'setAsGroupSummary': false, - 'groupAlertBehavior': GroupAlertBehavior.all.index, - 'autoCancel': true, - 'ongoing': false, - 'silent': false, - 'colorAlpha': null, - 'colorRed': null, - 'colorGreen': null, - 'colorBlue': null, - 'onlyAlertOnce': false, - 'showWhen': true, - 'when': null, - 'usesChronometer': false, - 'chronometerCountDown': false, - 'showProgress': false, - 'maxProgress': 0, - 'progress': 0, - 'indeterminate': false, - 'enableLights': false, - 'ledColorAlpha': null, - 'ledColorRed': null, - 'ledColorGreen': null, - 'ledColorBlue': null, - 'ledOnMs': null, - 'ledOffMs': null, - 'ticker': null, - 'visibility': null, - 'timeoutAfter': null, - 'category': null, - 'additionalFlags': null, - 'fullScreenIntent': false, - 'shortcutId': null, - 'subText': null, - 'style': AndroidNotificationStyle.bigPicture.index, - 'styleInformation': { - 'htmlFormatContent': true, - 'htmlFormatTitle': true, - 'bigPicture': 'bigPictureDrawable', - 'bigPictureBitmapSource': AndroidBitmapSource.drawable.index, - 'largeIcon': 'largeDrawableIcon', - 'largeIconBitmapSource': AndroidBitmapSource.drawable.index, - 'contentTitle': 'contentTitle', - 'summaryText': 'summaryText', - 'htmlFormatContentTitle': true, - 'htmlFormatSummaryText': true, - 'hideExpandedLargeIcon': true, - }, - 'tag': null, - 'colorized': false, - 'number': null, - 'audioAttributesUsage': 5, - }, - })); - }); - - test( - 'show with default Android big picture style settings using a file ' - 'path', () async { - const AndroidInitializationSettings androidInitializationSettings = - AndroidInitializationSettings('app_icon'); - const InitializationSettings initializationSettings = - InitializationSettings(android: androidInitializationSettings); - await flutterLocalNotificationsPlugin.initialize(initializationSettings); - const AndroidNotificationDetails androidNotificationDetails = - AndroidNotificationDetails( - 'channelId', - 'channelName', - channelDescription: 'channelDescription', - styleInformation: BigPictureStyleInformation( - FilePathAndroidBitmap('bigPictureFilePath'), - ), - ); - - await flutterLocalNotificationsPlugin.show( - 1, - 'notification title', - 'notification body', - const NotificationDetails(android: androidNotificationDetails)); - expect( - log.last, - isMethodCall('show', arguments: { - 'id': 1, - 'title': 'notification title', - 'body': 'notification body', - 'payload': '', - 'platformSpecifics': { - 'icon': null, - 'channelId': 'channelId', - 'channelName': 'channelName', - 'channelDescription': 'channelDescription', - 'channelShowBadge': true, - 'channelAction': - AndroidNotificationChannelAction.createIfNotExists.index, - 'importance': Importance.defaultImportance.value, - 'priority': Priority.defaultPriority.value, - 'playSound': true, - 'enableVibration': true, - 'vibrationPattern': null, - 'groupKey': null, - 'setAsGroupSummary': false, - 'groupAlertBehavior': GroupAlertBehavior.all.index, - 'autoCancel': true, - 'ongoing': false, - 'silent': false, - 'colorAlpha': null, - 'colorRed': null, - 'colorGreen': null, - 'colorBlue': null, - 'onlyAlertOnce': false, - 'showWhen': true, - 'when': null, - 'usesChronometer': false, - 'chronometerCountDown': false, - 'showProgress': false, - 'maxProgress': 0, - 'progress': 0, - 'indeterminate': false, - 'enableLights': false, - 'ledColorAlpha': null, - 'ledColorRed': null, - 'ledColorGreen': null, - 'ledColorBlue': null, - 'ledOnMs': null, - 'ledOffMs': null, - 'ticker': null, - 'visibility': null, - 'timeoutAfter': null, - 'category': null, - 'additionalFlags': null, - 'fullScreenIntent': false, - 'shortcutId': null, - 'subText': null, - 'style': AndroidNotificationStyle.bigPicture.index, - 'styleInformation': { - 'htmlFormatContent': false, - 'htmlFormatTitle': false, - 'bigPicture': 'bigPictureFilePath', - 'bigPictureBitmapSource': AndroidBitmapSource.filePath.index, - 'contentTitle': null, - 'summaryText': null, - 'htmlFormatContentTitle': false, - 'htmlFormatSummaryText': false, - 'hideExpandedLargeIcon': false, - }, - 'tag': null, - 'colorized': false, - 'number': null, - 'audioAttributesUsage': 5, - }, - })); - }); - - test( - 'show with non-default Android big picture style settings using a file ' - 'path', () async { - const AndroidInitializationSettings androidInitializationSettings = - AndroidInitializationSettings('app_icon'); - const InitializationSettings initializationSettings = - InitializationSettings(android: androidInitializationSettings); - await flutterLocalNotificationsPlugin.initialize(initializationSettings); - const AndroidNotificationDetails androidNotificationDetails = - AndroidNotificationDetails( - 'channelId', - 'channelName', - channelDescription: 'channelDescription', - styleInformation: BigPictureStyleInformation( - FilePathAndroidBitmap('bigPictureFilePath'), - contentTitle: 'contentTitle', - summaryText: 'summaryText', - htmlFormatContentTitle: true, - htmlFormatSummaryText: true, - largeIcon: FilePathAndroidBitmap('largeFilePathIcon'), - htmlFormatContent: true, - htmlFormatTitle: true, - hideExpandedLargeIcon: true, - ), - ); - - await flutterLocalNotificationsPlugin.show( - 1, - 'notification title', - 'notification body', - const NotificationDetails(android: androidNotificationDetails)); - expect( - log.last, - isMethodCall('show', arguments: { - 'id': 1, - 'title': 'notification title', - 'body': 'notification body', - 'payload': '', - 'platformSpecifics': { - 'icon': null, - 'channelId': 'channelId', - 'channelName': 'channelName', - 'channelDescription': 'channelDescription', - 'channelShowBadge': true, - 'channelAction': - AndroidNotificationChannelAction.createIfNotExists.index, - 'importance': Importance.defaultImportance.value, - 'priority': Priority.defaultPriority.value, - 'playSound': true, - 'enableVibration': true, - 'vibrationPattern': null, - 'groupKey': null, - 'setAsGroupSummary': false, - 'groupAlertBehavior': GroupAlertBehavior.all.index, - 'autoCancel': true, - 'ongoing': false, - 'silent': false, - 'colorAlpha': null, - 'colorRed': null, - 'colorGreen': null, - 'colorBlue': null, - 'onlyAlertOnce': false, - 'showWhen': true, - 'when': null, - 'usesChronometer': false, - 'chronometerCountDown': false, - 'showProgress': false, - 'maxProgress': 0, - 'progress': 0, - 'indeterminate': false, - 'enableLights': false, - 'ledColorAlpha': null, - 'ledColorRed': null, - 'ledColorGreen': null, - 'ledColorBlue': null, - 'ledOnMs': null, - 'ledOffMs': null, - 'ticker': null, - 'visibility': null, - 'timeoutAfter': null, - 'category': null, - 'additionalFlags': null, - 'fullScreenIntent': false, - 'shortcutId': null, - 'subText': null, - 'style': AndroidNotificationStyle.bigPicture.index, - 'styleInformation': { - 'htmlFormatContent': true, - 'htmlFormatTitle': true, - 'bigPicture': 'bigPictureFilePath', - 'bigPictureBitmapSource': AndroidBitmapSource.filePath.index, - 'largeIcon': 'largeFilePathIcon', - 'largeIconBitmapSource': AndroidBitmapSource.filePath.index, - 'contentTitle': 'contentTitle', - 'summaryText': 'summaryText', - 'htmlFormatContentTitle': true, - 'htmlFormatSummaryText': true, - 'hideExpandedLargeIcon': true, - }, - 'tag': null, - 'colorized': false, - 'number': null, - 'audioAttributesUsage': 5, - }, - })); - }); - - test('show with default Android inbox style settings', () async { - const AndroidInitializationSettings androidInitializationSettings = - AndroidInitializationSettings('app_icon'); - const InitializationSettings initializationSettings = - InitializationSettings(android: androidInitializationSettings); - await flutterLocalNotificationsPlugin.initialize(initializationSettings); - const AndroidNotificationDetails androidNotificationDetails = - AndroidNotificationDetails( - 'channelId', - 'channelName', - channelDescription: 'channelDescription', - styleInformation: InboxStyleInformation( - ['line1'], - ), - ); - - await flutterLocalNotificationsPlugin.show( - 1, - 'notification title', - 'notification body', - const NotificationDetails(android: androidNotificationDetails)); - expect( - log.last, - isMethodCall('show', arguments: { - 'id': 1, - 'title': 'notification title', - 'body': 'notification body', - 'payload': '', - 'platformSpecifics': { - 'icon': null, - 'channelId': 'channelId', - 'channelName': 'channelName', - 'channelDescription': 'channelDescription', - 'channelShowBadge': true, - 'channelAction': - AndroidNotificationChannelAction.createIfNotExists.index, - 'importance': Importance.defaultImportance.value, - 'priority': Priority.defaultPriority.value, - 'playSound': true, - 'enableVibration': true, - 'vibrationPattern': null, - 'groupKey': null, - 'setAsGroupSummary': false, - 'groupAlertBehavior': GroupAlertBehavior.all.index, - 'autoCancel': true, - 'ongoing': false, - 'silent': false, - 'colorAlpha': null, - 'colorRed': null, - 'colorGreen': null, - 'colorBlue': null, - 'onlyAlertOnce': false, - 'showWhen': true, - 'when': null, - 'usesChronometer': false, - 'chronometerCountDown': false, - 'showProgress': false, - 'maxProgress': 0, - 'progress': 0, - 'indeterminate': false, - 'enableLights': false, - 'ledColorAlpha': null, - 'ledColorRed': null, - 'ledColorGreen': null, - 'ledColorBlue': null, - 'ledOnMs': null, - 'ledOffMs': null, - 'ticker': null, - 'visibility': null, - 'timeoutAfter': null, - 'category': null, - 'additionalFlags': null, - 'fullScreenIntent': false, - 'shortcutId': null, - 'subText': null, - 'style': AndroidNotificationStyle.inbox.index, - 'styleInformation': { - 'htmlFormatContent': false, - 'htmlFormatTitle': false, - 'lines': ['line1'], - 'contentTitle': null, - 'summaryText': null, - 'htmlFormatContentTitle': false, - 'htmlFormatSummaryText': false, - 'htmlFormatLines': false, - }, - 'tag': null, - 'colorized': false, - 'number': null, - 'audioAttributesUsage': 5, - }, - })); - }); - - test('show with non-default Android inbox style settings', () async { - const AndroidInitializationSettings androidInitializationSettings = - AndroidInitializationSettings('app_icon'); - const InitializationSettings initializationSettings = - InitializationSettings(android: androidInitializationSettings); - await flutterLocalNotificationsPlugin.initialize(initializationSettings); - const AndroidNotificationDetails androidNotificationDetails = - AndroidNotificationDetails( - 'channelId', - 'channelName', - channelDescription: 'channelDescription', - styleInformation: InboxStyleInformation( - ['line1'], - htmlFormatLines: true, - htmlFormatContent: true, - htmlFormatContentTitle: true, - htmlFormatSummaryText: true, - htmlFormatTitle: true, - contentTitle: 'contentTitle', - summaryText: 'summaryText', - ), - ); - - await flutterLocalNotificationsPlugin.show( - 1, - 'notification title', - 'notification body', - const NotificationDetails(android: androidNotificationDetails)); - expect( - log.last, - isMethodCall('show', arguments: { - 'id': 1, - 'title': 'notification title', - 'body': 'notification body', - 'payload': '', - 'platformSpecifics': { - 'icon': null, - 'channelId': 'channelId', - 'channelName': 'channelName', - 'channelDescription': 'channelDescription', - 'channelShowBadge': true, - 'channelAction': - AndroidNotificationChannelAction.createIfNotExists.index, - 'importance': Importance.defaultImportance.value, - 'priority': Priority.defaultPriority.value, - 'playSound': true, - 'enableVibration': true, - 'vibrationPattern': null, - 'groupKey': null, - 'setAsGroupSummary': false, - 'groupAlertBehavior': GroupAlertBehavior.all.index, - 'autoCancel': true, - 'ongoing': false, - 'silent': false, - 'colorAlpha': null, - 'colorRed': null, - 'colorGreen': null, - 'colorBlue': null, - 'onlyAlertOnce': false, - 'showWhen': true, - 'when': null, - 'usesChronometer': false, - 'chronometerCountDown': false, - 'showProgress': false, - 'maxProgress': 0, - 'progress': 0, - 'indeterminate': false, - 'enableLights': false, - 'ledColorAlpha': null, - 'ledColorRed': null, - 'ledColorGreen': null, - 'ledColorBlue': null, - 'ledOnMs': null, - 'ledOffMs': null, - 'ticker': null, - 'visibility': null, - 'timeoutAfter': null, - 'category': null, - 'additionalFlags': null, - 'fullScreenIntent': false, - 'shortcutId': null, - 'subText': null, - 'style': AndroidNotificationStyle.inbox.index, - 'styleInformation': { - 'htmlFormatContent': true, - 'htmlFormatTitle': true, - 'lines': ['line1'], - 'contentTitle': 'contentTitle', - 'summaryText': 'summaryText', - 'htmlFormatContentTitle': true, - 'htmlFormatSummaryText': true, - 'htmlFormatLines': true, - }, - 'tag': null, - 'colorized': false, - 'number': null, - 'audioAttributesUsage': 5, - }, - })); - }); - - test('show with default Android media style settings', () async { - const AndroidInitializationSettings androidInitializationSettings = - AndroidInitializationSettings('app_icon'); - const InitializationSettings initializationSettings = - InitializationSettings(android: androidInitializationSettings); - await flutterLocalNotificationsPlugin.initialize(initializationSettings); - const AndroidNotificationDetails androidNotificationDetails = - AndroidNotificationDetails( - 'channelId', - 'channelName', - channelDescription: 'channelDescription', - styleInformation: MediaStyleInformation(), - ); - - await flutterLocalNotificationsPlugin.show( - 1, - 'notification title', - 'notification body', - const NotificationDetails(android: androidNotificationDetails)); - expect( - log.last, - isMethodCall('show', arguments: { - 'id': 1, - 'title': 'notification title', - 'body': 'notification body', - 'payload': '', - 'platformSpecifics': { - 'icon': null, - 'channelId': 'channelId', - 'channelName': 'channelName', - 'channelDescription': 'channelDescription', - 'channelShowBadge': true, - 'channelAction': - AndroidNotificationChannelAction.createIfNotExists.index, - 'importance': Importance.defaultImportance.value, - 'priority': Priority.defaultPriority.value, - 'playSound': true, - 'enableVibration': true, - 'vibrationPattern': null, - 'groupKey': null, - 'setAsGroupSummary': false, - 'groupAlertBehavior': GroupAlertBehavior.all.index, - 'autoCancel': true, - 'ongoing': false, - 'silent': false, - 'colorAlpha': null, - 'colorRed': null, - 'colorGreen': null, - 'colorBlue': null, - 'onlyAlertOnce': false, - 'showWhen': true, - 'when': null, - 'usesChronometer': false, - 'chronometerCountDown': false, - 'showProgress': false, - 'maxProgress': 0, - 'progress': 0, - 'indeterminate': false, - 'enableLights': false, - 'ledColorAlpha': null, - 'ledColorRed': null, - 'ledColorGreen': null, - 'ledColorBlue': null, - 'ledOnMs': null, - 'ledOffMs': null, - 'ticker': null, - 'visibility': null, - 'timeoutAfter': null, - 'category': null, - 'additionalFlags': null, - 'fullScreenIntent': false, - 'shortcutId': null, - 'subText': null, - 'style': AndroidNotificationStyle.media.index, - 'styleInformation': { - 'htmlFormatContent': false, - 'htmlFormatTitle': false, - }, - 'tag': null, - 'colorized': false, - 'number': null, - 'audioAttributesUsage': 5, - }, - })); - }); - - test('show with non-default Android media style settings', () async { - const AndroidInitializationSettings androidInitializationSettings = - AndroidInitializationSettings('app_icon'); - const InitializationSettings initializationSettings = - InitializationSettings(android: androidInitializationSettings); - await flutterLocalNotificationsPlugin.initialize(initializationSettings); - const AndroidNotificationDetails androidNotificationDetails = - AndroidNotificationDetails( - 'channelId', - 'channelName', - channelDescription: 'channelDescription', - styleInformation: MediaStyleInformation( - htmlFormatTitle: true, - htmlFormatContent: true, - ), - ); - - await flutterLocalNotificationsPlugin.show( - 1, - 'notification title', - 'notification body', - const NotificationDetails(android: androidNotificationDetails)); - expect( - log.last, - isMethodCall('show', arguments: { - 'id': 1, - 'title': 'notification title', - 'body': 'notification body', - 'payload': '', - 'platformSpecifics': { - 'icon': null, - 'channelId': 'channelId', - 'channelName': 'channelName', - 'channelDescription': 'channelDescription', - 'channelShowBadge': true, - 'channelAction': - AndroidNotificationChannelAction.createIfNotExists.index, - 'importance': Importance.defaultImportance.value, - 'priority': Priority.defaultPriority.value, - 'playSound': true, - 'enableVibration': true, - 'vibrationPattern': null, - 'groupKey': null, - 'setAsGroupSummary': false, - 'groupAlertBehavior': GroupAlertBehavior.all.index, - 'autoCancel': true, - 'ongoing': false, - 'silent': false, - 'colorAlpha': null, - 'colorRed': null, - 'colorGreen': null, - 'colorBlue': null, - 'onlyAlertOnce': false, - 'showWhen': true, - 'when': null, - 'usesChronometer': false, - 'chronometerCountDown': false, - 'showProgress': false, - 'maxProgress': 0, - 'progress': 0, - 'indeterminate': false, - 'enableLights': false, - 'ledColorAlpha': null, - 'ledColorRed': null, - 'ledColorGreen': null, - 'ledColorBlue': null, - 'ledOnMs': null, - 'ledOffMs': null, - 'ticker': null, - 'visibility': null, - 'timeoutAfter': null, - 'category': null, - 'additionalFlags': null, - 'fullScreenIntent': false, - 'shortcutId': null, - 'subText': null, - 'style': AndroidNotificationStyle.media.index, - 'styleInformation': { - 'htmlFormatContent': true, - 'htmlFormatTitle': true, - }, - 'tag': null, - 'colorized': false, - 'number': null, - 'audioAttributesUsage': 5, - }, - })); - }); - - test('show with default Android messaging style settings', () async { - final DateTime messageDateTime = clock.now(); - const AndroidInitializationSettings androidInitializationSettings = - AndroidInitializationSettings('app_icon'); - const InitializationSettings initializationSettings = - InitializationSettings(android: androidInitializationSettings); - await flutterLocalNotificationsPlugin.initialize(initializationSettings); - final AndroidNotificationDetails androidNotificationDetails = - AndroidNotificationDetails( - 'channelId', - 'channelName', - channelDescription: 'channelDescription', - styleInformation: MessagingStyleInformation( - const Person(name: 'name'), - messages: [ - Message( - 'message 1', - messageDateTime, - null, - ), - ], - ), - ); - - await flutterLocalNotificationsPlugin.show( - 1, - 'notification title', - 'notification body', - NotificationDetails(android: androidNotificationDetails)); - expect( - log.last, - isMethodCall('show', arguments: { - 'id': 1, - 'title': 'notification title', - 'body': 'notification body', - 'payload': '', - 'platformSpecifics': { - 'icon': null, - 'channelId': 'channelId', - 'channelName': 'channelName', - 'channelDescription': 'channelDescription', - 'channelShowBadge': true, - 'channelAction': - AndroidNotificationChannelAction.createIfNotExists.index, - 'importance': Importance.defaultImportance.value, - 'priority': Priority.defaultPriority.value, - 'playSound': true, - 'enableVibration': true, - 'vibrationPattern': null, - 'groupKey': null, - 'setAsGroupSummary': false, - 'groupAlertBehavior': GroupAlertBehavior.all.index, - 'autoCancel': true, - 'ongoing': false, - 'silent': false, - 'colorAlpha': null, - 'colorRed': null, - 'colorGreen': null, - 'colorBlue': null, - 'onlyAlertOnce': false, - 'showWhen': true, - 'when': null, - 'usesChronometer': false, - 'chronometerCountDown': false, - 'showProgress': false, - 'maxProgress': 0, - 'progress': 0, - 'indeterminate': false, - 'enableLights': false, - 'ledColorAlpha': null, - 'ledColorRed': null, - 'ledColorGreen': null, - 'ledColorBlue': null, - 'ledOnMs': null, - 'ledOffMs': null, - 'ticker': null, - 'visibility': null, - 'timeoutAfter': null, - 'category': null, - 'additionalFlags': null, - 'fullScreenIntent': false, - 'shortcutId': null, - 'subText': null, - 'style': AndroidNotificationStyle.messaging.index, - 'styleInformation': { - 'htmlFormatContent': false, - 'htmlFormatTitle': false, - 'person': { - 'bot': false, - 'important': false, - 'key': null, - 'name': 'name', - 'uri': null, - }, - 'conversationTitle': null, - 'groupConversation': null, - 'messages': >[ - { - 'text': 'message 1', - 'timestamp': messageDateTime.millisecondsSinceEpoch, - 'person': null, - 'dataMimeType': null, - 'dataUri': null, - } - ], - }, - 'tag': null, - 'colorized': false, - 'number': null, - 'audioAttributesUsage': 5, - }, - })); - }); - - test('show with non-default Android messaging style settings', () async { - final DateTime messageDateTime = clock.now(); - const AndroidInitializationSettings androidInitializationSettings = - AndroidInitializationSettings('app_icon'); - const InitializationSettings initializationSettings = - InitializationSettings(android: androidInitializationSettings); - await flutterLocalNotificationsPlugin.initialize(initializationSettings); - final AndroidNotificationDetails androidNotificationDetails = - AndroidNotificationDetails( - 'channelId', - 'channelName', - channelDescription: 'channelDescription', - styleInformation: MessagingStyleInformation( - const Person( - bot: true, - icon: DrawableResourceAndroidIcon('drawablePersonIcon'), - important: true, - key: 'key', - name: 'name', - uri: 'uri', - ), - conversationTitle: 'conversationTitle', - groupConversation: true, - messages: [ - Message( - 'message 1', - messageDateTime, - null, - dataMimeType: 'dataMimeType', - dataUri: 'dataUri', - ), - ], - ), - ); - - await flutterLocalNotificationsPlugin.show( - 1, - 'notification title', - 'notification body', - NotificationDetails(android: androidNotificationDetails)); - expect( - log.last, - isMethodCall('show', arguments: { - 'id': 1, - 'title': 'notification title', - 'body': 'notification body', - 'payload': '', - 'platformSpecifics': { - 'icon': null, - 'channelId': 'channelId', - 'channelName': 'channelName', - 'channelDescription': 'channelDescription', - 'channelShowBadge': true, - 'channelAction': - AndroidNotificationChannelAction.createIfNotExists.index, - 'importance': Importance.defaultImportance.value, - 'priority': Priority.defaultPriority.value, - 'playSound': true, - 'enableVibration': true, - 'vibrationPattern': null, - 'groupKey': null, - 'setAsGroupSummary': false, - 'groupAlertBehavior': GroupAlertBehavior.all.index, - 'autoCancel': true, - 'ongoing': false, - 'silent': false, - 'colorAlpha': null, - 'colorRed': null, - 'colorGreen': null, - 'colorBlue': null, - 'onlyAlertOnce': false, - 'showWhen': true, - 'when': null, - 'usesChronometer': false, - 'chronometerCountDown': false, - 'showProgress': false, - 'maxProgress': 0, - 'progress': 0, - 'indeterminate': false, - 'enableLights': false, - 'ledColorAlpha': null, - 'ledColorRed': null, - 'ledColorGreen': null, - 'ledColorBlue': null, - 'ledOnMs': null, - 'ledOffMs': null, - 'ticker': null, - 'visibility': null, - 'timeoutAfter': null, - 'category': null, - 'additionalFlags': null, - 'fullScreenIntent': false, - 'shortcutId': null, - 'subText': null, - 'style': AndroidNotificationStyle.messaging.index, - 'styleInformation': { - 'htmlFormatContent': false, - 'htmlFormatTitle': false, - 'person': { - 'bot': true, - 'important': true, - 'key': 'key', - 'name': 'name', - 'uri': 'uri', - 'icon': 'drawablePersonIcon', - 'iconSource': AndroidIconSource.drawableResource.index, - }, - 'conversationTitle': 'conversationTitle', - 'groupConversation': true, - 'messages': >[ - { - 'text': 'message 1', - 'timestamp': messageDateTime.millisecondsSinceEpoch, - 'person': null, - 'dataMimeType': 'dataMimeType', - 'dataUri': 'dataUri', - } - ], - }, - 'tag': null, - 'colorized': false, - 'number': null, - 'audioAttributesUsage': 5, - }, - })); - }); - - group('periodicallyShow', () { - final DateTime now = DateTime(2020, 10, 9); - for (final RepeatInterval repeatInterval in RepeatInterval.values) { - test('$repeatInterval', () async { - await withClock(Clock.fixed(now), () async { - const AndroidInitializationSettings androidInitializationSettings = - AndroidInitializationSettings('app_icon'); - const InitializationSettings initializationSettings = - InitializationSettings(android: androidInitializationSettings); - await flutterLocalNotificationsPlugin - .initialize(initializationSettings); - - const AndroidNotificationDetails androidNotificationDetails = - AndroidNotificationDetails('channelId', 'channelName', - channelDescription: 'channelDescription'); - await flutterLocalNotificationsPlugin.periodicallyShow( - 1, - 'notification title', - 'notification body', - repeatInterval, - const NotificationDetails(android: androidNotificationDetails), - androidScheduleMode: AndroidScheduleMode.exact, - ); - - expect( - log.last, - isMethodCall('periodicallyShow', arguments: { - 'id': 1, - 'title': 'notification title', - 'body': 'notification body', - 'payload': '', - 'calledAt': now.millisecondsSinceEpoch, - 'repeatInterval': repeatInterval.index, - 'platformSpecifics': { - 'scheduleMode': 'exact', - 'icon': null, - 'channelId': 'channelId', - 'channelName': 'channelName', - 'channelDescription': 'channelDescription', - 'channelShowBadge': true, - 'channelAction': AndroidNotificationChannelAction - .createIfNotExists.index, - 'importance': Importance.defaultImportance.value, - 'priority': Priority.defaultPriority.value, - 'playSound': true, - 'enableVibration': true, - 'vibrationPattern': null, - 'groupKey': null, - 'setAsGroupSummary': false, - 'groupAlertBehavior': GroupAlertBehavior.all.index, - 'autoCancel': true, - 'ongoing': false, - 'silent': false, - 'colorAlpha': null, - 'colorRed': null, - 'colorGreen': null, - 'colorBlue': null, - 'onlyAlertOnce': false, - 'showWhen': true, - 'when': null, - 'usesChronometer': false, - 'chronometerCountDown': false, - 'showProgress': false, - 'maxProgress': 0, - 'progress': 0, - 'indeterminate': false, - 'enableLights': false, - 'ledColorAlpha': null, - 'ledColorRed': null, - 'ledColorGreen': null, - 'ledColorBlue': null, - 'ledOnMs': null, - 'ledOffMs': null, - 'ticker': null, - 'visibility': null, - 'timeoutAfter': null, - 'category': null, - 'additionalFlags': null, - 'fullScreenIntent': false, - 'shortcutId': null, - 'subText': null, - 'style': AndroidNotificationStyle.defaultStyle.index, - 'styleInformation': { - 'htmlFormatContent': false, - 'htmlFormatTitle': false, - }, - 'tag': null, - 'colorized': false, - 'number': null, - 'audioAttributesUsage': 5, - }, - })); - }); - }); - } - }); - - group('periodicallyShowWithDuration', () { - final DateTime now = DateTime(2023, 12, 29); - - const Duration thirtySeconds = Duration(seconds: 30); - test('$thirtySeconds', () async { - await withClock(Clock.fixed(now), () async { - const AndroidInitializationSettings androidInitializationSettings = - AndroidInitializationSettings('app_icon'); - const InitializationSettings initializationSettings = - InitializationSettings(android: androidInitializationSettings); - await flutterLocalNotificationsPlugin - .initialize(initializationSettings); - - const AndroidNotificationDetails androidNotificationDetails = - AndroidNotificationDetails('channelId', 'channelName', - channelDescription: 'channelDescription'); - - expect( - () async => await flutterLocalNotificationsPlugin - .periodicallyShowWithDuration( - 1, - 'notification title', - 'notification body', - thirtySeconds, - const NotificationDetails( - android: androidNotificationDetails), - ), - throwsA(isA())); - }); - }); - - final List repeatDurationIntervals = [ - const Duration(minutes: 1), - const Duration(minutes: 15), - const Duration(hours: 5), - const Duration(days: 30) - ]; - - for (final Duration repeatDurationInterval in repeatDurationIntervals) { - test('$repeatDurationInterval', () async { - await withClock(Clock.fixed(now), () async { - const AndroidInitializationSettings androidInitializationSettings = - AndroidInitializationSettings('app_icon'); - const InitializationSettings initializationSettings = - InitializationSettings(android: androidInitializationSettings); - await flutterLocalNotificationsPlugin - .initialize(initializationSettings); - - const AndroidNotificationDetails androidNotificationDetails = - AndroidNotificationDetails('channelId', 'channelName', - channelDescription: 'channelDescription'); - await flutterLocalNotificationsPlugin.periodicallyShowWithDuration( - 1, - 'notification title', - 'notification body', - repeatDurationInterval, - const NotificationDetails(android: androidNotificationDetails), - ); - - expect( - log.last, - isMethodCall('periodicallyShowWithDuration', - arguments: { - 'id': 1, - 'title': 'notification title', - 'body': 'notification body', - 'payload': '', - 'calledAt': now.millisecondsSinceEpoch, - 'repeatIntervalMilliseconds': - repeatDurationInterval.inMilliseconds, - 'platformSpecifics': { - 'scheduleMode': 'exact', - 'icon': null, - 'channelId': 'channelId', - 'channelName': 'channelName', - 'channelDescription': 'channelDescription', - 'channelShowBadge': true, - 'channelAction': AndroidNotificationChannelAction - .createIfNotExists.index, - 'importance': Importance.defaultImportance.value, - 'priority': Priority.defaultPriority.value, - 'playSound': true, - 'enableVibration': true, - 'vibrationPattern': null, - 'groupKey': null, - 'setAsGroupSummary': false, - 'groupAlertBehavior': GroupAlertBehavior.all.index, - 'autoCancel': true, - 'ongoing': false, - 'silent': false, - 'colorAlpha': null, - 'colorRed': null, - 'colorGreen': null, - 'colorBlue': null, - 'onlyAlertOnce': false, - 'showWhen': true, - 'when': null, - 'usesChronometer': false, - 'chronometerCountDown': false, - 'showProgress': false, - 'maxProgress': 0, - 'progress': 0, - 'indeterminate': false, - 'enableLights': false, - 'ledColorAlpha': null, - 'ledColorRed': null, - 'ledColorGreen': null, - 'ledColorBlue': null, - 'ledOnMs': null, - 'ledOffMs': null, - 'ticker': null, - 'visibility': null, - 'timeoutAfter': null, - 'category': null, - 'additionalFlags': null, - 'fullScreenIntent': false, - 'shortcutId': null, - 'subText': null, - 'style': AndroidNotificationStyle.defaultStyle.index, - 'styleInformation': { - 'htmlFormatContent': false, - 'htmlFormatTitle': false, - }, - 'tag': null, - 'colorized': false, - 'number': null, - 'audioAttributesUsage': 5, - }, - })); - }); - }); - } - }); - - group('zonedSchedule', () { - test('no repeat frequency', () async { - const AndroidInitializationSettings androidInitializationSettings = - AndroidInitializationSettings('app_icon'); - const InitializationSettings initializationSettings = - InitializationSettings(android: androidInitializationSettings); - await flutterLocalNotificationsPlugin - .initialize(initializationSettings); - tz.initializeTimeZones(); - tz.setLocalLocation(tz.getLocation('Australia/Sydney')); - final tz.TZDateTime scheduledDate = - tz.TZDateTime.now(tz.local).add(const Duration(seconds: 5)); - const AndroidNotificationDetails androidNotificationDetails = - AndroidNotificationDetails('channelId', 'channelName', - channelDescription: 'channelDescription'); - await flutterLocalNotificationsPlugin.zonedSchedule( - 1, - 'notification title', - 'notification body', - scheduledDate, - const NotificationDetails(android: androidNotificationDetails), - androidScheduleMode: AndroidScheduleMode.exactAllowWhileIdle); - expect( - log.last, - isMethodCall('zonedSchedule', arguments: { - 'id': 1, - 'title': 'notification title', - 'body': 'notification body', - 'payload': '', - 'timeZoneName': 'Australia/Sydney', - 'scheduledDateTime': convertDateToISO8601String(scheduledDate), - 'scheduledDateTimeISO8601': scheduledDate.toIso8601String(), - 'platformSpecifics': { - 'scheduleMode': 'exactAllowWhileIdle', - 'icon': null, - 'channelId': 'channelId', - 'channelName': 'channelName', - 'channelDescription': 'channelDescription', - 'channelShowBadge': true, - 'channelAction': - AndroidNotificationChannelAction.createIfNotExists.index, - 'importance': Importance.defaultImportance.value, - 'priority': Priority.defaultPriority.value, - 'playSound': true, - 'enableVibration': true, - 'vibrationPattern': null, - 'groupKey': null, - 'setAsGroupSummary': false, - 'groupAlertBehavior': GroupAlertBehavior.all.index, - 'autoCancel': true, - 'ongoing': false, - 'silent': false, - 'colorAlpha': null, - 'colorRed': null, - 'colorGreen': null, - 'colorBlue': null, - 'onlyAlertOnce': false, - 'showWhen': true, - 'when': null, - 'usesChronometer': false, - 'chronometerCountDown': false, - 'showProgress': false, - 'maxProgress': 0, - 'progress': 0, - 'indeterminate': false, - 'enableLights': false, - 'ledColorAlpha': null, - 'ledColorRed': null, - 'ledColorGreen': null, - 'ledColorBlue': null, - 'ledOnMs': null, - 'ledOffMs': null, - 'ticker': null, - 'visibility': null, - 'timeoutAfter': null, - 'category': null, - 'additionalFlags': null, - 'fullScreenIntent': false, - 'shortcutId': null, - 'subText': null, - 'style': AndroidNotificationStyle.defaultStyle.index, - 'styleInformation': { - 'htmlFormatContent': false, - 'htmlFormatTitle': false, - }, - 'tag': null, - 'colorized': false, - 'number': null, - 'audioAttributesUsage': 5, - }, - })); - }); - - test('match time components', () async { - const AndroidInitializationSettings androidInitializationSettings = - AndroidInitializationSettings('app_icon'); - const InitializationSettings initializationSettings = - InitializationSettings(android: androidInitializationSettings); - await flutterLocalNotificationsPlugin - .initialize(initializationSettings); - - tz.initializeTimeZones(); - tz.setLocalLocation(tz.getLocation('Australia/Sydney')); - final tz.TZDateTime scheduledDate = - tz.TZDateTime.now(tz.local).add(const Duration(seconds: 5)); - const AndroidNotificationDetails androidNotificationDetails = - AndroidNotificationDetails('channelId', 'channelName', - channelDescription: 'channelDescription'); - await flutterLocalNotificationsPlugin.zonedSchedule( - 1, - 'notification title', - 'notification body', - scheduledDate, - const NotificationDetails(android: androidNotificationDetails), - androidScheduleMode: AndroidScheduleMode.exactAllowWhileIdle, - matchDateTimeComponents: DateTimeComponents.time); - expect( - log.last, - isMethodCall('zonedSchedule', arguments: { - 'id': 1, - 'title': 'notification title', - 'body': 'notification body', - 'payload': '', - 'timeZoneName': 'Australia/Sydney', - 'scheduledDateTime': convertDateToISO8601String(scheduledDate), - 'scheduledDateTimeISO8601': scheduledDate.toIso8601String(), - 'matchDateTimeComponents': DateTimeComponents.time.index, - 'platformSpecifics': { - 'scheduleMode': 'exactAllowWhileIdle', - 'icon': null, - 'channelId': 'channelId', - 'channelName': 'channelName', - 'channelDescription': 'channelDescription', - 'channelShowBadge': true, - 'channelAction': - AndroidNotificationChannelAction.createIfNotExists.index, - 'importance': Importance.defaultImportance.value, - 'priority': Priority.defaultPriority.value, - 'playSound': true, - 'enableVibration': true, - 'vibrationPattern': null, - 'groupKey': null, - 'setAsGroupSummary': false, - 'groupAlertBehavior': GroupAlertBehavior.all.index, - 'autoCancel': true, - 'ongoing': false, - 'silent': false, - 'colorAlpha': null, - 'colorRed': null, - 'colorGreen': null, - 'colorBlue': null, - 'onlyAlertOnce': false, - 'showWhen': true, - 'when': null, - 'usesChronometer': false, - 'chronometerCountDown': false, - 'showProgress': false, - 'maxProgress': 0, - 'progress': 0, - 'indeterminate': false, - 'enableLights': false, - 'ledColorAlpha': null, - 'ledColorRed': null, - 'ledColorGreen': null, - 'ledColorBlue': null, - 'ledOnMs': null, - 'ledOffMs': null, - 'ticker': null, - 'visibility': null, - 'timeoutAfter': null, - 'category': null, - 'additionalFlags': null, - 'fullScreenIntent': false, - 'shortcutId': null, - 'subText': null, - 'style': AndroidNotificationStyle.defaultStyle.index, - 'styleInformation': { - 'htmlFormatContent': false, - 'htmlFormatTitle': false, - }, - 'tag': null, - 'colorized': false, - 'number': null, - 'audioAttributesUsage': 5, - }, - })); - }); - - test('match day of week and time components', () async { - const AndroidInitializationSettings androidInitializationSettings = - AndroidInitializationSettings('app_icon'); - const InitializationSettings initializationSettings = - InitializationSettings(android: androidInitializationSettings); - await flutterLocalNotificationsPlugin - .initialize(initializationSettings); - - tz.initializeTimeZones(); - tz.setLocalLocation(tz.getLocation('Australia/Sydney')); - final tz.TZDateTime scheduledDate = - tz.TZDateTime.now(tz.local).add(const Duration(seconds: 5)); - const AndroidNotificationDetails androidNotificationDetails = - AndroidNotificationDetails('channelId', 'channelName', - channelDescription: 'channelDescription'); - await flutterLocalNotificationsPlugin.zonedSchedule( - 1, - 'notification title', - 'notification body', - scheduledDate, - const NotificationDetails(android: androidNotificationDetails), - androidScheduleMode: AndroidScheduleMode.exactAllowWhileIdle, - matchDateTimeComponents: DateTimeComponents.dayOfWeekAndTime); - expect( - log.last, - isMethodCall('zonedSchedule', arguments: { - 'id': 1, - 'title': 'notification title', - 'body': 'notification body', - 'payload': '', - 'timeZoneName': 'Australia/Sydney', - 'scheduledDateTime': convertDateToISO8601String(scheduledDate), - 'scheduledDateTimeISO8601': scheduledDate.toIso8601String(), - 'matchDateTimeComponents': - DateTimeComponents.dayOfWeekAndTime.index, - 'platformSpecifics': { - 'scheduleMode': 'exactAllowWhileIdle', - 'icon': null, - 'channelId': 'channelId', - 'channelName': 'channelName', - 'channelDescription': 'channelDescription', - 'channelShowBadge': true, - 'channelAction': - AndroidNotificationChannelAction.createIfNotExists.index, - 'importance': Importance.defaultImportance.value, - 'priority': Priority.defaultPriority.value, - 'playSound': true, - 'enableVibration': true, - 'vibrationPattern': null, - 'groupKey': null, - 'setAsGroupSummary': false, - 'groupAlertBehavior': GroupAlertBehavior.all.index, - 'autoCancel': true, - 'ongoing': false, - 'silent': false, - 'colorAlpha': null, - 'colorRed': null, - 'colorGreen': null, - 'colorBlue': null, - 'onlyAlertOnce': false, - 'showWhen': true, - 'when': null, - 'usesChronometer': false, - 'chronometerCountDown': false, - 'showProgress': false, - 'maxProgress': 0, - 'progress': 0, - 'indeterminate': false, - 'enableLights': false, - 'ledColorAlpha': null, - 'ledColorRed': null, - 'ledColorGreen': null, - 'ledColorBlue': null, - 'ledOnMs': null, - 'ledOffMs': null, - 'ticker': null, - 'visibility': null, - 'timeoutAfter': null, - 'category': null, - 'additionalFlags': null, - 'fullScreenIntent': false, - 'shortcutId': null, - 'subText': null, - 'style': AndroidNotificationStyle.defaultStyle.index, - 'styleInformation': { - 'htmlFormatContent': false, - 'htmlFormatTitle': false, - }, - 'tag': null, - 'colorized': false, - 'number': null, - 'audioAttributesUsage': 5, - }, - })); - }); - }); - - group('createNotificationChannelGroup', () { - test('without description', () async { - await flutterLocalNotificationsPlugin - .resolvePlatformSpecificImplementation< - AndroidFlutterLocalNotificationsPlugin>()! - .createNotificationChannelGroup( - const AndroidNotificationChannelGroup('groupId', 'groupName')); - expect(log, [ - isMethodCall('createNotificationChannelGroup', - arguments: { - 'id': 'groupId', - 'name': 'groupName', - 'description': null, - }) - ]); - }); - test('with description', () async { - await flutterLocalNotificationsPlugin - .resolvePlatformSpecificImplementation< - AndroidFlutterLocalNotificationsPlugin>()! - .createNotificationChannelGroup( - const AndroidNotificationChannelGroup('groupId', 'groupName', - description: 'groupDescription')); - expect(log, [ - isMethodCall('createNotificationChannelGroup', - arguments: { - 'id': 'groupId', - 'name': 'groupName', - 'description': 'groupDescription', - }) - ]); - }); - }); - - test('createNotificationChannel with default settings', () async { - await flutterLocalNotificationsPlugin - .resolvePlatformSpecificImplementation< - AndroidFlutterLocalNotificationsPlugin>()! - .createNotificationChannel(const AndroidNotificationChannel( - 'channelId', - 'channelName', - description: 'channelDescription', - )); - expect(log, [ - isMethodCall('createNotificationChannel', arguments: { - 'id': 'channelId', - 'name': 'channelName', - 'description': 'channelDescription', - 'groupId': null, - 'showBadge': true, - 'importance': Importance.defaultImportance.value, - 'playSound': true, - 'enableVibration': true, - 'vibrationPattern': null, - 'enableLights': false, - 'ledColorAlpha': null, - 'ledColorRed': null, - 'ledColorGreen': null, - 'ledColorBlue': null, - 'audioAttributesUsage': AudioAttributesUsage.notification.value, - 'channelAction': - AndroidNotificationChannelAction.createIfNotExists.index, - }) - ]); - }); - - test('createNotificationChannel with non-default settings', () async { - await flutterLocalNotificationsPlugin - .resolvePlatformSpecificImplementation< - AndroidFlutterLocalNotificationsPlugin>()! - .createNotificationChannel(const AndroidNotificationChannel( - 'channelId', - 'channelName', - description: 'channelDescription', - groupId: 'channelGroupId', - showBadge: false, - importance: Importance.max, - playSound: false, - enableLights: true, - enableVibration: false, - ledColor: Color.fromARGB(255, 255, 0, 0), - audioAttributesUsage: AudioAttributesUsage.alarm, - )); - expect(log, [ - isMethodCall('createNotificationChannel', arguments: { - 'id': 'channelId', - 'name': 'channelName', - 'description': 'channelDescription', - 'groupId': 'channelGroupId', - 'showBadge': false, - 'importance': Importance.max.value, - 'playSound': false, - 'enableVibration': false, - 'vibrationPattern': null, - 'enableLights': true, - 'ledColorAlpha': 255, - 'ledColorRed': 255, - 'ledColorGreen': 0, - 'ledColorBlue': 0, - 'audioAttributesUsage': AudioAttributesUsage.alarm.value, - 'channelAction': - AndroidNotificationChannelAction.createIfNotExists.index, - }) - ]); - }); - - test('deleteNotificationChannel', () async { - await flutterLocalNotificationsPlugin - .resolvePlatformSpecificImplementation< - AndroidFlutterLocalNotificationsPlugin>()! - .deleteNotificationChannel('channelId'); - expect(log, [ - isMethodCall('deleteNotificationChannel', arguments: 'channelId') - ]); - }); - - test('cancel', () async { - await flutterLocalNotificationsPlugin.cancel(1); - expect(log, [ - isMethodCall('cancel', arguments: { - 'id': 1, - 'tag': null, - }) - ]); - }); - - test('cancel with tag', () async { - await flutterLocalNotificationsPlugin.cancel(1, tag: 'tag'); - expect(log, [ - isMethodCall('cancel', arguments: { - 'id': 1, - 'tag': 'tag', - }) - ]); - }); - - test('cancelAll', () async { - await flutterLocalNotificationsPlugin.cancelAll(); - expect(log, [isMethodCall('cancelAll', arguments: null)]); - }); - - test('pendingNotificationRequests', () async { - await flutterLocalNotificationsPlugin.pendingNotificationRequests(); - expect(log, [ - isMethodCall('pendingNotificationRequests', arguments: null) - ]); - }); - - test('getActiveNotifications', () async { - await flutterLocalNotificationsPlugin.getActiveNotifications(); - expect(log, - [isMethodCall('getActiveNotifications', arguments: null)]); - }); - - test('getNotificationAppLaunchDetails', () async { - await flutterLocalNotificationsPlugin.getNotificationAppLaunchDetails(); - expect(log, [ - isMethodCall('getNotificationAppLaunchDetails', arguments: null) - ]); - }); - - test('startForegroundService', () async { - const AndroidInitializationSettings androidInitializationSettings = - AndroidInitializationSettings('app_icon'); - const InitializationSettings initializationSettings = - InitializationSettings(android: androidInitializationSettings); - await flutterLocalNotificationsPlugin.initialize(initializationSettings); - await flutterLocalNotificationsPlugin - .resolvePlatformSpecificImplementation< - AndroidFlutterLocalNotificationsPlugin>()! - .startForegroundService(1, 'notification title', 'notification body'); - expect( - log.last, - isMethodCall('startForegroundService', arguments: { - 'notificationData': { - 'id': 1, - 'title': 'notification title', - 'body': 'notification body', - 'payload': '', - 'platformSpecifics': null, - }, - 'startType': AndroidServiceStartType.startSticky.index, - 'foregroundServiceTypes': null - })); - }); - - test('stopForegroundService', () async { - await flutterLocalNotificationsPlugin - .resolvePlatformSpecificImplementation< - AndroidFlutterLocalNotificationsPlugin>()! - .stopForegroundService(); - expect( - log.last, - isMethodCall( - 'stopForegroundService', - arguments: null, - )); - }); - - test('areNotificationsEnabled', () async { - await flutterLocalNotificationsPlugin - .resolvePlatformSpecificImplementation< - AndroidFlutterLocalNotificationsPlugin>()! - .areNotificationsEnabled(); - expect( - log.last, isMethodCall('areNotificationsEnabled', arguments: null)); - }); - - test('startForegroundServiceWithBlueBackgroundNotification', () async { - const AndroidInitializationSettings androidInitializationSettings = - AndroidInitializationSettings('app_icon'); - const InitializationSettings initializationSettings = - InitializationSettings(android: androidInitializationSettings); - await flutterLocalNotificationsPlugin.initialize(initializationSettings); - const AndroidNotificationDetails androidPlatformChannelSpecifics = - AndroidNotificationDetails( - 'channelId', - 'channelName', - channelDescription: 'channelDescription', - color: Colors.blue, - colorized: true, - ); - - await flutterLocalNotificationsPlugin - .resolvePlatformSpecificImplementation< - AndroidFlutterLocalNotificationsPlugin>()! - .startForegroundService(1, 'colored background notification title', - 'colored background notification body', - notificationDetails: androidPlatformChannelSpecifics); - expect( - log.last, - isMethodCall( - 'startForegroundService', - arguments: { - 'notificationData': { - 'id': 1, - 'title': 'colored background notification title', - 'body': 'colored background notification body', - 'payload': '', - 'platformSpecifics': { - 'icon': null, - 'channelId': 'channelId', - 'channelName': 'channelName', - 'channelDescription': 'channelDescription', - 'channelShowBadge': true, - 'channelAction': - AndroidNotificationChannelAction.createIfNotExists.index, - 'importance': Importance.defaultImportance.value, - 'priority': Priority.defaultPriority.value, - 'playSound': true, - 'enableVibration': true, - 'vibrationPattern': null, - 'groupKey': null, - 'setAsGroupSummary': false, - 'groupAlertBehavior': GroupAlertBehavior.all.index, - 'autoCancel': true, - 'ongoing': false, - 'silent': false, - 'colorAlpha': 255, - 'colorRed': 33, - 'colorGreen': 150, - 'colorBlue': 243, - 'onlyAlertOnce': false, - 'showWhen': true, - 'when': null, - 'usesChronometer': false, - 'chronometerCountDown': false, - 'showProgress': false, - 'maxProgress': 0, - 'progress': 0, - 'indeterminate': false, - 'enableLights': false, - 'ledColorAlpha': null, - 'ledColorRed': null, - 'ledColorGreen': null, - 'ledColorBlue': null, - 'ledOnMs': null, - 'ledOffMs': null, - 'ticker': null, - 'visibility': null, - 'timeoutAfter': null, - 'category': null, - 'additionalFlags': null, - 'fullScreenIntent': false, - 'shortcutId': null, - 'subText': null, - 'style': AndroidNotificationStyle.defaultStyle.index, - 'styleInformation': { - 'htmlFormatContent': false, - 'htmlFormatTitle': false, - }, - 'tag': null, - 'colorized': true, - 'number': null, - 'audioAttributesUsage': 5, - }, - }, - 'startType': AndroidServiceStartType.startSticky.index, - 'foregroundServiceTypes': null - }, - )); - }); - - test('requestNotificationsPermission', () async { - await flutterLocalNotificationsPlugin - .resolvePlatformSpecificImplementation< - AndroidFlutterLocalNotificationsPlugin>()! - .requestNotificationsPermission(); - expect(log.last, - isMethodCall('requestNotificationsPermission', arguments: null)); - }); - - test('requestExactAlarmsPermission', () async { - await flutterLocalNotificationsPlugin - .resolvePlatformSpecificImplementation< - AndroidFlutterLocalNotificationsPlugin>()! - .requestExactAlarmsPermission(); - expect(log.last, - isMethodCall('requestExactAlarmsPermission', arguments: null)); - }); - }); -} From e5d62ae538f7aacf6b0dd68d2065cdef4d9abee2 Mon Sep 17 00:00:00 2001 From: Levi Lesches Date: Tue, 24 Dec 2024 15:00:48 -0500 Subject: [PATCH 8/9] Formatted --- .../integration_test/flutter_local_notifications_test.dart | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/flutter_local_notifications/example/integration_test/flutter_local_notifications_test.dart b/flutter_local_notifications/example/integration_test/flutter_local_notifications_test.dart index a6b83b525..112748a39 100644 --- a/flutter_local_notifications/example/integration_test/flutter_local_notifications_test.dart +++ b/flutter_local_notifications/example/integration_test/flutter_local_notifications_test.dart @@ -6,8 +6,8 @@ import 'package:integration_test/integration_test.dart'; void main() { IntegrationTestWidgetsFlutterBinding.ensureInitialized(); - const AndroidInitializationSettings initializationSettingsAndroid = - AndroidInitializationSettings('app_icon'); + final AndroidInitializationSettings initializationSettingsAndroid = + AndroidInitializationSettings(defaultIcon: 'app_icon'); const DarwinInitializationSettings initializationSettingsIOS = DarwinInitializationSettings(); const DarwinInitializationSettings initializationSettingsMacOS = From 26c5b71620d25891ebf959250443115c026d69f7 Mon Sep 17 00:00:00 2001 From: Levi Lesches Date: Tue, 24 Dec 2024 15:17:38 -0500 Subject: [PATCH 9/9] Pre-emptively deleted Java code --- .../models/BitmapSource.java | 10 - .../models/DateTimeComponents.java | 11 - .../models/IconSource.java | 12 - .../models/MessageDetails.java | 23 - .../models/NotificationAction.java | 160 ----- .../models/NotificationChannelAction.java | 9 - .../models/NotificationChannelDetails.java | 101 ---- .../NotificationChannelGroupDetails.java | 26 - .../models/NotificationDetails.java | 562 ------------------ .../models/NotificationStyle.java | 13 - .../models/PersonDetails.java | 33 - .../models/RepeatInterval.java | 11 - .../models/ScheduleMode.java | 41 -- .../ScheduledNotificationRepeatFrequency.java | 9 - .../models/SoundSource.java | 9 - .../styles/BigPictureStyleInformation.java | 42 -- .../styles/BigTextStyleInformation.java | 31 - .../styles/DefaultStyleInformation.java | 14 - .../models/styles/InboxStyleInformation.java | 33 - .../styles/MessagingStyleInformation.java | 30 - .../models/styles/StyleInformation.java | 8 - 21 files changed, 1188 deletions(-) delete mode 100644 flutter_local_notifications/android/src/main/java/com/dexterous/flutterlocalnotifications/models/BitmapSource.java delete mode 100644 flutter_local_notifications/android/src/main/java/com/dexterous/flutterlocalnotifications/models/DateTimeComponents.java delete mode 100644 flutter_local_notifications/android/src/main/java/com/dexterous/flutterlocalnotifications/models/IconSource.java delete mode 100644 flutter_local_notifications/android/src/main/java/com/dexterous/flutterlocalnotifications/models/MessageDetails.java delete mode 100644 flutter_local_notifications/android/src/main/java/com/dexterous/flutterlocalnotifications/models/NotificationAction.java delete mode 100644 flutter_local_notifications/android/src/main/java/com/dexterous/flutterlocalnotifications/models/NotificationChannelAction.java delete mode 100644 flutter_local_notifications/android/src/main/java/com/dexterous/flutterlocalnotifications/models/NotificationChannelDetails.java delete mode 100644 flutter_local_notifications/android/src/main/java/com/dexterous/flutterlocalnotifications/models/NotificationChannelGroupDetails.java delete mode 100644 flutter_local_notifications/android/src/main/java/com/dexterous/flutterlocalnotifications/models/NotificationDetails.java delete mode 100644 flutter_local_notifications/android/src/main/java/com/dexterous/flutterlocalnotifications/models/NotificationStyle.java delete mode 100644 flutter_local_notifications/android/src/main/java/com/dexterous/flutterlocalnotifications/models/PersonDetails.java delete mode 100644 flutter_local_notifications/android/src/main/java/com/dexterous/flutterlocalnotifications/models/RepeatInterval.java delete mode 100644 flutter_local_notifications/android/src/main/java/com/dexterous/flutterlocalnotifications/models/ScheduleMode.java delete mode 100644 flutter_local_notifications/android/src/main/java/com/dexterous/flutterlocalnotifications/models/ScheduledNotificationRepeatFrequency.java delete mode 100644 flutter_local_notifications/android/src/main/java/com/dexterous/flutterlocalnotifications/models/SoundSource.java delete mode 100644 flutter_local_notifications/android/src/main/java/com/dexterous/flutterlocalnotifications/models/styles/BigPictureStyleInformation.java delete mode 100644 flutter_local_notifications/android/src/main/java/com/dexterous/flutterlocalnotifications/models/styles/BigTextStyleInformation.java delete mode 100644 flutter_local_notifications/android/src/main/java/com/dexterous/flutterlocalnotifications/models/styles/DefaultStyleInformation.java delete mode 100644 flutter_local_notifications/android/src/main/java/com/dexterous/flutterlocalnotifications/models/styles/InboxStyleInformation.java delete mode 100644 flutter_local_notifications/android/src/main/java/com/dexterous/flutterlocalnotifications/models/styles/MessagingStyleInformation.java delete mode 100644 flutter_local_notifications/android/src/main/java/com/dexterous/flutterlocalnotifications/models/styles/StyleInformation.java diff --git a/flutter_local_notifications/android/src/main/java/com/dexterous/flutterlocalnotifications/models/BitmapSource.java b/flutter_local_notifications/android/src/main/java/com/dexterous/flutterlocalnotifications/models/BitmapSource.java deleted file mode 100644 index 14bcf7a5a..000000000 --- a/flutter_local_notifications/android/src/main/java/com/dexterous/flutterlocalnotifications/models/BitmapSource.java +++ /dev/null @@ -1,10 +0,0 @@ -package com.dexterous.flutterlocalnotifications.models; - -import androidx.annotation.Keep; - -@Keep -public enum BitmapSource { - DrawableResource, - FilePath, - ByteArray -} diff --git a/flutter_local_notifications/android/src/main/java/com/dexterous/flutterlocalnotifications/models/DateTimeComponents.java b/flutter_local_notifications/android/src/main/java/com/dexterous/flutterlocalnotifications/models/DateTimeComponents.java deleted file mode 100644 index ef4c03f98..000000000 --- a/flutter_local_notifications/android/src/main/java/com/dexterous/flutterlocalnotifications/models/DateTimeComponents.java +++ /dev/null @@ -1,11 +0,0 @@ -package com.dexterous.flutterlocalnotifications.models; - -import androidx.annotation.Keep; - -@Keep -public enum DateTimeComponents { - Time, - DayOfWeekAndTime, - DayOfMonthAndTime, - DateAndTime -} diff --git a/flutter_local_notifications/android/src/main/java/com/dexterous/flutterlocalnotifications/models/IconSource.java b/flutter_local_notifications/android/src/main/java/com/dexterous/flutterlocalnotifications/models/IconSource.java deleted file mode 100644 index 2fde7012d..000000000 --- a/flutter_local_notifications/android/src/main/java/com/dexterous/flutterlocalnotifications/models/IconSource.java +++ /dev/null @@ -1,12 +0,0 @@ -package com.dexterous.flutterlocalnotifications.models; - -import androidx.annotation.Keep; - -@Keep -public enum IconSource { - DrawableResource, - BitmapFilePath, - ContentUri, - FlutterBitmapAsset, - ByteArray -} diff --git a/flutter_local_notifications/android/src/main/java/com/dexterous/flutterlocalnotifications/models/MessageDetails.java b/flutter_local_notifications/android/src/main/java/com/dexterous/flutterlocalnotifications/models/MessageDetails.java deleted file mode 100644 index 754901aa5..000000000 --- a/flutter_local_notifications/android/src/main/java/com/dexterous/flutterlocalnotifications/models/MessageDetails.java +++ /dev/null @@ -1,23 +0,0 @@ -package com.dexterous.flutterlocalnotifications.models; - -import androidx.annotation.Keep; - -import java.io.Serializable; - -@Keep -public class MessageDetails implements Serializable { - public String text; - public Long timestamp; - public PersonDetails person; - public String dataMimeType; - public String dataUri; - - public MessageDetails( - String text, Long timestamp, PersonDetails person, String dataMimeType, String dataUri) { - this.text = text; - this.timestamp = timestamp; - this.person = person; - this.dataMimeType = dataMimeType; - this.dataUri = dataUri; - } -} diff --git a/flutter_local_notifications/android/src/main/java/com/dexterous/flutterlocalnotifications/models/NotificationAction.java b/flutter_local_notifications/android/src/main/java/com/dexterous/flutterlocalnotifications/models/NotificationAction.java deleted file mode 100644 index bd72db630..000000000 --- a/flutter_local_notifications/android/src/main/java/com/dexterous/flutterlocalnotifications/models/NotificationAction.java +++ /dev/null @@ -1,160 +0,0 @@ -package com.dexterous.flutterlocalnotifications.models; - -import android.graphics.Color; - -import androidx.annotation.Keep; -import androidx.annotation.Nullable; -import java.io.Serializable; -import java.util.ArrayList; -import java.util.Collection; -import java.util.Collections; -import java.util.List; -import java.util.Map; - -@Keep -public class NotificationAction implements Serializable { - public static class NotificationActionInput implements Serializable { - - public NotificationActionInput( - @Nullable List choices, - Boolean allowFreeFormInput, - String label, - @Nullable List allowedMimeTypes) { - this.choices = choices; - this.allowFreeFormInput = allowFreeFormInput; - this.label = label; - this.allowedMimeTypes = allowedMimeTypes; - } - - @SuppressWarnings("EqualsReplaceableByObjectsCall") - @Override - public boolean equals(Object o) { - if (this == o) { - return true; - } - if (o == null || getClass() != o.getClass()) { - return false; - } - - NotificationActionInput that = (NotificationActionInput) o; - - if (choices != null ? !choices.equals(that.choices) : that.choices != null) { - return false; - } - if (allowFreeFormInput != null - ? !allowFreeFormInput.equals(that.allowFreeFormInput) - : that.allowFreeFormInput != null) { - return false; - } - if (label != null ? !label.equals(that.label) : that.label != null) { - return false; - } - return allowedMimeTypes != null - ? allowedMimeTypes.equals(that.allowedMimeTypes) - : that.allowedMimeTypes == null; - } - - @Override - public int hashCode() { - int result = choices != null ? choices.hashCode() : 0; - result = 31 * result + (allowFreeFormInput != null ? allowFreeFormInput.hashCode() : 0); - result = 31 * result + (label != null ? label.hashCode() : 0); - result = 31 * result + (allowedMimeTypes != null ? allowedMimeTypes.hashCode() : 0); - return result; - } - - @Nullable public final List choices; - public final Boolean allowFreeFormInput; - public final String label; - @Nullable public final List allowedMimeTypes; - } - - private static final String ID = "id"; - private static final String INPUTS = "inputs"; - private static final String TITLE = "title"; - private static final String TITLE_COLOR_ALPHA = "titleColorAlpha"; - private static final String TITLE_COLOR_RED = "titleColorRed"; - private static final String TITLE_COLOR_GREEN = "titleColorGreen"; - private static final String TITLE_COLOR_BLUE = "titleColorBlue"; - private static final String ICON = "icon"; - private static final String ICON_SOURCE = "iconBitmapSource"; - - private static final String CONTEXTUAL = "contextual"; - private static final String SHOWS_USER_INTERFACE = "showsUserInterface"; - private static final String ALLOW_GENERATED_REPLIES = "allowGeneratedReplies"; - private static final String CANCEL_NOTIFICATION = "cancelNotification"; - - public final String id; - public final String title; - @Nullable public final Integer titleColor; - @Nullable public final String icon; - @Nullable public final Boolean cancelNotification; - @Nullable public final Boolean contextual; - @Nullable public final Boolean showsUserInterface; - @Nullable public final Boolean allowGeneratedReplies; - @Nullable public final IconSource iconSource; - // actionInputs is annotated as nullable as the Flutter API use to allow this to be nullable - // before null-safety was added in - @Nullable public final List actionInputs = new ArrayList<>(); - - public NotificationAction(Map arguments) { - id = (String) arguments.get(ID); - cancelNotification = (Boolean) arguments.get(CANCEL_NOTIFICATION); - title = (String) arguments.get(TITLE); - - Integer a = (Integer) arguments.get(TITLE_COLOR_ALPHA); - Integer r = (Integer) arguments.get(TITLE_COLOR_RED); - Integer g = (Integer) arguments.get(TITLE_COLOR_GREEN); - Integer b = (Integer) arguments.get(TITLE_COLOR_BLUE); - if (a != null && r != null && g != null && b != null) { - titleColor = Color.argb(a, r, g, b); - } else { - titleColor = null; - } - - icon = (String) arguments.get(ICON); - contextual = (Boolean) arguments.get(CONTEXTUAL); - showsUserInterface = (Boolean) arguments.get(SHOWS_USER_INTERFACE); - allowGeneratedReplies = (Boolean) arguments.get(ALLOW_GENERATED_REPLIES); - - Integer iconSourceIndex = (Integer) arguments.get(ICON_SOURCE); - if (iconSourceIndex != null) { - iconSource = IconSource.values()[iconSourceIndex]; - } else { - iconSource = null; - } - - if (arguments.get(INPUTS) != null) { - @SuppressWarnings("unchecked") - List> inputs = (List>) arguments.get(INPUTS); - - if (inputs != null) { - for (Map input : inputs) { - actionInputs.add( - new NotificationActionInput( - castList(String.class, (Collection) input.get("choices")), - (Boolean) input.get("allowFreeFormInput"), - (String) input.get("label"), - castList(String.class, (Collection) input.get("allowedMimeTypes")))); - } - } - } - } - - public static List castList( - Class clazz, @Nullable Collection rawCollection) { - if (rawCollection == null) { - return Collections.emptyList(); - } - - List result = new ArrayList<>(rawCollection.size()); - for (Object o : rawCollection) { - try { - result.add(clazz.cast(o)); - } catch (ClassCastException e) { - // log the exception or other error handling - } - } - return result; - } -} diff --git a/flutter_local_notifications/android/src/main/java/com/dexterous/flutterlocalnotifications/models/NotificationChannelAction.java b/flutter_local_notifications/android/src/main/java/com/dexterous/flutterlocalnotifications/models/NotificationChannelAction.java deleted file mode 100644 index ceb49b925..000000000 --- a/flutter_local_notifications/android/src/main/java/com/dexterous/flutterlocalnotifications/models/NotificationChannelAction.java +++ /dev/null @@ -1,9 +0,0 @@ -package com.dexterous.flutterlocalnotifications.models; - -import androidx.annotation.Keep; - -@Keep -public enum NotificationChannelAction { - CreateIfNotExists, - Update -} diff --git a/flutter_local_notifications/android/src/main/java/com/dexterous/flutterlocalnotifications/models/NotificationChannelDetails.java b/flutter_local_notifications/android/src/main/java/com/dexterous/flutterlocalnotifications/models/NotificationChannelDetails.java deleted file mode 100644 index ffa4e6e70..000000000 --- a/flutter_local_notifications/android/src/main/java/com/dexterous/flutterlocalnotifications/models/NotificationChannelDetails.java +++ /dev/null @@ -1,101 +0,0 @@ -package com.dexterous.flutterlocalnotifications.models; - -import android.graphics.Color; -import androidx.annotation.Keep; -import java.io.Serializable; -import java.util.Map; - -@Keep -public class NotificationChannelDetails implements Serializable { - private static final String ID = "id"; - private static final String NAME = "name"; - private static final String DESCRIPTION = "description"; - private static final String GROUP_ID = "groupId"; - private static final String SHOW_BADGE = "showBadge"; - private static final String IMPORTANCE = "importance"; - private static final String PLAY_SOUND = "playSound"; - private static final String SOUND = "sound"; - private static final String SOUND_SOURCE = "soundSource"; - private static final String ENABLE_VIBRATION = "enableVibration"; - private static final String VIBRATION_PATTERN = "vibrationPattern"; - private static final String CHANNEL_ACTION = "channelAction"; - private static final String ENABLE_LIGHTS = "enableLights"; - private static final String LED_COLOR_ALPHA = "ledColorAlpha"; - private static final String LED_COLOR_RED = "ledColorRed"; - private static final String LED_COLOR_GREEN = "ledColorGreen"; - private static final String LED_COLOR_BLUE = "ledColorBlue"; - private static final String AUDIO_ATTRIBUTES_USAGE = "audioAttributesUsage"; - - public String id; - public String name; - public String description; - public String groupId; - public Boolean showBadge; - public Integer importance; - public Boolean playSound; - public String sound; - public SoundSource soundSource; - public Boolean enableVibration; - public long[] vibrationPattern; - public NotificationChannelAction channelAction; - public Boolean enableLights; - public Integer ledColor; - public Integer audioAttributesUsage; - - public static NotificationChannelDetails from(Map arguments) { - NotificationChannelDetails notificationChannel = new NotificationChannelDetails(); - notificationChannel.id = (String) arguments.get(ID); - notificationChannel.name = (String) arguments.get(NAME); - notificationChannel.description = (String) arguments.get(DESCRIPTION); - notificationChannel.groupId = (String) arguments.get(GROUP_ID); - notificationChannel.importance = (Integer) arguments.get(IMPORTANCE); - notificationChannel.showBadge = (Boolean) arguments.get(SHOW_BADGE); - notificationChannel.channelAction = - NotificationChannelAction.values()[(Integer) arguments.get(CHANNEL_ACTION)]; - notificationChannel.enableVibration = (Boolean) arguments.get(ENABLE_VIBRATION); - notificationChannel.vibrationPattern = (long[]) arguments.get(VIBRATION_PATTERN); - - notificationChannel.playSound = (Boolean) arguments.get(PLAY_SOUND); - notificationChannel.sound = (String) arguments.get(SOUND); - notificationChannel.audioAttributesUsage = (Integer) arguments.get(AUDIO_ATTRIBUTES_USAGE); - Integer soundSourceIndex = (Integer) arguments.get(SOUND_SOURCE); - if (soundSourceIndex != null) { - notificationChannel.soundSource = SoundSource.values()[soundSourceIndex]; - } - - Integer a = (Integer) arguments.get(LED_COLOR_ALPHA); - Integer r = (Integer) arguments.get(LED_COLOR_RED); - Integer g = (Integer) arguments.get(LED_COLOR_GREEN); - Integer b = (Integer) arguments.get(LED_COLOR_BLUE); - if (a != null && r != null && g != null && b != null) { - notificationChannel.ledColor = Color.argb(a, r, g, b); - } - - notificationChannel.enableLights = (Boolean) arguments.get(ENABLE_LIGHTS); - return notificationChannel; - } - - public static NotificationChannelDetails fromNotificationDetails( - NotificationDetails notificationDetails) { - NotificationChannelDetails notificationChannel = new NotificationChannelDetails(); - notificationChannel.id = notificationDetails.channelId; - notificationChannel.name = notificationDetails.channelName; - notificationChannel.description = notificationDetails.channelDescription; - notificationChannel.importance = notificationDetails.importance; - notificationChannel.showBadge = notificationDetails.channelShowBadge; - if (notificationDetails.channelAction == null) { - notificationChannel.channelAction = NotificationChannelAction.CreateIfNotExists; - } else { - notificationChannel.channelAction = notificationDetails.channelAction; - } - notificationChannel.enableVibration = notificationDetails.enableVibration; - notificationChannel.vibrationPattern = notificationDetails.vibrationPattern; - notificationChannel.playSound = notificationDetails.playSound; - notificationChannel.sound = notificationDetails.sound; - notificationChannel.soundSource = notificationDetails.soundSource; - notificationChannel.audioAttributesUsage = notificationDetails.audioAttributesUsage; - notificationChannel.ledColor = notificationDetails.ledColor; - notificationChannel.enableLights = notificationDetails.enableLights; - return notificationChannel; - } -} diff --git a/flutter_local_notifications/android/src/main/java/com/dexterous/flutterlocalnotifications/models/NotificationChannelGroupDetails.java b/flutter_local_notifications/android/src/main/java/com/dexterous/flutterlocalnotifications/models/NotificationChannelGroupDetails.java deleted file mode 100644 index 67d767eff..000000000 --- a/flutter_local_notifications/android/src/main/java/com/dexterous/flutterlocalnotifications/models/NotificationChannelGroupDetails.java +++ /dev/null @@ -1,26 +0,0 @@ -package com.dexterous.flutterlocalnotifications.models; - -import androidx.annotation.Keep; - -import java.io.Serializable; -import java.util.Map; - -@Keep -public class NotificationChannelGroupDetails implements Serializable { - private static final String ID = "id"; - private static final String NAME = "name"; - private static final String DESCRIPTION = "description"; - - public String id; - public String name; - public String description; - - public static NotificationChannelGroupDetails from(Map arguments) { - NotificationChannelGroupDetails notificationChannelGroupDetails = - new NotificationChannelGroupDetails(); - notificationChannelGroupDetails.id = (String) arguments.get(ID); - notificationChannelGroupDetails.name = (String) arguments.get(NAME); - notificationChannelGroupDetails.description = (String) arguments.get(DESCRIPTION); - return notificationChannelGroupDetails; - } -} diff --git a/flutter_local_notifications/android/src/main/java/com/dexterous/flutterlocalnotifications/models/NotificationDetails.java b/flutter_local_notifications/android/src/main/java/com/dexterous/flutterlocalnotifications/models/NotificationDetails.java deleted file mode 100644 index dcb59648a..000000000 --- a/flutter_local_notifications/android/src/main/java/com/dexterous/flutterlocalnotifications/models/NotificationDetails.java +++ /dev/null @@ -1,562 +0,0 @@ -package com.dexterous.flutterlocalnotifications.models; - -import android.graphics.Color; -import android.os.Build.VERSION; -import android.os.Build.VERSION_CODES; - -import androidx.annotation.Keep; -import androidx.annotation.Nullable; - -import com.dexterous.flutterlocalnotifications.models.styles.BigPictureStyleInformation; -import com.dexterous.flutterlocalnotifications.models.styles.BigTextStyleInformation; -import com.dexterous.flutterlocalnotifications.models.styles.DefaultStyleInformation; -import com.dexterous.flutterlocalnotifications.models.styles.InboxStyleInformation; -import com.dexterous.flutterlocalnotifications.models.styles.MessagingStyleInformation; -import com.dexterous.flutterlocalnotifications.models.styles.StyleInformation; -import com.dexterous.flutterlocalnotifications.utils.LongUtils; -import com.google.gson.annotations.SerializedName; - -import java.io.Serializable; -import java.util.ArrayList; -import java.util.List; -import java.util.Map; - -@Keep -public class NotificationDetails implements Serializable { - private static final String ID = "id"; - private static final String TITLE = "title"; - private static final String BODY = "body"; - private static final String PAYLOAD = "payload"; - private static final String MILLISECONDS_SINCE_EPOCH = "millisecondsSinceEpoch"; - private static final String CALLED_AT = "calledAt"; - private static final String REPEAT_INTERVAL = "repeatInterval"; - private static final String REPEAT_INTERVAL_MILLISECONDS = "repeatIntervalMilliseconds"; - private static final String REPEAT_TIME = "repeatTime"; - private static final String PLATFORM_SPECIFICS = "platformSpecifics"; - private static final String AUTO_CANCEL = "autoCancel"; - private static final String ONGOING = "ongoing"; - private static final String SILENT = "silent"; - private static final String STYLE = "style"; - private static final String ICON = "icon"; - private static final String PRIORITY = "priority"; - private static final String PLAY_SOUND = "playSound"; - private static final String SOUND = "sound"; - private static final String SOUND_SOURCE = "soundSource"; - private static final String ENABLE_VIBRATION = "enableVibration"; - private static final String VIBRATION_PATTERN = "vibrationPattern"; - private static final String TAG = "tag"; - private static final String GROUP_KEY = "groupKey"; - private static final String SET_AS_GROUP_SUMMARY = "setAsGroupSummary"; - private static final String GROUP_ALERT_BEHAVIOR = "groupAlertBehavior"; - private static final String ONLY_ALERT_ONCE = "onlyAlertOnce"; - private static final String CHANNEL_ID = "channelId"; - private static final String CHANNEL_NAME = "channelName"; - private static final String CHANNEL_DESCRIPTION = "channelDescription"; - private static final String CHANNEL_SHOW_BADGE = "channelShowBadge"; - private static final String IMPORTANCE = "importance"; - private static final String STYLE_INFORMATION = "styleInformation"; - private static final String BIG_TEXT = "bigText"; - private static final String HTML_FORMAT_BIG_TEXT = "htmlFormatBigText"; - private static final String CONTENT_TITLE = "contentTitle"; - private static final String HTML_FORMAT_CONTENT_TITLE = "htmlFormatContentTitle"; - private static final String SUMMARY_TEXT = "summaryText"; - private static final String HTML_FORMAT_SUMMARY_TEXT = "htmlFormatSummaryText"; - private static final String LINES = "lines"; - private static final String HTML_FORMAT_LINES = "htmlFormatLines"; - private static final String HTML_FORMAT_TITLE = "htmlFormatTitle"; - private static final String HTML_FORMAT_CONTENT = "htmlFormatContent"; - private static final String DAY = "day"; - private static final String COLOR_ALPHA = "colorAlpha"; - private static final String COLOR_RED = "colorRed"; - private static final String COLOR_GREEN = "colorGreen"; - private static final String COLOR_BLUE = "colorBlue"; - private static final String LARGE_ICON = "largeIcon"; - private static final String LARGE_ICON_BITMAP_SOURCE = "largeIconBitmapSource"; - private static final String BIG_PICTURE = "bigPicture"; - private static final String BIG_PICTURE_BITMAP_SOURCE = "bigPictureBitmapSource"; - private static final String HIDE_EXPANDED_LARGE_ICON = "hideExpandedLargeIcon"; - private static final String SHOW_PROGRESS = "showProgress"; - private static final String MAX_PROGRESS = "maxProgress"; - private static final String PROGRESS = "progress"; - private static final String INDETERMINATE = "indeterminate"; - private static final String PERSON = "person"; - private static final String CONVERSATION_TITLE = "conversationTitle"; - private static final String GROUP_CONVERSATION = "groupConversation"; - private static final String MESSAGES = "messages"; - private static final String TEXT = "text"; - private static final String TIMESTAMP = "timestamp"; - private static final String BOT = "bot"; - private static final String ICON_SOURCE = "iconSource"; - private static final String IMPORTANT = "important"; - private static final String KEY = "key"; - private static final String NAME = "name"; - private static final String URI = "uri"; - private static final String DATA_MIME_TYPE = "dataMimeType"; - private static final String DATA_URI = "dataUri"; - private static final String CHANNEL_ACTION = "channelAction"; - private static final String ENABLE_LIGHTS = "enableLights"; - private static final String LED_COLOR_ALPHA = "ledColorAlpha"; - private static final String LED_COLOR_RED = "ledColorRed"; - private static final String LED_COLOR_GREEN = "ledColorGreen"; - private static final String LED_COLOR_BLUE = "ledColorBlue"; - - private static final String LED_ON_MS = "ledOnMs"; - private static final String LED_OFF_MS = "ledOffMs"; - private static final String VISIBILITY = "visibility"; - - private static final String TICKER = "ticker"; - private static final String SCHEDULE_MODE = "scheduleMode"; - private static final String CATEGORY = "category"; - private static final String TIMEOUT_AFTER = "timeoutAfter"; - private static final String SHOW_WHEN = "showWhen"; - private static final String WHEN = "when"; - private static final String USES_CHRONOMETER = "usesChronometer"; - private static final String CHRONOMETER_COUNT_DOWN = "chronometerCountDown"; - private static final String ADDITIONAL_FLAGS = "additionalFlags"; - - private static final String SCHEDULED_DATE_TIME = "scheduledDateTime"; - private static final String TIME_ZONE_NAME = "timeZoneName"; - private static final String SCHEDULED_NOTIFICATION_REPEAT_FREQUENCY = - "scheduledNotificationRepeatFrequency"; - private static final String MATCH_DATE_TIME_COMPONENTS = "matchDateTimeComponents"; - - private static final String FULL_SCREEN_INTENT = "fullScreenIntent"; - private static final String SHORTCUT_ID = "shortcutId"; - private static final String SUB_TEXT = "subText"; - private static final String ACTIONS = "actions"; - private static final String COLORIZED = "colorized"; - private static final String NUMBER = "number"; - private static final String AUDIO_ATTRIBUTES_USAGE = "audioAttributesUsage"; - - public Integer id; - public String title; - public String body; - public String icon; - public String channelId = "Default_Channel_Id"; - public String channelName; - public String channelDescription; - public Boolean channelShowBadge; - public Integer importance; - public Integer priority; - public Boolean playSound; - public String sound; - public SoundSource soundSource; - public Boolean enableVibration; - public long[] vibrationPattern; - public NotificationStyle style; - public StyleInformation styleInformation; - public RepeatInterval repeatInterval; - public Integer repeatIntervalMilliseconds; - public Time repeatTime; - public Long millisecondsSinceEpoch; - public Long calledAt; - public String payload; - public String groupKey; - public Boolean setAsGroupSummary; - public Integer groupAlertBehavior; - public Boolean autoCancel; - public Boolean ongoing; - public Boolean silent; - public Integer day; - public Integer color; - public Object largeIcon; - public BitmapSource largeIconBitmapSource; - public Boolean onlyAlertOnce; - public Boolean showProgress; - public Integer maxProgress; - public Integer progress; - public Boolean indeterminate; - public NotificationChannelAction channelAction; - public Boolean enableLights; - public Integer ledColor; - public Integer ledOnMs; - public Integer ledOffMs; - public String ticker; - public Integer visibility; - - @SerializedName(value = "scheduleMode", alternate = "allowWhileIdle") - public ScheduleMode scheduleMode; - - public Long timeoutAfter; - public String category; - public int[] additionalFlags; - public Boolean showWhen; - public Boolean usesChronometer; - public Boolean chronometerCountDown; - public String scheduledDateTime; - public String timeZoneName; - public ScheduledNotificationRepeatFrequency scheduledNotificationRepeatFrequency; - public DateTimeComponents matchDateTimeComponents; - public Long when; - public Boolean fullScreenIntent; - public String shortcutId; - public String subText; - public @Nullable List actions; - public String tag; - public Boolean colorized; - public Integer number; - public Integer audioAttributesUsage; - - // Note: this is set on the Android to save details about the icon that should be used when - // re-hydrating scheduled notifications when a device has been restarted. - public Integer iconResourceId; - - public static NotificationDetails from(Map arguments) { - NotificationDetails notificationDetails = new NotificationDetails(); - notificationDetails.payload = (String) arguments.get(PAYLOAD); - notificationDetails.id = (Integer) arguments.get(ID); - notificationDetails.title = (String) arguments.get(TITLE); - notificationDetails.body = (String) arguments.get(BODY); - notificationDetails.scheduledDateTime = (String) arguments.get(SCHEDULED_DATE_TIME); - notificationDetails.timeZoneName = (String) arguments.get(TIME_ZONE_NAME); - if (arguments.containsKey(SCHEDULED_NOTIFICATION_REPEAT_FREQUENCY)) { - notificationDetails.scheduledNotificationRepeatFrequency = - ScheduledNotificationRepeatFrequency.values()[ - (Integer) arguments.get(SCHEDULED_NOTIFICATION_REPEAT_FREQUENCY)]; - } - if (arguments.containsKey(MATCH_DATE_TIME_COMPONENTS)) { - notificationDetails.matchDateTimeComponents = - DateTimeComponents.values()[(Integer) arguments.get(MATCH_DATE_TIME_COMPONENTS)]; - } - if (arguments.containsKey(MILLISECONDS_SINCE_EPOCH)) { - notificationDetails.millisecondsSinceEpoch = (Long) arguments.get(MILLISECONDS_SINCE_EPOCH); - } - if (arguments.containsKey(CALLED_AT)) { - notificationDetails.calledAt = (Long) arguments.get(CALLED_AT); - } - if (arguments.containsKey(REPEAT_INTERVAL)) { - notificationDetails.repeatInterval = - RepeatInterval.values()[(Integer) arguments.get(REPEAT_INTERVAL)]; - } - if (arguments.containsKey(REPEAT_INTERVAL_MILLISECONDS)) { - notificationDetails.repeatIntervalMilliseconds = - (Integer) arguments.get(REPEAT_INTERVAL_MILLISECONDS); - } - if (arguments.containsKey(REPEAT_TIME)) { - @SuppressWarnings("unchecked") - Map repeatTimeParams = (Map) arguments.get(REPEAT_TIME); - notificationDetails.repeatTime = Time.from(repeatTimeParams); - } - if (arguments.containsKey(DAY)) { - notificationDetails.day = (Integer) arguments.get(DAY); - } - - readPlatformSpecifics(arguments, notificationDetails); - return notificationDetails; - } - - private static void readPlatformSpecifics( - Map arguments, NotificationDetails notificationDetails) { - @SuppressWarnings("unchecked") - Map platformChannelSpecifics = - (Map) arguments.get(PLATFORM_SPECIFICS); - if (platformChannelSpecifics != null) { - notificationDetails.autoCancel = (Boolean) platformChannelSpecifics.get(AUTO_CANCEL); - notificationDetails.ongoing = (Boolean) platformChannelSpecifics.get(ONGOING); - notificationDetails.silent = (Boolean) platformChannelSpecifics.get(SILENT); - notificationDetails.style = - NotificationStyle.values()[(Integer) platformChannelSpecifics.get(STYLE)]; - readStyleInformation(notificationDetails, platformChannelSpecifics); - notificationDetails.icon = (String) platformChannelSpecifics.get(ICON); - notificationDetails.priority = (Integer) platformChannelSpecifics.get(PRIORITY); - readSoundInformation(notificationDetails, platformChannelSpecifics); - notificationDetails.enableVibration = - (Boolean) platformChannelSpecifics.get(ENABLE_VIBRATION); - notificationDetails.vibrationPattern = - (long[]) platformChannelSpecifics.get(VIBRATION_PATTERN); - readGroupingInformation(notificationDetails, platformChannelSpecifics); - notificationDetails.onlyAlertOnce = (Boolean) platformChannelSpecifics.get(ONLY_ALERT_ONCE); - notificationDetails.showWhen = (Boolean) platformChannelSpecifics.get(SHOW_WHEN); - notificationDetails.when = LongUtils.parseLong(platformChannelSpecifics.get(WHEN)); - notificationDetails.usesChronometer = - (Boolean) platformChannelSpecifics.get(USES_CHRONOMETER); - notificationDetails.chronometerCountDown = - (Boolean) platformChannelSpecifics.get(CHRONOMETER_COUNT_DOWN); - readProgressInformation(notificationDetails, platformChannelSpecifics); - readColor(notificationDetails, platformChannelSpecifics); - readChannelInformation(notificationDetails, platformChannelSpecifics); - readLedInformation(notificationDetails, platformChannelSpecifics); - readLargeIconInformation(notificationDetails, platformChannelSpecifics); - notificationDetails.ticker = (String) platformChannelSpecifics.get(TICKER); - notificationDetails.visibility = (Integer) platformChannelSpecifics.get(VISIBILITY); - if (platformChannelSpecifics.containsKey(SCHEDULE_MODE)) { - notificationDetails.scheduleMode = - ScheduleMode.valueOf((String) platformChannelSpecifics.get(SCHEDULE_MODE)); - } - notificationDetails.timeoutAfter = - LongUtils.parseLong(platformChannelSpecifics.get(TIMEOUT_AFTER)); - notificationDetails.category = (String) platformChannelSpecifics.get(CATEGORY); - notificationDetails.fullScreenIntent = - (Boolean) platformChannelSpecifics.get((FULL_SCREEN_INTENT)); - notificationDetails.shortcutId = (String) platformChannelSpecifics.get(SHORTCUT_ID); - notificationDetails.additionalFlags = (int[]) platformChannelSpecifics.get(ADDITIONAL_FLAGS); - notificationDetails.subText = (String) platformChannelSpecifics.get(SUB_TEXT); - notificationDetails.tag = (String) platformChannelSpecifics.get(TAG); - notificationDetails.colorized = (Boolean) platformChannelSpecifics.get(COLORIZED); - notificationDetails.number = (Integer) platformChannelSpecifics.get(NUMBER); - notificationDetails.audioAttributesUsage = - (Integer) platformChannelSpecifics.get(AUDIO_ATTRIBUTES_USAGE); - - if (platformChannelSpecifics.containsKey(ACTIONS)) { - @SuppressWarnings("unchecked") - List> inputActions = - (List>) platformChannelSpecifics.get(ACTIONS); - if (inputActions != null && !inputActions.isEmpty()) { - notificationDetails.actions = new ArrayList<>(); - for (Map input : inputActions) { - final NotificationAction action = new NotificationAction(input); - notificationDetails.actions.add(action); - } - } - } - } - } - - private static void readProgressInformation( - NotificationDetails notificationDetails, Map platformChannelSpecifics) { - notificationDetails.showProgress = (Boolean) platformChannelSpecifics.get(SHOW_PROGRESS); - if (platformChannelSpecifics.containsKey(MAX_PROGRESS)) { - notificationDetails.maxProgress = (Integer) platformChannelSpecifics.get(MAX_PROGRESS); - } - - if (platformChannelSpecifics.containsKey(PROGRESS)) { - notificationDetails.progress = (Integer) platformChannelSpecifics.get(PROGRESS); - } - - if (platformChannelSpecifics.containsKey(INDETERMINATE)) { - notificationDetails.indeterminate = (Boolean) platformChannelSpecifics.get(INDETERMINATE); - } - } - - private static void readLargeIconInformation( - NotificationDetails notificationDetails, Map platformChannelSpecifics) { - notificationDetails.largeIcon = platformChannelSpecifics.get(LARGE_ICON); - if (platformChannelSpecifics.containsKey(LARGE_ICON_BITMAP_SOURCE)) { - Integer argumentValue = (Integer) platformChannelSpecifics.get(LARGE_ICON_BITMAP_SOURCE); - if (argumentValue != null) { - notificationDetails.largeIconBitmapSource = BitmapSource.values()[argumentValue]; - } - } - } - - private static void readGroupingInformation( - NotificationDetails notificationDetails, Map platformChannelSpecifics) { - notificationDetails.groupKey = (String) platformChannelSpecifics.get(GROUP_KEY); - notificationDetails.setAsGroupSummary = - (Boolean) platformChannelSpecifics.get(SET_AS_GROUP_SUMMARY); - notificationDetails.groupAlertBehavior = - (Integer) platformChannelSpecifics.get(GROUP_ALERT_BEHAVIOR); - } - - private static void readSoundInformation( - NotificationDetails notificationDetails, Map platformChannelSpecifics) { - notificationDetails.playSound = (Boolean) platformChannelSpecifics.get(PLAY_SOUND); - notificationDetails.sound = (String) platformChannelSpecifics.get(SOUND); - Integer soundSourceIndex = (Integer) platformChannelSpecifics.get(SOUND_SOURCE); - if (soundSourceIndex != null) { - notificationDetails.soundSource = SoundSource.values()[soundSourceIndex]; - } - } - - private static void readColor( - NotificationDetails notificationDetails, Map platformChannelSpecifics) { - Integer a = (Integer) platformChannelSpecifics.get(COLOR_ALPHA); - Integer r = (Integer) platformChannelSpecifics.get(COLOR_RED); - Integer g = (Integer) platformChannelSpecifics.get(COLOR_GREEN); - Integer b = (Integer) platformChannelSpecifics.get(COLOR_BLUE); - if (a != null && r != null && g != null && b != null) { - notificationDetails.color = Color.argb(a, r, g, b); - } - } - - private static void readLedInformation( - NotificationDetails notificationDetails, Map platformChannelSpecifics) { - Integer a = (Integer) platformChannelSpecifics.get(LED_COLOR_ALPHA); - Integer r = (Integer) platformChannelSpecifics.get(LED_COLOR_RED); - Integer g = (Integer) platformChannelSpecifics.get(LED_COLOR_GREEN); - Integer b = (Integer) platformChannelSpecifics.get(LED_COLOR_BLUE); - if (a != null && r != null && g != null && b != null) { - notificationDetails.ledColor = Color.argb(a, r, g, b); - } - notificationDetails.enableLights = (Boolean) platformChannelSpecifics.get(ENABLE_LIGHTS); - notificationDetails.ledOnMs = (Integer) platformChannelSpecifics.get(LED_ON_MS); - notificationDetails.ledOffMs = (Integer) platformChannelSpecifics.get(LED_OFF_MS); - } - - private static void readChannelInformation( - NotificationDetails notificationDetails, Map platformChannelSpecifics) { - if (VERSION.SDK_INT >= VERSION_CODES.O) { - notificationDetails.channelId = (String) platformChannelSpecifics.get(CHANNEL_ID); - notificationDetails.channelName = (String) platformChannelSpecifics.get(CHANNEL_NAME); - notificationDetails.channelDescription = - (String) platformChannelSpecifics.get(CHANNEL_DESCRIPTION); - notificationDetails.importance = (Integer) platformChannelSpecifics.get(IMPORTANCE); - notificationDetails.channelShowBadge = - (Boolean) platformChannelSpecifics.get(CHANNEL_SHOW_BADGE); - notificationDetails.channelAction = - NotificationChannelAction.values()[ - (Integer) platformChannelSpecifics.get(CHANNEL_ACTION)]; - } - } - - @SuppressWarnings("unchecked") - private static void readStyleInformation( - NotificationDetails notificationDetails, Map platformSpecifics) { - Map styleInformation = - (Map) platformSpecifics.get(STYLE_INFORMATION); - DefaultStyleInformation defaultStyleInformation = getDefaultStyleInformation(styleInformation); - if (notificationDetails.style == NotificationStyle.Default) { - notificationDetails.styleInformation = defaultStyleInformation; - } else if (notificationDetails.style == NotificationStyle.BigPicture) { - readBigPictureStyleInformation( - notificationDetails, styleInformation, defaultStyleInformation); - } else if (notificationDetails.style == NotificationStyle.BigText) { - readBigTextStyleInformation(notificationDetails, styleInformation, defaultStyleInformation); - } else if (notificationDetails.style == NotificationStyle.Inbox) { - readInboxStyleInformation(notificationDetails, styleInformation, defaultStyleInformation); - } else if (notificationDetails.style == NotificationStyle.Messaging) { - readMessagingStyleInformation(notificationDetails, styleInformation, defaultStyleInformation); - } else if (notificationDetails.style == NotificationStyle.Media) { - notificationDetails.styleInformation = defaultStyleInformation; - } - } - - @SuppressWarnings("unchecked") - private static void readMessagingStyleInformation( - NotificationDetails notificationDetails, - Map styleInformation, - DefaultStyleInformation defaultStyleInformation) { - String conversationTitle = (String) styleInformation.get(CONVERSATION_TITLE); - Boolean groupConversation = (Boolean) styleInformation.get(GROUP_CONVERSATION); - PersonDetails person = readPersonDetails((Map) styleInformation.get(PERSON)); - ArrayList messages = - readMessages((ArrayList>) styleInformation.get(MESSAGES)); - notificationDetails.styleInformation = - new MessagingStyleInformation( - person, - conversationTitle, - groupConversation, - messages, - defaultStyleInformation.htmlFormatTitle, - defaultStyleInformation.htmlFormatBody); - } - - private static PersonDetails readPersonDetails(Map person) { - if (person == null) { - return null; - } - Boolean bot = (Boolean) person.get(BOT); - Object icon = person.get(ICON); - Integer iconSourceIndex = (Integer) person.get(ICON_SOURCE); - IconSource iconSource = iconSourceIndex == null ? null : IconSource.values()[iconSourceIndex]; - Boolean important = (Boolean) person.get(IMPORTANT); - String key = (String) person.get(KEY); - String name = (String) person.get(NAME); - String uri = (String) person.get(URI); - return new PersonDetails(bot, icon, iconSource, important, key, name, uri); - } - - @SuppressWarnings("unchecked") - private static ArrayList readMessages(ArrayList> messages) { - ArrayList result = new ArrayList<>(); - if (messages != null) { - for (Map messageData : messages) { - result.add( - new MessageDetails( - (String) messageData.get(TEXT), - LongUtils.parseLong(messageData.get(TIMESTAMP)), - readPersonDetails((Map) messageData.get(PERSON)), - (String) messageData.get(DATA_MIME_TYPE), - (String) messageData.get(DATA_URI))); - } - } - return result; - } - - private static void readInboxStyleInformation( - NotificationDetails notificationDetails, - Map styleInformation, - DefaultStyleInformation defaultStyleInformation) { - String contentTitle = (String) styleInformation.get(CONTENT_TITLE); - Boolean htmlFormatContentTitle = (Boolean) styleInformation.get(HTML_FORMAT_CONTENT_TITLE); - String summaryText = (String) styleInformation.get(SUMMARY_TEXT); - Boolean htmlFormatSummaryText = (Boolean) styleInformation.get(HTML_FORMAT_SUMMARY_TEXT); - @SuppressWarnings("unchecked") - ArrayList lines = (ArrayList) styleInformation.get(LINES); - Boolean htmlFormatLines = (Boolean) styleInformation.get(HTML_FORMAT_LINES); - notificationDetails.styleInformation = - new InboxStyleInformation( - defaultStyleInformation.htmlFormatTitle, - defaultStyleInformation.htmlFormatBody, - contentTitle, - htmlFormatContentTitle, - summaryText, - htmlFormatSummaryText, - lines, - htmlFormatLines); - } - - private static void readBigTextStyleInformation( - NotificationDetails notificationDetails, - Map styleInformation, - DefaultStyleInformation defaultStyleInformation) { - String bigText = (String) styleInformation.get(BIG_TEXT); - Boolean htmlFormatBigText = (Boolean) styleInformation.get(HTML_FORMAT_BIG_TEXT); - String contentTitle = (String) styleInformation.get(CONTENT_TITLE); - Boolean htmlFormatContentTitle = (Boolean) styleInformation.get(HTML_FORMAT_CONTENT_TITLE); - String summaryText = (String) styleInformation.get(SUMMARY_TEXT); - Boolean htmlFormatSummaryText = (Boolean) styleInformation.get(HTML_FORMAT_SUMMARY_TEXT); - notificationDetails.styleInformation = - new BigTextStyleInformation( - defaultStyleInformation.htmlFormatTitle, - defaultStyleInformation.htmlFormatBody, - bigText, - htmlFormatBigText, - contentTitle, - htmlFormatContentTitle, - summaryText, - htmlFormatSummaryText); - } - - private static void readBigPictureStyleInformation( - NotificationDetails notificationDetails, - Map styleInformation, - DefaultStyleInformation defaultStyleInformation) { - String contentTitle = (String) styleInformation.get(CONTENT_TITLE); - Boolean htmlFormatContentTitle = (Boolean) styleInformation.get(HTML_FORMAT_CONTENT_TITLE); - String summaryText = (String) styleInformation.get(SUMMARY_TEXT); - Boolean htmlFormatSummaryText = (Boolean) styleInformation.get(HTML_FORMAT_SUMMARY_TEXT); - Object largeIcon = styleInformation.get(LARGE_ICON); - BitmapSource largeIconBitmapSource = null; - if (styleInformation.containsKey(LARGE_ICON_BITMAP_SOURCE)) { - Integer largeIconBitmapSourceArgument = - (Integer) styleInformation.get(LARGE_ICON_BITMAP_SOURCE); - largeIconBitmapSource = BitmapSource.values()[largeIconBitmapSourceArgument]; - } - Object bigPicture = styleInformation.get(BIG_PICTURE); - Integer bigPictureBitmapSourceArgument = - (Integer) styleInformation.get(BIG_PICTURE_BITMAP_SOURCE); - BitmapSource bigPictureBitmapSource = BitmapSource.values()[bigPictureBitmapSourceArgument]; - Boolean showThumbnail = (Boolean) styleInformation.get(HIDE_EXPANDED_LARGE_ICON); - notificationDetails.styleInformation = - new BigPictureStyleInformation( - defaultStyleInformation.htmlFormatTitle, - defaultStyleInformation.htmlFormatBody, - contentTitle, - htmlFormatContentTitle, - summaryText, - htmlFormatSummaryText, - largeIcon, - largeIconBitmapSource, - bigPicture, - bigPictureBitmapSource, - showThumbnail); - } - - private static DefaultStyleInformation getDefaultStyleInformation( - Map styleInformation) { - Boolean htmlFormatTitle = (Boolean) styleInformation.get(HTML_FORMAT_TITLE); - Boolean htmlFormatBody = (Boolean) styleInformation.get(HTML_FORMAT_CONTENT); - return new DefaultStyleInformation(htmlFormatTitle, htmlFormatBody); - } -} diff --git a/flutter_local_notifications/android/src/main/java/com/dexterous/flutterlocalnotifications/models/NotificationStyle.java b/flutter_local_notifications/android/src/main/java/com/dexterous/flutterlocalnotifications/models/NotificationStyle.java deleted file mode 100644 index e91a13e74..000000000 --- a/flutter_local_notifications/android/src/main/java/com/dexterous/flutterlocalnotifications/models/NotificationStyle.java +++ /dev/null @@ -1,13 +0,0 @@ -package com.dexterous.flutterlocalnotifications.models; - -import androidx.annotation.Keep; - -@Keep -public enum NotificationStyle { - Default, - BigPicture, - BigText, - Inbox, - Messaging, - Media -} diff --git a/flutter_local_notifications/android/src/main/java/com/dexterous/flutterlocalnotifications/models/PersonDetails.java b/flutter_local_notifications/android/src/main/java/com/dexterous/flutterlocalnotifications/models/PersonDetails.java deleted file mode 100644 index 04c923830..000000000 --- a/flutter_local_notifications/android/src/main/java/com/dexterous/flutterlocalnotifications/models/PersonDetails.java +++ /dev/null @@ -1,33 +0,0 @@ -package com.dexterous.flutterlocalnotifications.models; - -import androidx.annotation.Keep; - -import java.io.Serializable; - -@Keep -public class PersonDetails implements Serializable { - public Boolean bot; - public Object icon; - public IconSource iconBitmapSource; - public Boolean important; - public String key; - public String name; - public String uri; - - public PersonDetails( - Boolean bot, - Object icon, - IconSource iconSource, - Boolean important, - String key, - String name, - String uri) { - this.bot = bot; - this.icon = icon; - this.iconBitmapSource = iconSource; - this.important = important; - this.key = key; - this.name = name; - this.uri = uri; - } -} diff --git a/flutter_local_notifications/android/src/main/java/com/dexterous/flutterlocalnotifications/models/RepeatInterval.java b/flutter_local_notifications/android/src/main/java/com/dexterous/flutterlocalnotifications/models/RepeatInterval.java deleted file mode 100644 index 4ad5b6deb..000000000 --- a/flutter_local_notifications/android/src/main/java/com/dexterous/flutterlocalnotifications/models/RepeatInterval.java +++ /dev/null @@ -1,11 +0,0 @@ -package com.dexterous.flutterlocalnotifications.models; - -import androidx.annotation.Keep; - -@Keep -public enum RepeatInterval { - EveryMinute, - Hourly, - Daily, - Weekly -} diff --git a/flutter_local_notifications/android/src/main/java/com/dexterous/flutterlocalnotifications/models/ScheduleMode.java b/flutter_local_notifications/android/src/main/java/com/dexterous/flutterlocalnotifications/models/ScheduleMode.java deleted file mode 100644 index 91608b9f3..000000000 --- a/flutter_local_notifications/android/src/main/java/com/dexterous/flutterlocalnotifications/models/ScheduleMode.java +++ /dev/null @@ -1,41 +0,0 @@ -package com.dexterous.flutterlocalnotifications.models; - -import androidx.annotation.Keep; - -import com.google.gson.*; - -import java.lang.reflect.Type; - -@Keep -public enum ScheduleMode { - alarmClock, - exact, - exactAllowWhileIdle, - inexact, - inexactAllowWhileIdle; - - public boolean useAllowWhileIdle() { - return this == exactAllowWhileIdle || this == inexactAllowWhileIdle; - } - - public boolean useExactAlarm() { - return this == exact || this == exactAllowWhileIdle; - } - - public boolean useAlarmClock() { - return this == alarmClock; - } - - public static class Deserializer implements JsonDeserializer { - @Override - public ScheduleMode deserialize( - JsonElement json, Type typeOfT, JsonDeserializationContext context) - throws JsonParseException { - try { - return ScheduleMode.valueOf(json.getAsString()); - } catch (Exception e) { - return json.getAsBoolean() ? ScheduleMode.exactAllowWhileIdle : ScheduleMode.exact; - } - } - } -} diff --git a/flutter_local_notifications/android/src/main/java/com/dexterous/flutterlocalnotifications/models/ScheduledNotificationRepeatFrequency.java b/flutter_local_notifications/android/src/main/java/com/dexterous/flutterlocalnotifications/models/ScheduledNotificationRepeatFrequency.java deleted file mode 100644 index 3e4df1933..000000000 --- a/flutter_local_notifications/android/src/main/java/com/dexterous/flutterlocalnotifications/models/ScheduledNotificationRepeatFrequency.java +++ /dev/null @@ -1,9 +0,0 @@ -package com.dexterous.flutterlocalnotifications.models; - -import androidx.annotation.Keep; - -@Keep -public enum ScheduledNotificationRepeatFrequency { - Daily, - Weekly -} diff --git a/flutter_local_notifications/android/src/main/java/com/dexterous/flutterlocalnotifications/models/SoundSource.java b/flutter_local_notifications/android/src/main/java/com/dexterous/flutterlocalnotifications/models/SoundSource.java deleted file mode 100644 index 3d7f3be88..000000000 --- a/flutter_local_notifications/android/src/main/java/com/dexterous/flutterlocalnotifications/models/SoundSource.java +++ /dev/null @@ -1,9 +0,0 @@ -package com.dexterous.flutterlocalnotifications.models; - -import androidx.annotation.Keep; - -@Keep -public enum SoundSource { - RawResource, - Uri -} diff --git a/flutter_local_notifications/android/src/main/java/com/dexterous/flutterlocalnotifications/models/styles/BigPictureStyleInformation.java b/flutter_local_notifications/android/src/main/java/com/dexterous/flutterlocalnotifications/models/styles/BigPictureStyleInformation.java deleted file mode 100644 index 3c433677a..000000000 --- a/flutter_local_notifications/android/src/main/java/com/dexterous/flutterlocalnotifications/models/styles/BigPictureStyleInformation.java +++ /dev/null @@ -1,42 +0,0 @@ -package com.dexterous.flutterlocalnotifications.models.styles; - -import androidx.annotation.Keep; - -import com.dexterous.flutterlocalnotifications.models.BitmapSource; - -@Keep -public class BigPictureStyleInformation extends DefaultStyleInformation { - public String contentTitle; - public Boolean htmlFormatContentTitle; - public String summaryText; - public Boolean htmlFormatSummaryText; - public Object largeIcon; - public BitmapSource largeIconBitmapSource; - public Object bigPicture; - public BitmapSource bigPictureBitmapSource; - public Boolean hideExpandedLargeIcon; - - public BigPictureStyleInformation( - Boolean htmlFormatTitle, - Boolean htmlFormatBody, - String contentTitle, - Boolean htmlFormatContentTitle, - String summaryText, - Boolean htmlFormatSummaryText, - Object largeIcon, - BitmapSource largeIconBitmapSource, - Object bigPicture, - BitmapSource bigPictureBitmapSource, - Boolean hideExpandedLargeIcon) { - super(htmlFormatTitle, htmlFormatBody); - this.contentTitle = contentTitle; - this.htmlFormatContentTitle = htmlFormatContentTitle; - this.summaryText = summaryText; - this.htmlFormatSummaryText = htmlFormatSummaryText; - this.largeIcon = largeIcon; - this.largeIconBitmapSource = largeIconBitmapSource; - this.bigPicture = bigPicture; - this.bigPictureBitmapSource = bigPictureBitmapSource; - this.hideExpandedLargeIcon = hideExpandedLargeIcon; - } -} diff --git a/flutter_local_notifications/android/src/main/java/com/dexterous/flutterlocalnotifications/models/styles/BigTextStyleInformation.java b/flutter_local_notifications/android/src/main/java/com/dexterous/flutterlocalnotifications/models/styles/BigTextStyleInformation.java deleted file mode 100644 index 63012c566..000000000 --- a/flutter_local_notifications/android/src/main/java/com/dexterous/flutterlocalnotifications/models/styles/BigTextStyleInformation.java +++ /dev/null @@ -1,31 +0,0 @@ -package com.dexterous.flutterlocalnotifications.models.styles; - -import androidx.annotation.Keep; - -@Keep -public class BigTextStyleInformation extends DefaultStyleInformation { - public String bigText; - public Boolean htmlFormatBigText; - public String contentTitle; - public Boolean htmlFormatContentTitle; - public String summaryText; - public Boolean htmlFormatSummaryText; - - public BigTextStyleInformation( - Boolean htmlFormatTitle, - Boolean htmlFormatBody, - String bigText, - Boolean htmlFormatBigText, - String contentTitle, - Boolean htmlFormatContentTitle, - String summaryText, - Boolean htmlFormatSummaryText) { - super(htmlFormatTitle, htmlFormatBody); - this.bigText = bigText; - this.htmlFormatBigText = htmlFormatBigText; - this.contentTitle = contentTitle; - this.htmlFormatContentTitle = htmlFormatContentTitle; - this.summaryText = summaryText; - this.htmlFormatSummaryText = htmlFormatSummaryText; - } -} diff --git a/flutter_local_notifications/android/src/main/java/com/dexterous/flutterlocalnotifications/models/styles/DefaultStyleInformation.java b/flutter_local_notifications/android/src/main/java/com/dexterous/flutterlocalnotifications/models/styles/DefaultStyleInformation.java deleted file mode 100644 index d9ea5fa15..000000000 --- a/flutter_local_notifications/android/src/main/java/com/dexterous/flutterlocalnotifications/models/styles/DefaultStyleInformation.java +++ /dev/null @@ -1,14 +0,0 @@ -package com.dexterous.flutterlocalnotifications.models.styles; - -import androidx.annotation.Keep; - -@Keep -public class DefaultStyleInformation extends StyleInformation { - public Boolean htmlFormatTitle; - public Boolean htmlFormatBody; - - public DefaultStyleInformation(Boolean htmlFormatTitle, Boolean htmlFormatBody) { - this.htmlFormatTitle = htmlFormatTitle; - this.htmlFormatBody = htmlFormatBody; - } -} diff --git a/flutter_local_notifications/android/src/main/java/com/dexterous/flutterlocalnotifications/models/styles/InboxStyleInformation.java b/flutter_local_notifications/android/src/main/java/com/dexterous/flutterlocalnotifications/models/styles/InboxStyleInformation.java deleted file mode 100644 index 5fd8dac9b..000000000 --- a/flutter_local_notifications/android/src/main/java/com/dexterous/flutterlocalnotifications/models/styles/InboxStyleInformation.java +++ /dev/null @@ -1,33 +0,0 @@ -package com.dexterous.flutterlocalnotifications.models.styles; - -import androidx.annotation.Keep; - -import java.util.ArrayList; - -@Keep -public class InboxStyleInformation extends DefaultStyleInformation { - public Boolean htmlFormatLines; - public ArrayList lines; - public String contentTitle; - public Boolean htmlFormatContentTitle; - public String summaryText; - public Boolean htmlFormatSummaryText; - - public InboxStyleInformation( - Boolean htmlFormatTitle, - Boolean htmlFormatBody, - String contentTitle, - Boolean htmlFormatContentTitle, - String summaryText, - Boolean htmlFormatSummaryText, - ArrayList lines, - Boolean htmlFormatLines) { - super(htmlFormatTitle, htmlFormatBody); - this.contentTitle = contentTitle; - this.htmlFormatContentTitle = htmlFormatContentTitle; - this.summaryText = summaryText; - this.htmlFormatSummaryText = htmlFormatSummaryText; - this.lines = lines; - this.htmlFormatLines = htmlFormatLines; - } -} diff --git a/flutter_local_notifications/android/src/main/java/com/dexterous/flutterlocalnotifications/models/styles/MessagingStyleInformation.java b/flutter_local_notifications/android/src/main/java/com/dexterous/flutterlocalnotifications/models/styles/MessagingStyleInformation.java deleted file mode 100644 index 3c6eeaeac..000000000 --- a/flutter_local_notifications/android/src/main/java/com/dexterous/flutterlocalnotifications/models/styles/MessagingStyleInformation.java +++ /dev/null @@ -1,30 +0,0 @@ -package com.dexterous.flutterlocalnotifications.models.styles; - -import androidx.annotation.Keep; - -import com.dexterous.flutterlocalnotifications.models.MessageDetails; -import com.dexterous.flutterlocalnotifications.models.PersonDetails; - -import java.util.ArrayList; - -@Keep -public class MessagingStyleInformation extends DefaultStyleInformation { - public PersonDetails person; - public String conversationTitle; - public Boolean groupConversation; - public ArrayList messages; - - public MessagingStyleInformation( - PersonDetails person, - String conversationTitle, - Boolean groupConversation, - ArrayList messages, - Boolean htmlFormatTitle, - Boolean htmlFormatBody) { - super(htmlFormatTitle, htmlFormatBody); - this.person = person; - this.conversationTitle = conversationTitle; - this.groupConversation = groupConversation; - this.messages = messages; - } -} diff --git a/flutter_local_notifications/android/src/main/java/com/dexterous/flutterlocalnotifications/models/styles/StyleInformation.java b/flutter_local_notifications/android/src/main/java/com/dexterous/flutterlocalnotifications/models/styles/StyleInformation.java deleted file mode 100644 index 592b30742..000000000 --- a/flutter_local_notifications/android/src/main/java/com/dexterous/flutterlocalnotifications/models/styles/StyleInformation.java +++ /dev/null @@ -1,8 +0,0 @@ -package com.dexterous.flutterlocalnotifications.models.styles; - -import androidx.annotation.Keep; - -import java.io.Serializable; - -@Keep -public abstract class StyleInformation implements Serializable {}