在特定时间创建通知

时间:2018-12-10 11:15:55

标签: c# android xamarin.android notifications android-notifications

我有一个正在使用的日历应用程序,我需要提醒用户即将发生的事件。

所以我想知道这样做的最佳实践是什么,应该怎么做,因为我目前使用的解决方案甚至还不能很好地工作。

我现在的操作方式是使用AlarmManager触发一个BroadcasReciever,它创建并显示通知。

我需要使用服务吗?如果是这样,我应该怎么做?

代码:

    private void StartDBUpdateAlarm() // Start the alarm manager for event reminder 
    {
        // Get the eventos orded by date (Later than DateTime.Now),
        // so that we can get the earliest events
        var eventos = eventDao.Select(FromEventos.OrderByDate, DateTime.Now);

        if ((eventos.Count > 0)) // Only create notification if there is an event
        {
            // Create the Intent to pass some info through it to the notification
            Intent alarmIntent = new Intent(this, typeof(ReminderReciever));

            // Putting the information that will be passed with constant Id's  
            alarmIntent.PutExtra(GerirUtils.INTENT_TITLE, GetString(Resource.String.main_notification_title));
            alarmIntent.PutExtra(GerirUtils.INTENT_INFO, "Info");
            alarmIntent.PutExtra(GerirUtils.INTENT_CONTENT, eventos[0].Descricao);

            // Creating/Recreating the Pending Intent that will pass the actual information to the notification
            PendingIntent pendingIntent = PendingIntent.GetBroadcast(this, GerirUtils.NOTIFICATION_REMINDER_ID, alarmIntent, 0);

            // Getting the date and time of the next event, then calculate the diference between DateTime.Now,
            // to know how much time it'll be until next event, so that we know when to trigger the notification
            DateTime eventDateTime = CalendarHelper.EventDateTime(eventos[0]);                
            TimeSpan eventMillis = (eventDateTime - GerirUtils.BaseUTCDate); // BaseDate is just the Utc date = 1970/01/01, because the alarm counts millis since then

            // Creating and setting the alarm manager
            alarm = (AlarmManager)GetSystemService(Context.AlarmService);
            alarm.SetExact(AlarmType.RtcWakeup, (long)eventMillis.TotalMilliseconds, pendingIntent);
        }
    }

广播接收器类

[BroadcastReceiver(Enabled = true)]
public class ReminderReciever : BroadcastReceiver
{
    private string type, title, info, content;
    private IList<string> events;
    private int notificationId;
    private Context context;

    public override void OnReceive(Context context, Intent intent)
    {
        this.context = context;
        notificationId = intent.GetIntExtra(GerirUtils.INTENT_ID, -1);
        type           = intent.GetStringExtra(GerirUtils.INTENT_TYPE);
        events         = intent.GetStringArrayListExtra(GerirUtils.INTENT_EVENTS);

        title    = intent.GetStringExtra(GerirUtils.INTENT_TITLE);
        info     = intent.GetStringExtra(GerirUtils.INTENT_INFO);
        content  = intent.GetStringExtra(GerirUtils.INTENT_CONTENT);


        if(notificationId > -1)
            if(type == GerirUtils.NOTIFICATION_TYPE_EVENT_REMINDER)
                ShowNotification();
            else if(type == GerirUtils.NOTIFICATION_TYPE_ADDED_EVENTS)
                ShowNotificationList();
    }

    private void ShowNotification() 
    {
        Android.Net.Uri sound = RingtoneManager.GetDefaultUri(RingtoneType.Alarm);
        NotificationManager mNotificationManager = (NotificationManager)context.GetSystemService(Context.NotificationService);

        if (Android.OS.Build.VERSION.SdkInt >= Android.OS.BuildVersionCodes.O)
        {
            NotificationChannel channel = new NotificationChannel("default", title, NotificationImportance.Default) { Description = content };
            mNotificationManager.CreateNotificationChannel(channel);
        }

        NotificationCompat.Builder mBuilder = new NotificationCompat.Builder(context, "default")
                    .SetSmallIcon(Resource.Mipmap.ic_calendario_gerir) // notification icon
                    .SetContentTitle(title)  // title for notification
                    .SetContentText(content) // message for notification
                    .SetContentInfo(info)    // Info message next to content
                    .SetSound(sound)         // set alarm sound for notification
                    .SetAutoCancel(true);    // clear notification after click

        Intent intent = new Intent(context, typeof(MainActivity));

        PendingIntent pi = PendingIntent.GetActivity(context, 0, intent, PendingIntentFlags.UpdateCurrent);
        mBuilder.SetContentIntent(pi);
        mNotificationManager.Notify(0, mBuilder.Build());
    }
}

1 个答案:

答案 0 :(得分:0)

好吧,我在仔细检查代码后设法找到了问题,看来我没有通过意图发送NotificationId。 ,BroadcastReviever的意图始终为默认值-1,因此if语句始终为false,并且愚蠢的我,在ID为-1时没有发出警告消息,因此我很难找到错误,那么如果收到消息我会怎么办。

因此,解决方案是将以下代码行添加到程序中:

private void StartDBUpdateAlarm() // Start the alarm manager for event reminder 
{
    ...
    ...

    if ((eventos.Count > 0)) // Only create notification if there is an event
    {
        // Create the Intent to pass some info through it to the notification
        Intent alarmIntent = new Intent(this, typeof(ReminderReciever));

        // MISSING LINE OF CODE
        alarmIntent.PutExtra(GerirUtils.INTENT_ID, GerirUtils.NOTIFICATION_REMINDER_ID);
        ...
        ...
        ...            
    }
}