将AlarmManager设置为在给定的特定时间内重复

时间:2014-04-25 17:56:37

标签: c# xamarin.android xamarin alarmmanager

我无法让AlarmManagerCalendarGregorianCalendar对象一起正常使用。

Global.StartingTime是另一个类中的static DateTime对象。它的小时属性以24小时时钟格式返回时间。

尝试1 - 使用Calendar - 结果:不会触发

public void SetAlarm()
{
        if (Global.StartingTime == null || Global.StartingTime == DateTime.MinValue) return;

        Calendar now = Calendar.GetInstance (Java.Util.TimeZone.Default);
        Calendar alarmTime = Calendar.GetInstance (Java.Util.TimeZone.Default);

        alarmTime.Set(CalendarField.HourOfDay, Global.StartingTime.Hour);
        alarmTime.Set(CalendarField.HourOfDay, Global.StartingTime.Minute);
        if (alarmTime.Before(now))
            alarmTime.Add(CalendarField.DayOfMonth, 1);

        AlarmManager am = (AlarmManager) _context.GetSystemService (Context.AlarmService);
        Intent intent = new Intent(_context, typeof(MainReceiver));
        intent.PutExtra (ALARM_ACTION, true);
        PendingIntent pi = PendingIntent.GetBroadcast (_context, 0, intent, 0);
        am.SetRepeating (AlarmType.ElapsedRealtimeWakeup, alarmTime.TimeInMillis, AlarmManager.IntervalDay, pi);
        AlarmSet = true;
}

尝试2 - 使用GregorianCalendar - 结果:立即开火,而不是在指定的时间和分钟开火。

public void SetAlarm()
{
        if (Global.StartingTime == null || Global.StartingTime == DateTime.MinValue) return;

        GregorianCalendar now = new GregorianCalendar ();
        now.TimeInMillis = SystemClock.ElapsedRealtime();

        GregorianCalendar alarmTime = new GregorianCalendar ();
        alarmTime.Add(CalendarField.DayOfYear, now.Get(CalendarField.DayOfYear));
        alarmTime.Set(CalendarField.HourOfDay, Global.StartingTime.Hour);
        alarmTime.Set(CalendarField.Minute, Global.StartingTime.Minute);
        alarmTime.Set(CalendarField.Second, now.Get(CalendarField.Second));
        alarmTime.Set(CalendarField.Millisecond, now.Get(CalendarField.Millisecond));
        alarmTime.Set(CalendarField.Date, now.Get(CalendarField.Date));
        alarmTime.Set(CalendarField.Month, now.Get(CalendarField.Month));

        if (alarmTime.Before (now))
            alarmTime.Add (CalendarField.DayOfYear, 1);

        AlarmManager am = (AlarmManager) _context.GetSystemService (Context.AlarmService);
        Intent intent = new Intent(_context, typeof(MainReceiver));
        intent.PutExtra (ALARM_ACTION, true);
        PendingIntent pi = PendingIntent.GetBroadcast (_context, 0, intent, 0);
        am.SetRepeating (AlarmType.RtcWakeup, alarmTime.TimeInMillis, AlarmManager.IntervalDay, pi);
        AlarmSet = true;
}

1 个答案:

答案 0 :(得分:0)

我决定只使用Timer而不是AlarmManager这似乎在我的特定情况下运行良好(应用程序不断运行服务而且我不需要使用AlarmManager唤醒它。)

这会获得闹钟之前的时间

public int GetTimeInterval(DateTime dt)
{
    DateTime now = DateTime.Now;
    if (dt <= now) {
        dt = dt.AddDays(1);
    }

    return (dt - now).TotalMilliseconds;
}

然后我使用发送广播的System.Threading.Timer

var IntervalOfOneDay = 86400000; // 24 hours in milliseconds
var interval = GetTimeInterval(alarmTime);
timer = New System.Threading.Timer(func, null, interval, IntervalOfOneDay);