Xamarin Android Еженедельно повторяющийся сигнал тревоги не срабатывает - PullRequest
0 голосов
/ 14 сентября 2018

Я пытаюсь запланировать еженедельное уведомление. Для определенного дня и времени повторяется еженедельно, но это не работает. Вот мой код для планирования будильника

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 дней.

1 Ответ

0 голосов
/ 14 сентября 2018

Я думаю, что проблема в 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);

HIH

...