diff --git a/src/Plugin.LocalNotifications.Abstractions/ILocalNotifications.cs b/src/Plugin.LocalNotifications.Abstractions/ILocalNotifications.cs new file mode 100644 index 0000000..e8f283c --- /dev/null +++ b/src/Plugin.LocalNotifications.Abstractions/ILocalNotifications.cs @@ -0,0 +1,33 @@ +using System; + +namespace Plugin.LocalNotifications.Abstractions +{ + /// + /// Local Notification Interface + /// + public interface ILocalNotifications + { + /// + /// Show a local notification + /// + /// Title of the notification + /// Body or description of the notification + /// Id of the notification + void Show(string title, string body, int id = 0); + + /// + /// Show a local notification at a specified time + /// + /// Title of the notification + /// Body or description of the notification + /// Id of the notification + /// Time to show notification + void Show(string title, string body, int id, DateTime notifyTime); + + /// + /// Cancel a local notification + /// + /// Id of the notification to cancel + void Cancel(int id); + } +} diff --git a/src/Plugin.LocalNotifications.Abstractions/Plugin.LocalNotifications.Abstractions.csproj b/src/Plugin.LocalNotifications.Abstractions/Plugin.LocalNotifications.Abstractions.csproj index c8ecf48..0a063a5 100644 --- a/src/Plugin.LocalNotifications.Abstractions/Plugin.LocalNotifications.Abstractions.csproj +++ b/src/Plugin.LocalNotifications.Abstractions/Plugin.LocalNotifications.Abstractions.csproj @@ -38,7 +38,7 @@ - + diff --git a/src/Plugin.LocalNotifications.Android/LocalNotificationsImplementation.cs b/src/Plugin.LocalNotifications.Android/LocalNotificationsImplementation.cs index fd7ba26..26c8a98 100644 --- a/src/Plugin.LocalNotifications.Android/LocalNotificationsImplementation.cs +++ b/src/Plugin.LocalNotifications.Android/LocalNotificationsImplementation.cs @@ -1,10 +1,10 @@ +using System; +using System.IO; +using System.Xml.Serialization; using Android.App; using Android.Content; using Android.Support.V4.App; using Plugin.LocalNotifications.Abstractions; -using System; -using System.IO; -using System.Xml.Serialization; namespace Plugin.LocalNotifications { @@ -18,6 +18,19 @@ public class LocalNotificationsImplementation : ILocalNotifications /// public static int NotificationIconId { get; set; } + /// + /// Gets or sets the optional local notification intent action. + /// + /// The local notification intent action. + public static string LocalNotificationIntentAction { get; set; } + + internal const string LocalNotificationKey = "LocalNotification"; + + /// + /// The key of the bundle element that contains notification's id. + /// + public const string LocalNotificationIntentKey = "NotificationId"; + /// /// Show a local notification /// @@ -40,24 +53,26 @@ public void Show(string title, string body, int id = 0) builder.SetSmallIcon(Resource.Drawable.plugin_lc_smallicon); } - var resultIntent = GetLauncherActivity(); - resultIntent.SetFlags(ActivityFlags.NewTask | ActivityFlags.ClearTask); - var stackBuilder = Android.Support.V4.App.TaskStackBuilder.Create(Application.Context); - stackBuilder.AddNextIntent(resultIntent); - var resultPendingIntent = - stackBuilder.GetPendingIntent(0, (int)PendingIntentFlags.UpdateCurrent); + var resultIntent = string.IsNullOrEmpty(LocalNotificationIntentAction) ? + GetLauncherActivity() + : + new Intent(LocalNotificationIntentAction).AddFlags(ActivityFlags.NewTask); + + resultIntent.PutExtra(LocalNotificationIntentKey, id); + + var resultPendingIntent = PendingIntent.GetActivity(Application.Context, 0, resultIntent, PendingIntentFlags.UpdateCurrent); builder.SetContentIntent(resultPendingIntent); var notificationManager = NotificationManagerCompat.From(Application.Context); + notificationManager.Notify(id, builder.Build()); } - public static Intent GetLauncherActivity() { - var packageName = Application.Context.PackageName; - return Application.Context.PackageManager.GetLaunchIntentForPackage(packageName); + return Application.Context.PackageManager.GetLaunchIntentForPackage(Application.Context.PackageName); } + /// /// Show a local notification at a specified time /// @@ -74,6 +89,7 @@ public void Show(string title, string body, int id, DateTime notifyTime) localNotification.Body = body; localNotification.Id = id; localNotification.NotifyTime = notifyTime; + if (NotificationIconId != 0) { localNotification.IconId = NotificationIconId; @@ -84,7 +100,7 @@ public void Show(string title, string body, int id, DateTime notifyTime) } var serializedNotification = SerializeNotification(localNotification); - intent.PutExtra(ScheduledAlarmHandler.LocalNotificationKey, serializedNotification); + intent.PutExtra(LocalNotificationKey, serializedNotification); var pendingIntent = PendingIntent.GetBroadcast(Application.Context, 0, intent, PendingIntentFlags.CancelCurrent); var triggerTime = NotifyTimeInMilliseconds(localNotification.NotifyTime); @@ -111,15 +127,12 @@ public void Cancel(int id) private Intent CreateIntent(int id) { - return new Intent(Application.Context, typeof(ScheduledAlarmHandler)) - .SetAction("LocalNotifierIntent" + id); + return new Intent(Application.Context, typeof(ScheduledAlarmHandler)).SetAction("LocalNotifierIntent" + id); } - private AlarmManager GetAlarmManager() { - var alarmManager = Application.Context.GetSystemService(Context.AlarmService) as AlarmManager; - return alarmManager; + return Application.Context.GetSystemService(Context.AlarmService) as AlarmManager; } private string SerializeNotification(LocalNotification notification) @@ -128,6 +141,7 @@ private string SerializeNotification(LocalNotification notification) using (var stringWriter = new StringWriter()) { xmlSerializer.Serialize(stringWriter, notification); + return stringWriter.ToString(); } } @@ -137,8 +151,7 @@ private long NotifyTimeInMilliseconds(DateTime notifyTime) var utcTime = TimeZoneInfo.ConvertTimeToUtc(notifyTime); var epochDifference = (new DateTime(1970, 1, 1) - DateTime.MinValue).TotalSeconds; - var utcAlarmTimeInMillis = utcTime.AddSeconds(-epochDifference).Ticks / 10000; - return utcAlarmTimeInMillis; + return utcTime.AddSeconds(-epochDifference).Ticks / 10000; } } } \ No newline at end of file diff --git a/src/Plugin.LocalNotifications.Android/Plugin.LocalNotifications.Android.csproj b/src/Plugin.LocalNotifications.Android/Plugin.LocalNotifications.Android.csproj index 2afb2e0..df427be 100644 --- a/src/Plugin.LocalNotifications.Android/Plugin.LocalNotifications.Android.csproj +++ b/src/Plugin.LocalNotifications.Android/Plugin.LocalNotifications.Android.csproj @@ -16,6 +16,7 @@ Off False v4.4 + true @@ -42,9 +43,8 @@ - - ..\packages\Xamarin.Android.Support.v4.23.0.1.3\lib\MonoAndroid403\Xamarin.Android.Support.v4.dll - True + + ..\..\..\packages\Xamarin.Android.Support.v4.23.3.0\lib\MonoAndroid403\Xamarin.Android.Support.v4.dll @@ -58,12 +58,12 @@ - + - {2906ba0a-cd3e-4ab3-9e8c-7b4da836fa1f} + {57564CE6-C079-47C5-9272-4395A0224C3D} Plugin.LocalNotifications.Abstractions diff --git a/src/Plugin.LocalNotifications.Android/ScheduledAlarmHandler.cs b/src/Plugin.LocalNotifications.Android/ScheduledAlarmHandler.cs index 10d9b89..99a9130 100644 --- a/src/Plugin.LocalNotifications.Android/ScheduledAlarmHandler.cs +++ b/src/Plugin.LocalNotifications.Android/ScheduledAlarmHandler.cs @@ -12,11 +12,6 @@ namespace Plugin.LocalNotifications [BroadcastReceiver(Enabled = true, Label = "Local Notifications Plugin Broadcast Receiver")] public class ScheduledAlarmHandler : BroadcastReceiver { - /// - /// - /// - public const string LocalNotificationKey = "LocalNotification"; - /// /// /// @@ -24,7 +19,7 @@ public class ScheduledAlarmHandler : BroadcastReceiver /// public override void OnReceive(Context context, Intent intent) { - var extra = intent.GetStringExtra(LocalNotificationKey); + var extra = intent.GetStringExtra(LocalNotificationsImplementation.LocalNotificationKey); var notification = DeserializeNotification(extra); var builder = new NotificationCompat.Builder(Application.Context) @@ -33,25 +28,28 @@ public override void OnReceive(Context context, Intent intent) .SetSmallIcon(notification.IconId) .SetAutoCancel(true); - var resultIntent = LocalNotificationsImplementation.GetLauncherActivity(); - resultIntent.SetFlags(ActivityFlags.NewTask | ActivityFlags.ClearTask); - var stackBuilder = Android.Support.V4.App.TaskStackBuilder.Create(Application.Context); - stackBuilder.AddNextIntent(resultIntent); - var resultPendingIntent = - stackBuilder.GetPendingIntent(0, (int)PendingIntentFlags.UpdateCurrent); + var resultIntent = string.IsNullOrEmpty(LocalNotificationsImplementation.LocalNotificationIntentAction) ? + LocalNotificationsImplementation.GetLauncherActivity() + : + new Intent(LocalNotificationsImplementation.LocalNotificationIntentAction).AddFlags(ActivityFlags.NewTask); + + resultIntent.PutExtra(LocalNotificationsImplementation.LocalNotificationIntentKey, notification.Id); + + var resultPendingIntent = PendingIntent.GetActivity(Application.Context, 0, resultIntent, 0); builder.SetContentIntent(resultPendingIntent); var notificationManager = NotificationManagerCompat.From(Application.Context); + notificationManager.Notify(notification.Id, builder.Build()); } private LocalNotification DeserializeNotification(string notificationString) { var xmlSerializer = new XmlSerializer(typeof(LocalNotification)); + using (var stringReader = new StringReader(notificationString)) { - var notification = (LocalNotification)xmlSerializer.Deserialize(stringReader); - return notification; + return (LocalNotification)xmlSerializer.Deserialize(stringReader); } } } diff --git a/src/Plugin.LocalNotifications.Android/packages.config b/src/Plugin.LocalNotifications.Android/packages.config index 6bca63c..e5587cb 100644 --- a/src/Plugin.LocalNotifications.Android/packages.config +++ b/src/Plugin.LocalNotifications.Android/packages.config @@ -1,4 +1,4 @@  - + \ No newline at end of file diff --git a/src/Plugin.LocalNotifications.iOS/LocalNotificationsImplementation.cs b/src/Plugin.LocalNotifications.iOS/LocalNotificationsImplementation.cs index a4e60d0..c694a0f 100644 --- a/src/Plugin.LocalNotifications.iOS/LocalNotificationsImplementation.cs +++ b/src/Plugin.LocalNotifications.iOS/LocalNotificationsImplementation.cs @@ -1,7 +1,7 @@ using System; -using Plugin.LocalNotifications.Abstractions; using System.Linq; using Foundation; +using Plugin.LocalNotifications.Abstractions; using UIKit; using UserNotifications; @@ -25,6 +25,7 @@ public void Show(string title, string body, int id = 0) if (UIDevice.CurrentDevice.CheckSystemVersion(10, 0)) { var trigger = UNTimeIntervalNotificationTrigger.CreateTrigger(.1, false); + ShowUserNotification(title, body, id, trigger); } else @@ -45,6 +46,7 @@ public void Show(string title, string body, int id, DateTime notifyTime) if (UIDevice.CurrentDevice.CheckSystemVersion(10, 0)) { var trigger = UNCalendarNotificationTrigger.CreateTrigger(GetNSDateComponentsFromDateTime(notifyTime), false); + ShowUserNotification(title, body, id, trigger); } else @@ -75,8 +77,7 @@ public void Cancel(int id) else { var notifications = UIApplication.SharedApplication.ScheduledLocalNotifications; - var notification = notifications.Where(n => n.UserInfo.ContainsKey(NSObject.FromObject(NotificationKey))) - .FirstOrDefault(n => n.UserInfo[NotificationKey].Equals(NSObject.FromObject(id))); + var notification = notifications.Where(n => n.UserInfo.ContainsKey(NSObject.FromObject(NotificationKey))).FirstOrDefault(n => n.UserInfo[NotificationKey].Equals(NSObject.FromObject(id))); if (notification != null) { @@ -96,9 +97,10 @@ void ShowUserNotification(string title, string body, int id, UNNotificationTrigg var content = new UNMutableNotificationContent() { Title = title, - Body = body + Body = body, + UserInfo = NSDictionary.FromObjectAndKey(NSObject.FromObject(id), NSObject.FromObject(NotificationKey)) }; - + var request = UNNotificationRequest.FromIdentifier(id.ToString(), content, trigger); UNUserNotificationCenter.Current.AddNotificationRequest(request, (error) => { }); @@ -117,4 +119,4 @@ NSDateComponents GetNSDateComponentsFromDateTime(DateTime dateTime) }; } } -} +} \ No newline at end of file