AlarmManager sólo funciona en un futuro próximo

Estoy trabajando en una aplicación de Xamarin para Android, iOS y Windows Phone. Esta aplicación debe mostrar las notificaciones locales en determinados momentos. Para Android utilizo AlamManager. Las notificaciones funcionan en iOS, WinPhone y en los emuladores de Android. En mi dispositivo (Samsung Galaxy S2) sólo las notificaciones en un futuro próximo (1 min, 5 min, 20 min) de trabajo. Las notificaciones en unos 45 minutos o más no aparecen. Las notificaciones en unos 30 minutos a veces aparecen y otras no. Las notificaciones se realizan en un receptor de difusión. ¿Hay algún problema con mi código o el alarmManager? No se puede encontrar nada. Gracias por tu ayuda.

Aquí se establece el alarmManager:

public class NotificationService : NotificationServiceBase { private readonly AlarmManager _alarmManager; private readonly long _dayInMilliseconds = AlarmManager.IntervalDay; private PendingIntent _currentPendingIntent; public NotificationService() { _alarmManager = (AlarmManager) Forms.Context.GetSystemService(Context.AlarmService); } public override void CancelNotification() { _alarmManager.Cancel(_currentPendingIntent); } protected override void ChangeNotificationTime(TaskEntity task) { var settings = _settingsBusinessLayer.GetSettings(); NotificationSetup(settings, task); } protected override async void ChangeNotificationSettings(SettingsEntity settings) { if (!settings.IsReminderOn) { CancelNotification(); return; } var task = await _taskBusinessLayer.GetTaskForCurrentMonthAsync(true, true); NotificationSetup(settings, task); } private void NotificationSetup(SettingsEntity settings, TaskEntity task) { _currentPendingIntent = GetPendingIntent(); _alarmManager.Cancel(_currentPendingIntent); if (settings.ReminderRepetitive == ReminderRepetitive.Daily) { SetDailyAlarm(settings); } else { SetSingleAlarm(settings, task); } } private void SetDailyAlarm(SettingsEntity settings) { long alarmTimeInMilliseconds; if (settings.RemindOn < DateTime.Now.TimeOfDay) { alarmTimeInMilliseconds = (long) CalculateAlarmTimeFromNow (DateTime.Now.AddDays(1), 0, settings.RemindOn).TotalMilliseconds; } else { alarmTimeInMilliseconds = (long) CalculateAlarmTimeFromNow (DateTime.Now, 0, settings.RemindOn).TotalMilliseconds; } var alarmTime = SystemClock.ElapsedRealtime() + alarmTimeInMilliseconds; _alarmManager.SetRepeating(AlarmType.ElapsedRealtime, alarmTime, _dayInMilliseconds, _currentPendingIntent); } private void SetSingleAlarm(SettingsEntity settings, TaskEntity task) { try { var alarmTimeInMilliseconds = (long) CalculateAlarmTimeFromNow (task.DueDate, Convert.ToUInt32(settings.RemindDaysBefore), settings.RemindOn).TotalMilliseconds; var alarmTime = SystemClock.ElapsedRealtime() + alarmTimeInMilliseconds; _alarmManager.Set(AlarmType.ElapsedRealtime, alarmTime, _currentPendingIntent); } catch (AlarmTimeIsInPastException) { } } private PendingIntent GetPendingIntent() { var alarmIntent = new Intent(Forms.Context, typeof (NotificationReceiver)); return PendingIntent.GetBroadcast(Forms.Context, 0, alarmIntent, PendingIntentFlags.UpdateCurrent); } } 

Receptor de radiodifusión, donde se hace la notificación.

 [BroadcastReceiver] public class NotificationReceiver : BroadcastReceiver { public override void OnReceive(Context context, Intent intent) { var taskBusinessLayer = DependencyInjection.Container.Resolve<ITaskBusinessLayer>(); var task = taskBusinessLayer.GetTaskForCurrentMonthAsync(true, true).Result; var message = NotificationServiceBase.CreateNotificationMessageRemainingTime(task); var title = AppResources.NotificationTitle; var notIntent = new Intent(context, typeof (MainActivity)); var contentIntent = PendingIntent.GetActivity(context, 0, notIntent, PendingIntentFlags.CancelCurrent); var builder = new Notification.Builder(context) .SetContentIntent(contentIntent) .SetContentTitle(title) .SetContentText(message) .SetSmallIcon(Resource.Drawable.icon) .SetDefaults(NotificationDefaults.Sound | NotificationDefaults.Vibrate) .SetPriority((int) NotificationPriority.Max) .SetAutoCancel(true) .SetWhen(JavaSystem.CurrentTimeMillis()); var notification = builder.Build(); var notificationManager = NotificationManager.FromContext(context); const int notificationId = 0; notificationManager.Notify(notificationId, notification); } } 

La entrega de alarmas desde KITKAT es inexacta. Así que probablemente necesite cambiar en su método SetSingleAlarm esto:

 _alarmManager.Set(AlarmType.ElapsedRealtime, alarmTime, _currentPendingIntent); 

a esto:

 if (Build.VERSION.SdkInt < BuildVersionCodes.Kitkat) { _alarmManager.Set(AlarmType.ElapsedRealtime, alarmTime, _currentPendingIntent); } else { _alarmManager.SetExact(AlarmType.ElapsedRealtime, alarmTime, _currentPendingIntent); } 
  • Xamarin.Forms ListView OutOfMemoryError excepción en Android
  • Xamarin.Forms Tome la foto con la cámara muestra la orientación equivocada y se bloquea en el botón Atrás
  • ¿Por qué Xamarin.Forms es tan lento al mostrar algunas etiquetas (especialmente en Android)?
  • Convertir Xamarin.Forms.Color a color específico de la plataforma
  • Color del borde para el editor en Xamarin.Forms
  • Xamarin Forms Android Keyboard mueve toda la página hacia arriba
  • ¿Cómo detectar Golpe izquierdo y Golpe derecho para Stacklayout en Xamarin.Forms?
  • SetPage (Xamarin.Forms.Page) 'es un error obsoleto - Android
  • Convertir automáticamente el código entre Xamarin iOS y Xamarin Android
  • Cómo desactivar la selección resaltada en listview xamarin.forms en android
  • Cómo obtener / detectar el tamaño de la pantalla en Xamarin.Forms?
  • FlipAndroid es un fan de Google para Android, Todo sobre Android Phones, Android Wear, Android Dev y Aplicaciones para Android Aplicaciones.