【问题标题】:Xamarin Android Weekly repeating Alarm is not firingXamarin Android Weekly 重复警报未触发
【发布时间】:2018-09-14 09:59:12
【问题描述】:

我正在尝试安排每周通知。对于特定的日期和时间,每周重复但它不起作用。这是我安排闹钟的代码

var id = Convert.ToInt32(string.Format("{0}{1}{2}", task.Id, hour, minutes));
var intent = new Intent(context, typeof(AlarmReceiver));
intent.PutExtra(AndroidConstants.NotificationId, id);
intent.PutExtra(AndroidConstants.NotificationMessage, $"{context.Resources.GetString(Resource.String.general_push_reminder_body)} {task.Name}");
intent.PutExtra(AndroidConstants.NotificationTitle, context.Resources.GetString(Resource.String.general_push_reminder_title));

var pendingIntent = PendingIntent.GetBroadcast(context, id, intent, PendingIntentFlags.CancelCurrent);
Calendar calendar = Calendar.Instance;
calendar.Set(CalendarField.DayOfWeek, (int)day);
calendar.Set(CalendarField.HourOfDay, hour);
calendar.Set(CalendarField.Minute, minutes);
calendar.Set(CalendarField.Second, 0);

if (calendar.Before(Calendar.Instance))
{
    Log.Info("Task", $"Adding 7 days as scheduled time is past");
    calendar.Add(CalendarField.DayOfYear, 7);
}
var alarmManager = (AlarmManager)context.GetSystemService(Context.AlarmService);
alarmManager.SetRepeating(AlarmType.RtcWakeup, calendar.TimeInMillis, 7 * AlarmManager.IntervalDay, pendingIntent);

这是我的接收器

[BroadcastReceiver(Enabled = true)]
    public class AlarmReceiver : BroadcastReceiver
    {
        public override void OnReceive(Context context, Intent intent)
        {
            try
            {
                Log.Info("Task", $"Alarm manager received");
                var title = intent.GetStringExtra(AndroidConstants.NotificationTitle);
                var message = intent.GetStringExtra(AndroidConstants.NotificationMessage);
                var id = intent.GetIntExtra(AndroidConstants.NotificationId, 0);
                Log.Info("Task", $"Showing Notification with id {id} {title} and {message}");
                NotificationHandler.ShowNotification(context, id, title, message);
            }
            catch (Exception ex)
            {
                Log.Error("Task", ex.ToString());
            }
        }

也不例外。我尝试了几个选项,但 AlarmReceiver 根本没有触发。

如果我选择今天并在当前时间之后给出时间,仍然会触发 if block for adding time for past 并添加额外的 7 天。

【问题讨论】:

    标签: xamarin xamarin.android alarmmanager android-alarms repeatingalarm


    【解决方案1】:

    我认为问题出在alarmManager.SetRepeating(...)。

    如果您看到Android.App.AlarmManager.SetRepeating 的文档,则说明第二个参数:

    triggerAtMillis:闹钟应该首先响起的时间(以毫秒为单位),使用适当的时钟(取决于闹钟类型)。

    您正在传递calendar.TimeInMillis,根据文档为您提供:

    当前时间,距纪元的 UTC 毫秒数

    这不是你想要的。

    我宁愿不使用Calendar,而是使用DateTime,因为它更易于使用,并且以毫秒为单位计算所需日期时间和当前日期时间之间的差异,即:

    // here I hardcode the values but you should set whatever you want or get it from the user
    DayOfWeek desiredDayOfWeek = DayOfWeek.Saturday;
    int desiredHour = 1, desiredMinute = 30, desiredSecond = 0;
    
    // Calculate which will be the desired date time in which the alarm will go off for the first time
    var differenceInNumberOfDaysBetweenDayOfWeek = desiredDayOfWeek - DateTime.Today.DayOfWeek;
    var nextDayOfWeek = differenceInNumberOfDaysBetweenDayOfWeek >= 0
                            ? DateTime.Today.AddDays(differenceInNumberOfDaysBetweenDayOfWeek)
                            : DateTime.Today.AddDays(differenceInNumberOfDaysBetweenDayOfWeek + 7);
    var desiredDateTime = new DateTime(nextDayOfWeek.Year, nextDayOfWeek.Month, nextDayOfWeek.Day, desiredHour, desiredMinute, desiredSecond);
    
    // this are the milliseconds left to arrive to the desired date time for the alarm to go off
    var desiredMillisToArriveToDateTime = (desiredDateTime - DateTime.Now).Milliseconds;
    
    var alarmManager = (AlarmManager)context.GetSystemService(Context.AlarmService);
    alarmManager.SetRepeating(AlarmType.RtcWakeup, desiredMillisToArriveToDateTime, 7 * AlarmManager.IntervalDay, pendingIntent);
    

    嗨

    【讨论】:

    • 使用此代码,警报会在指定时间前几分钟触发。我检查了一些 Android java 代码,发现 calendar.TimeInMillis 是这样完成的。顺便说一句,我在代码中发现了另一个问题。 C# DayOfWeek 和 Android DayofWeek 没有相同的 int 值。 Android DayOfWeek 值从 1 开始,而 C# 为 0。我解决了这个问题。有了这个修复,我得到了警报,但它永远不会在准确的时间。
    • 我会检查它给出了多少毫秒,以及等待的实际毫秒数,以便发出警报的时间是正确的
    • 我已经检查过了。它们完全相同。可能是关于 Android 操作系统如何根据电池使用情况、cpu 使用情况等处理预定警报。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多