Reputation: 31
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 3 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.
SQL Data:
Table: Table Name
Element 1: String 1, String One
Element 2: String 2, String Two
Element 3: String 3, String Three
Android notification out:
First notification: Title: 1, Message: One
Second notification: Title: 2, Message: Two
Third notification: Title: 3, Message: Three
How do I trigger a Xamarin cross-platform method that goes through my database for the next element every time an android notification is called? How do I keep track of what the next notification will be in the background?
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);
}
}
Upvotes: 0
Views: 64
Reputation: 31
The trick seemed to be serialize the information.
My OnReceive does the SQL logic and then calls a function to serialize it all then i call the next remind
[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;
}
}
}
Upvotes: 1