Forum Xamarin Xamarin.Android

Using information off local database to display notification information

joonjangjoonjang Member ✭✭
edited April 17 in Xamarin.Android
Hello I have a repeating notification. I would like the information displayed on the notification to be of a new element off of my local database every time it is called.

For example I would have a table in my database with 5 elements containing a unique string of titles and messages per index. Every time the notification is called a new index of the database is called to bring forward a new element.

First notification: First element from database

Second notification: second element from database
And so on

How do I trigger a cross platform method that goes through my database everytime an android notification is called? How do I keep track of what the next notification will be in the background?

Best Answer

  • joonjangjoonjang Member ✭✭
    Accepted Answer

    Oh wow sorry about the repeat post. My Ublock chrome plug in gave me an issue with this forum. I found the solution was to serialize the information.

    So what i did was have my SQL logic happen in the OnReceive and then repackage the next index commend in the respective function, then serialize it, then call the next notification

    [assembly: Xamarin.Forms.Dependency(typeof(DebugNoti))]
    namespace LawsForImpact.Droid
    {
        class DebugNoti : IDebugNotiServ
        {
            int _notificationIconId { get; set; }
    
            internal string _randomNumber;
    
            public void LocalNotification(string title, string body, int id, DateTime notifyTime)
            {
    
                var intent = CreateIntent(id);
                var localNotification = new LocalNotification();
                localNotification.Title = title;
                localNotification.Body = body;
                localNotification.Id = id;
                localNotification.NotifyTime = notifyTime;
    
                if (_notificationIconId != 0)
                {
                    localNotification.IconId = _notificationIconId;
                }
                else
                {
                    localNotification.IconId = Resource.Drawable.notification_template_icon_bg;
                }
    
                var serializedNotification = SerializeNotification(localNotification);
                intent.PutExtra(DebugScheduledAlarmHandler.LocalNotificationKey, serializedNotification);
    
                Random generator = new Random();
                _randomNumber = generator.Next(100000, 999999).ToString("D6");
    
                var pendingIntent = PendingIntent.GetBroadcast(Application.Context, Convert.ToInt32(_randomNumber), intent, PendingIntentFlags.Immutable);
                var alarmManager = GetAlarmManager();
                // todo change variable of alarm manager
                //totalMilliSeconds, repeateForMinute
                alarmManager.SetExactAndAllowWhileIdle(AlarmType.RtcWakeup, 3000, pendingIntent);
            }
    
            public void Cancel(int id)
            {
    
                var intent = CreateIntent(id);
                var pendingIntent = PendingIntent.GetBroadcast(Application.Context, Convert.ToInt32(_randomNumber), intent, PendingIntentFlags.Immutable);
                var alarmManager = GetAlarmManager();
                alarmManager.Cancel(pendingIntent);
                var notificationManager = NotificationManagerCompat.From(Application.Context);
                notificationManager.CancelAll();
                notificationManager.Cancel(id);
            }
    
            public static Intent GetLauncherActivity()
            {
    
                var packageName = Application.Context.PackageName;
                return Application.Context.PackageManager.GetLaunchIntentForPackage(packageName);
            }
    
    
            private Intent CreateIntent(int id)
            {
    
                return new Intent(Application.Context, typeof(DebugScheduledAlarmHandler))
                    .SetAction("LocalNotifierIntent" + id);
            }
    
            private AlarmManager GetAlarmManager()
            {
    
                var alarmManager = Application.Context.GetSystemService(Context.AlarmService) as AlarmManager;
                return alarmManager;
            }
    
            private string SerializeNotification(LocalNotification notification)
            {
    
                var xmlSerializer = new XmlSerializer(notification.GetType());
    
                using (var stringWriter = new StringWriter())
                {
                    xmlSerializer.Serialize(stringWriter, notification);
                    return stringWriter.ToString();
                }
            }
        }
    
        [BroadcastReceiver(Enabled = true, Label = "Debug Noti")]
        public class DebugScheduledAlarmHandler : BroadcastReceiver
        {
    
            public const string LocalNotificationKey = "LocalNotification";
            const string channelId = "default";
            const string channelName = "Default";
            const string channelDescription = "The default channel for notifications.";
            const int pendingIntentId = 0;
    
            public const string TitleKey = "title";
            public const string MessageKey = "message";
    
            bool channelInitialized = false;
            NotificationManager manager;
            NotificationCompat.BigTextStyle textStyle = new NotificationCompat.BigTextStyle();
            Dictionary<string,int> nQueue = Global.notifQueue;
    
    
            private SQLiteConnection _sqLiteConnection ;
    
    
    
            public override async void OnReceive(Context context, Intent intent)
            {
                _sqLiteConnection = await Xamarin.Forms.DependencyService.Get<ISQLite>().GetConnection();
                var listDataPower = _sqLiteConnection.Table<Power>().ToList();
    
                if (!channelInitialized)
                {
                    CreateNotificationChannel();
                }
    
                intent.SetFlags(ActivityFlags.SingleTop);
                intent.PutExtra("OpenPage", "SomePage");
    
    
                var extra = intent.GetStringExtra(LocalNotificationKey);
                var notification = DeserializeNotification(extra);
    
                int notiID = notification.Id;
    
    
                PendingIntent pendingIntent = PendingIntent.GetActivity(AndroidApp.Context, pendingIntentId, intent, PendingIntentFlags.OneShot);
    
                NotificationCompat.Builder builder = new NotificationCompat.Builder(AndroidApp.Context, channelId)
                    .SetContentIntent(pendingIntent)
                    .SetContentTitle(listDataPower[notiID].Title)
                    .SetContentText(listDataPower[notiID].Description)
                    .SetLargeIcon(BitmapFactory.DecodeResource(AndroidApp.Context.Resources, Resource.Drawable.notify_panel_notification_icon_bg))
                    .SetSmallIcon(Resource.Drawable.notify_panel_notification_icon_bg)
                    .SetDefaults((int)NotificationDefaults.Sound | (int)NotificationDefaults.Vibrate)
                    .SetStyle(textStyle);
    
                var resultIntent = DebugNoti.GetLauncherActivity();
                resultIntent.SetFlags(ActivityFlags.NewTask | ActivityFlags.ClearTask);
                var stackBuilder = Android.Support.V4.App.TaskStackBuilder.Create(Application.Context);
                stackBuilder.AddNextIntent(resultIntent);
    
                Random random = new Random();
                int randomNumber = random.Next(9999 - 1000) + 1000;
    
                var resultPendingIntent =
                    stackBuilder.GetPendingIntent(randomNumber, (int)PendingIntentFlags.Immutable);
                builder.SetContentIntent(resultPendingIntent);
                // Sending notification    
                var notificationManager = NotificationManagerCompat.From(Application.Context);
                notificationManager.Notify(randomNumber, builder.Build());
    
                notiID++;
    
                Xamarin.Forms.DependencyService.Get<IDebugNotiServ>().LocalNotification(listDataPower[notiID].Title, listDataPower[notiID].Description, notiID, DateTime.Now);
            }
    
            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;
                }
            }
    
            void CreateNotificationChannel()
            {
                manager = (NotificationManager)AndroidApp.Context.GetSystemService(AndroidApp.NotificationService);
    
                if (Build.VERSION.SdkInt >= BuildVersionCodes.O)
                {
                    var channelNameJava = new Java.Lang.String(channelName);
                    var channel = new NotificationChannel(channelId, channelNameJava, NotificationImportance.Default)
                    {
                        Description = channelDescription
                    };
                    manager.CreateNotificationChannel(channel);
                }
    
                channelInitialized = true;
            }
        }
    }
    
    

Answers

  • joonjangjoonjang Member ✭✭

    Here is my android notification code:

    //used: https://blog.nishanil.com/2014/12/16/scheduled-notifications-in-android-using-alarm-manager/
    // new notifications service
    public class AndroidReminderService : IReminderService
    {
        public void Remind(DateTime dateTime, string title, string message)
        {
            // create alarm intent
            Intent alarmIntent = new Intent(Application.Context, typeof(AlarmReceiver));
            alarmIntent.PutExtra("message", message);
            alarmIntent.PutExtra("title", title);
    
            // specify the broadcast receiver
            PendingIntent pendingIntent = PendingIntent.GetBroadcast(Application.Context, 0, alarmIntent, PendingIntentFlags.UpdateCurrent);
            AlarmManager alarmManager = (AlarmManager)Application.Context.GetSystemService(Context.AlarmService);
    
            // set the time when app is woken up
            // todo: this is where time is adjusted
            alarmManager.SetInexactRepeating(AlarmType.ElapsedRealtimeWakeup, SystemClock.ElapsedRealtime() + 5* 1000, 1000, pendingIntent);}
    

    [BroadcastReceiver]
    public class AlarmReceiver : BroadcastReceiver
    {
    const string channelId = "default";
    public override void OnReceive(Context context, Intent intent)
    {
    var message = intent.GetStringExtra("message");
    var title = intent.GetStringExtra("title");

            var notIntent = new Intent(context, typeof(MainActivity));
            var contentIntent = PendingIntent.GetActivity(context, 0, notIntent, PendingIntentFlags.CancelCurrent);
            var manager = NotificationManagerCompat.From(context);
    
            var style = new NotificationCompat.BigTextStyle();
            style.BigText(message);
    
            // sets notifcation logo
            int resourceId;
            resourceId = Resource.Drawable.xamarin_logo;
    
            var wearableExtender = new NotificationCompat.WearableExtender().SetBackground(BitmapFactory.DecodeResource(context.Resources, resourceId));
    
            // Generate a notification
            // todo look at notification compat properties
            var builder = new NotificationCompat.Builder(context, channelId)
                .SetContentIntent(contentIntent)
                .SetSmallIcon(Resource.Drawable.notification_template_icon_bg)
                .SetContentTitle(title)
                .SetContentText(message)
                .SetStyle(style)
                .SetWhen(Java.Lang.JavaSystem.CurrentTimeMillis())
                .SetAutoCancel(true)
                .Extend(wearableExtender);
    
            var notification = builder.Build();
            manager.Notify(0, notification);
        }
    }
    
  • LandLuLandLu Member, Xamarin Team Xamurai

    I think you could use NotificationListenerService to detect the incoming of notification.
    Here are the specific steps to implement it in Xamarin:
    https://forums.xamarin.com/discussion/166297/how-to-check-for-incoming-notifications-in-xamarin-android

  • joonjangjoonjang Member ✭✭

    Here is my android notification code:

    //used: https://blog.nishanil.com/2014/12/16/scheduled-notifications-in-android-using-alarm-manager/
    // new notifications service
    public class AndroidReminderService : IReminderService
    {
        public void Remind(DateTime dateTime, string title, string message)
        {
            // create alarm intent
            Intent alarmIntent = new Intent(Application.Context, typeof(AlarmReceiver));
            alarmIntent.PutExtra("message", message);
            alarmIntent.PutExtra("title", title);
    
            // specify the broadcast receiver
            PendingIntent pendingIntent = PendingIntent.GetBroadcast(Application.Context, 0, alarmIntent, PendingIntentFlags.UpdateCurrent);
            AlarmManager alarmManager = (AlarmManager)Application.Context.GetSystemService(Context.AlarmService);
    
            // set the time when app is woken up
            // todo: this is where time is adjusted
            alarmManager.SetInexactRepeating(AlarmType.ElapsedRealtimeWakeup, SystemClock.ElapsedRealtime() + 5* 1000, 1000, pendingIntent);
    

    }
    }

    [BroadcastReceiver]
    public class AlarmReceiver : BroadcastReceiver
    {
    const string channelId = "default";
    public override void OnReceive(Context context, Intent intent)
    {
    var message = intent.GetStringExtra("message");
    var title = intent.GetStringExtra("title");

            var notIntent = new Intent(context, typeof(MainActivity));
            var contentIntent = PendingIntent.GetActivity(context, 0, notIntent, PendingIntentFlags.CancelCurrent);
            var manager = NotificationManagerCompat.From(context);
    
            var style = new NotificationCompat.BigTextStyle();
            style.BigText(message);
    
            // sets notifcation logo
            int resourceId;
            resourceId = Resource.Drawable.xamarin_logo;
    
            var wearableExtender = new NotificationCompat.WearableExtender().SetBackground(BitmapFactory.DecodeResource(context.Resources, resourceId));
    
            // Generate a notification
            // todo look at notification compat properties
            var builder = new NotificationCompat.Builder(context, channelId)
                .SetContentIntent(contentIntent)
                .SetSmallIcon(Resource.Drawable.notification_template_icon_bg)
                .SetContentTitle(title)
                .SetContentText(message)
                .SetStyle(style)
                .SetWhen(Java.Lang.JavaSystem.CurrentTimeMillis())
                .SetAutoCancel(true)
                .Extend(wearableExtender);
    
            var notification = builder.Build();
            manager.Notify(0, notification);
        }
    }
    
  • joonjangjoonjang Member ✭✭

    Here is my android notification code:

    //used: https://blog.nishanil.com/2014/12/16/scheduled-notifications-in-android-using-alarm-manager/
    // new notifications service
    public class AndroidReminderService : IReminderService
    {
        public void Remind(DateTime dateTime, string title, string message)
        {
            // create alarm intent
            Intent alarmIntent = new Intent(Application.Context, typeof(AlarmReceiver));
            alarmIntent.PutExtra("message", message);
            alarmIntent.PutExtra("title", title);
    
            // specify the broadcast receiver
            PendingIntent pendingIntent = PendingIntent.GetBroadcast(Application.Context, 0, alarmIntent, PendingIntentFlags.UpdateCurrent);
            AlarmManager alarmManager = (AlarmManager)Application.Context.GetSystemService(Context.AlarmService);
    
            // set the time when app is woken up
            // todo: this is where time is adjusted
            alarmManager.SetInexactRepeating(AlarmType.ElapsedRealtimeWakeup, SystemClock.ElapsedRealtime() + 5* 1000, 1000, pendingIntent);
    

    }
    }

    [BroadcastReceiver]
    public class AlarmReceiver : BroadcastReceiver
    {
    const string channelId = "default";
    public override void OnReceive(Context context, Intent intent)
    {
    var message = intent.GetStringExtra("message");
    var title = intent.GetStringExtra("title");

            var notIntent = new Intent(context, typeof(MainActivity));
            var contentIntent = PendingIntent.GetActivity(context, 0, notIntent, PendingIntentFlags.CancelCurrent);
            var manager = NotificationManagerCompat.From(context);
    
            var style = new NotificationCompat.BigTextStyle();
            style.BigText(message);
    
            // sets notifcation logo
            int resourceId;
            resourceId = Resource.Drawable.xamarin_logo;
    
            var wearableExtender = new NotificationCompat.WearableExtender().SetBackground(BitmapFactory.DecodeResource(context.Resources, resourceId));
    
            // Generate a notification
            // todo look at notification compat properties
            var builder = new NotificationCompat.Builder(context, channelId)
                .SetContentIntent(contentIntent)
                .SetSmallIcon(Resource.Drawable.notification_template_icon_bg)
                .SetContentTitle(title)
                .SetContentText(message)
                .SetStyle(style)
                .SetWhen(Java.Lang.JavaSystem.CurrentTimeMillis())
                .SetAutoCancel(true)
                .Extend(wearableExtender);
    
            var notification = builder.Build();
            manager.Notify(0, notification);
        }
    }
    
  • LandLuLandLu Member, Xamarin Team Xamurai

    This code tells how to use an alarm to send several notifications.
    Have you tried the code from the link I posted to track the notifications?

  • joonjangjoonjang Member ✭✭
    Accepted Answer

    Oh wow sorry about the repeat post. My Ublock chrome plug in gave me an issue with this forum. I found the solution was to serialize the information.

    So what i did was have my SQL logic happen in the OnReceive and then repackage the next index commend in the respective function, then serialize it, then call the next notification

    [assembly: Xamarin.Forms.Dependency(typeof(DebugNoti))]
    namespace LawsForImpact.Droid
    {
        class DebugNoti : IDebugNotiServ
        {
            int _notificationIconId { get; set; }
    
            internal string _randomNumber;
    
            public void LocalNotification(string title, string body, int id, DateTime notifyTime)
            {
    
                var intent = CreateIntent(id);
                var localNotification = new LocalNotification();
                localNotification.Title = title;
                localNotification.Body = body;
                localNotification.Id = id;
                localNotification.NotifyTime = notifyTime;
    
                if (_notificationIconId != 0)
                {
                    localNotification.IconId = _notificationIconId;
                }
                else
                {
                    localNotification.IconId = Resource.Drawable.notification_template_icon_bg;
                }
    
                var serializedNotification = SerializeNotification(localNotification);
                intent.PutExtra(DebugScheduledAlarmHandler.LocalNotificationKey, serializedNotification);
    
                Random generator = new Random();
                _randomNumber = generator.Next(100000, 999999).ToString("D6");
    
                var pendingIntent = PendingIntent.GetBroadcast(Application.Context, Convert.ToInt32(_randomNumber), intent, PendingIntentFlags.Immutable);
                var alarmManager = GetAlarmManager();
                // todo change variable of alarm manager
                //totalMilliSeconds, repeateForMinute
                alarmManager.SetExactAndAllowWhileIdle(AlarmType.RtcWakeup, 3000, pendingIntent);
            }
    
            public void Cancel(int id)
            {
    
                var intent = CreateIntent(id);
                var pendingIntent = PendingIntent.GetBroadcast(Application.Context, Convert.ToInt32(_randomNumber), intent, PendingIntentFlags.Immutable);
                var alarmManager = GetAlarmManager();
                alarmManager.Cancel(pendingIntent);
                var notificationManager = NotificationManagerCompat.From(Application.Context);
                notificationManager.CancelAll();
                notificationManager.Cancel(id);
            }
    
            public static Intent GetLauncherActivity()
            {
    
                var packageName = Application.Context.PackageName;
                return Application.Context.PackageManager.GetLaunchIntentForPackage(packageName);
            }
    
    
            private Intent CreateIntent(int id)
            {
    
                return new Intent(Application.Context, typeof(DebugScheduledAlarmHandler))
                    .SetAction("LocalNotifierIntent" + id);
            }
    
            private AlarmManager GetAlarmManager()
            {
    
                var alarmManager = Application.Context.GetSystemService(Context.AlarmService) as AlarmManager;
                return alarmManager;
            }
    
            private string SerializeNotification(LocalNotification notification)
            {
    
                var xmlSerializer = new XmlSerializer(notification.GetType());
    
                using (var stringWriter = new StringWriter())
                {
                    xmlSerializer.Serialize(stringWriter, notification);
                    return stringWriter.ToString();
                }
            }
        }
    
        [BroadcastReceiver(Enabled = true, Label = "Debug Noti")]
        public class DebugScheduledAlarmHandler : BroadcastReceiver
        {
    
            public const string LocalNotificationKey = "LocalNotification";
            const string channelId = "default";
            const string channelName = "Default";
            const string channelDescription = "The default channel for notifications.";
            const int pendingIntentId = 0;
    
            public const string TitleKey = "title";
            public const string MessageKey = "message";
    
            bool channelInitialized = false;
            NotificationManager manager;
            NotificationCompat.BigTextStyle textStyle = new NotificationCompat.BigTextStyle();
            Dictionary<string,int> nQueue = Global.notifQueue;
    
    
            private SQLiteConnection _sqLiteConnection ;
    
    
    
            public override async void OnReceive(Context context, Intent intent)
            {
                _sqLiteConnection = await Xamarin.Forms.DependencyService.Get<ISQLite>().GetConnection();
                var listDataPower = _sqLiteConnection.Table<Power>().ToList();
    
                if (!channelInitialized)
                {
                    CreateNotificationChannel();
                }
    
                intent.SetFlags(ActivityFlags.SingleTop);
                intent.PutExtra("OpenPage", "SomePage");
    
    
                var extra = intent.GetStringExtra(LocalNotificationKey);
                var notification = DeserializeNotification(extra);
    
                int notiID = notification.Id;
    
    
                PendingIntent pendingIntent = PendingIntent.GetActivity(AndroidApp.Context, pendingIntentId, intent, PendingIntentFlags.OneShot);
    
                NotificationCompat.Builder builder = new NotificationCompat.Builder(AndroidApp.Context, channelId)
                    .SetContentIntent(pendingIntent)
                    .SetContentTitle(listDataPower[notiID].Title)
                    .SetContentText(listDataPower[notiID].Description)
                    .SetLargeIcon(BitmapFactory.DecodeResource(AndroidApp.Context.Resources, Resource.Drawable.notify_panel_notification_icon_bg))
                    .SetSmallIcon(Resource.Drawable.notify_panel_notification_icon_bg)
                    .SetDefaults((int)NotificationDefaults.Sound | (int)NotificationDefaults.Vibrate)
                    .SetStyle(textStyle);
    
                var resultIntent = DebugNoti.GetLauncherActivity();
                resultIntent.SetFlags(ActivityFlags.NewTask | ActivityFlags.ClearTask);
                var stackBuilder = Android.Support.V4.App.TaskStackBuilder.Create(Application.Context);
                stackBuilder.AddNextIntent(resultIntent);
    
                Random random = new Random();
                int randomNumber = random.Next(9999 - 1000) + 1000;
    
                var resultPendingIntent =
                    stackBuilder.GetPendingIntent(randomNumber, (int)PendingIntentFlags.Immutable);
                builder.SetContentIntent(resultPendingIntent);
                // Sending notification    
                var notificationManager = NotificationManagerCompat.From(Application.Context);
                notificationManager.Notify(randomNumber, builder.Build());
    
                notiID++;
    
                Xamarin.Forms.DependencyService.Get<IDebugNotiServ>().LocalNotification(listDataPower[notiID].Title, listDataPower[notiID].Description, notiID, DateTime.Now);
            }
    
            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;
                }
            }
    
            void CreateNotificationChannel()
            {
                manager = (NotificationManager)AndroidApp.Context.GetSystemService(AndroidApp.NotificationService);
    
                if (Build.VERSION.SdkInt >= BuildVersionCodes.O)
                {
                    var channelNameJava = new Java.Lang.String(channelName);
                    var channel = new NotificationChannel(channelId, channelNameJava, NotificationImportance.Default)
                    {
                        Description = channelDescription
                    };
                    manager.CreateNotificationChannel(channel);
                }
    
                channelInitialized = true;
            }
        }
    }
    
    
Sign In or Register to comment.