xamarin xamarin.android broadcastreceiver alarmmanager

Xamarin Android-Cómo programar y alarmar con un BroadcastReceiver



xamarin.android alarmmanager (2)

(Pregunto aquí porque no recibí ayuda en los foros de Xamarin) Estoy creando una alarma con este código:

Intent alarmIntent = new Intent(context, typeof(AlarmReceiver)); notificationClickIntent = PendingIntent.GetActivity(context, 0, new Intent(), 0); pendingIntent = PendingIntent.GetBroadcast(context, 0, alarmIntent, PendingIntentFlags.UpdateCurrent); am = (AlarmManager)Android.App.Application.Context.GetSystemService(Context.AlarmService); DateTime setTime = new DateTime(temp.Ticks + offset); //temp is the current time where seconds field = 0 if ((int)Build.VERSION.SdkInt >= 21) //my device enters this case { AlarmManager.AlarmClockInfo info = new AlarmManager.AlarmClockInfo(setTime.Ticks, notificationClickIntent); am.SetAlarmClock(info, pendingIntent); } else { am.SetExact(AlarmType.RtcWakeup, setTime.Ticks, notificationClickIntent); }

Antes de que se llame a ese código, mi clase se asegura de que estos también se hayan ejecutado:

ComponentName receiver = new ComponentName(context, Java.Lang.Class.FromType(typeof(AlarmReceiver))); PackageManager pm = context.PackageManager; pm.SetComponentEnabledSetting(receiver, ComponentEnabledState.Enabled, ComponentEnableOption.DontKillApp); Intent alarmIntent = new Intent(context, typeof(AlarmReceiver)); notificationClickIntent = PendingIntent.GetActivity(context, 0, new Intent(), 0); pendingIntent = PendingIntent.GetBroadcast(context, 0, alarmIntent, PendingIntentFlags.UpdateCurrent); am = (AlarmManager)Android.App.Application.Context.GetSystemService(Context.AlarmService);

Y aquí está mi receptor:

[BroadcastReceiver (Process = ":remote")] public class AlarmReceiver : BroadcastReceiver { public override void OnReceive(Context context, Intent intent) { Console.WriteLine("alarm fired"); Toast.MakeText(context, "Received intent!", ToastLength.Short).Show(); } }

De acuerdo, el receptor está siendo registrado por Xamarin correctamente. Lo sé porque si doy un valor incorrecto a AlarmClockInfo (un valor fuera del rango de tics de DateTime), la alarma se activa inmediatamente y se llama a mi método OnReceive. Sin embargo, cuando le doy un valor de tilde, por ejemplo, un minuto antes de la hora actual, la alarma no se activa. ¿Tal vez el momento es incorrecto? ... No parece así porque he registrado la hora de la próxima alarma programada del sistema y me informa al mismo tiempo que la configuré. ¿Alguna idea?

EDITAR: Así que ya tengo una aplicación de Android que realiza todo esto correctamente. Cuando lo convierto en Xamarin y C #, ya no funciona.


Así es como estoy creando una notificación local en mi aplicación Xamarin.

DateTime time = ... // whatever time AlarmManager manager = (AlarmManager)context.GetSystemService(Context.AlarmService); Java.Util.Calendar calendar = Java.Util.Calendar.Instance; calendar.TimeInMillis = Java.Lang.JavaSystem.CurrentTimeMillis(); calendar.Set(time.Year, time.Month - 1, time.Day, time.Hour, time.Minute, 0); manager.SetRepeating(AlarmType.RtcWakeup, calendar.TimeInMillis, AlarmManager.IntervalDay, pendingIntent);

Y aquí está la clase BroadcastReceiver:

[BroadcastReceiver] public class AlarmReceiver : BroadcastReceiver { public override void OnReceive(Context context, Intent intent) { NotificationManager nManager = (NotificationManager)context.GetSystemService(Context.NotificationService); Intent repeatingIntent; // Here I''m opening two different Activities based on condition if (CommonUtils.isLoggedIn())) { repeatingIntent = new Intent(context, typeof(MainActivity)); repeatingIntent.PutExtra(MainActivity.SELECT_TAB, 1); } else { repeatingIntent = new Intent(context, typeof(SplashActivity)); } repeatingIntent.SetFlags(ActivityFlags.ClearTop); PendingIntent pIntent = PendingIntent.GetActivity(context, 100, repeatingIntent, PendingIntentFlags.UpdateCurrent); NotificationCompat.Builder builder = new NotificationCompat.Builder(context) .SetContentIntent(pIntent) .SetSmallIcon(Resource.Drawable.az_logo_small) .SetColor(ContextCompat.GetColor(context, Resource.Color.PrimaryColor)) .SetContentTitle(CommonUtils.MAIN_TITLE) .SetContentText(UIMessages.VITAL_REMINDER) .SetAutoCancel(true); nManager.Notify(100, builder.Build()); } }

y en AndroidManifest.xml, necesitas este permiso

<uses-permission android:name="com.android.alarm.permission.SET_ALARM" />

también necesita el registro de BroadcastReceiver en AndroidManifest.xml

<application android:label="YourAppName" android:largeHeap="true" android:icon="@drawable/ic_launcher"> <receiver android:name=".AlarmReceiver"></receiver> </application>

Espero eso ayude.


Primero debe declarar <receiver android:name=".AlarmReceiver"></receiver> en su Manifiesto dentro de su aplicación

Y crea una clase BroadcastReceiver:

[BroadcastReceiver] class AlarmReceiver : BroadcastReceiver { public override void OnReceive(Context context, Intent intent) { //Miramos si la alarma debe repetirse var repeat = intent.GetStringExtra("repeat"); //Hacemos sonar la alarma Uri notification = RingtoneManager.GetDefaultUri(RingtoneType.Alarm); Ringtone r = RingtoneManager.GetRingtone(context, notification); r.Play(); // }

El siguiente código es Iniciar y cancelar el intento pendiente

public void SetAlarm(long miliseconds) { AlarmManager alarmManager = (AlarmManager)this.Activity.GetSystemService(Context.AlarmService); Intent intent = new Intent(this.Activity, typeof(AlarmReceiver)); intent.PutExtra("repeat", repeat); PendingIntent pendingIntent = PendingIntent.GetBroadcast(this.Activity, /*id de la alarma que sea unico */0, intent, PendingIntentFlags.CancelCurrent); alarmManager.Set(AlarmType.RtcWakeup, miliseconds, pendingIntent); Toast toast = Toast.MakeText(this.Activity, Resource.String.set_alarm, ToastLength.Short); toast.Show(); } public void CancelAlarm() { AlarmManager alarmManager = (AlarmManager)this.Activity.GetSystemService(Context.AlarmService); Intent intent = new Intent(this.Activity, typeof(AlarmReceiver)); PendingIntent pendingIntent = PendingIntent.GetBroadcast(this.Activity, /*a traves del anterior id ahora podemos pedir que se actualice */0, intent, PendingIntentFlags.UpdateCurrent); //Con el pending intent actualizado podemos cancelarlo pendingIntent.Cancel(); alarmManager.Cancel(pendingIntent); Toast toast = Toast.MakeText(this.Activity, Resource.String.remove_alarm, ToastLength.Short); toast.Show(); }

Para terminar, debe llamarlos, por ejemplo, al hacer clic en ellos

if (alarm.Active == true) { alarm.Active = false; alarmsFragment.CancelAlarm(); } else { alarm.Active = true; // the time you want in milliseconds long miliseconds = Java.Lang.JavaSystem.CurrentTimeMillis() + 10000 ; alarmsFragment.SetAlarm(miliseconds); }