例如,我希望每周四中午12点发出警报 我该怎么做?
我有一些实施但没有正常工作,我的代码,今天是星期三15,如果将手机的日期改为16星期四,应用程序什么都不做,如果我改变手机的日期在下周三22号电话发出通知,但只能在周四发送。
这是我的代码:
MainActivity:
protected override void OnCreate(Bundle bundle)
{
TabLayoutResource = Resource.Layout.Tabbar;
ToolbarResource = Resource.Layout.Toolbar;
base.OnCreate(bundle);
AsNumAssemblyHelper.HoldAssembly();
global::Xamarin.Forms.Forms.Init(this, bundle);
ImageCircleRenderer.Init();
Intent alarmIntent = new Intent(this, typeof(AlarmReceiver));
PendingIntent pending = PendingIntent.GetBroadcast(this, 0, alarmIntent, PendingIntentFlags.UpdateCurrent);
AlarmManager alarmManager = GetSystemService(AlarmService).JavaCast<AlarmManager>();
//AlarmType.RtcWakeup – it will fire up the pending intent at a specified time, waking up the device
alarmManager.SetRepeating(AlarmType.RtcWakeup,BootReceiver.FirstReminder(), BootReceiver.reminderInterval, pending);
PendingIntent pendingIntent = PendingIntent.GetBroadcast(this, 0, alarmIntent, 0);
LoadApplication(new App());
}
BootReceiver:
[BroadcastReceiver]
[IntentFilter(new[] { Intent.ActionBootCompleted })]
public class BootReceiver : BroadcastReceiver
{
//the interval currently every one minute
//to set it to dayly change the value to 24 * 60 * 60 * 1000
public static long reminderInterval = AlarmManager.IntervalDay * 7;
//public static long reminderInterval = 30 * 1000;
public static long FirstReminder()
{
Java.Util.Calendar calendar = Java.Util.Calendar.Instance;
calendar.Set(Java.Util.CalendarField.DayOfWeek, Calendar.Thursday);
return calendar.TimeInMillis;
}
public override void OnReceive(Context context, Intent intent)
{
Console.WriteLine("BootReceiver: OnReceive");
var alarmIntent = new Intent(context, typeof(AlarmReceiver));
var pending = PendingIntent.GetBroadcast(context, 0, alarmIntent, PendingIntentFlags.UpdateCurrent);
AlarmManager alarmManager = (AlarmManager)context.GetSystemService(Context.AlarmService);
alarmManager.SetRepeating(AlarmType.RtcWakeup, FirstReminder(), reminderInterval, pending);
PendingIntent pendingIntent = PendingIntent.GetBroadcast(context, 0, alarmIntent, 0);
}
}
AlarmReceiver:
[BroadcastReceiver]
public class AlarmReceiver : BroadcastReceiver
{
public override void OnReceive(Context context, Intent intent)
{
try
{
var title = "Something";
var message = "Something";
Intent backIntent = new Intent(context, typeof(MainActivity));
backIntent.SetFlags(ActivityFlags.NewTask);
var builder =
new Notification.Builder(context)
.SetContentTitle(title)
.SetContentText(message)
.SetAutoCancel(true)
.SetSmallIcon(Resource.Drawable.icon)
.SetDefaults(NotificationDefaults.All);
var notification = builder.Build();
var manager = NotificationManager.FromContext(context);
manager.Notify(1331, notification);
}
}
catch (Exception)
{
}
}
}
答案 0 :(得分:2)
对于低于19的api级别,您应该使用AlarmManager.setRepeating()
,并且您的警报将在指定时间准确触发。但正如document所说,当你的设备api等级为19及以上时,这将不再起作用。
注意:从API 19(KITKAT)开始,警报传递不准确:操作系统将移动警报以最小化唤醒和电池使用。有新的API支持需要严格交付保证的应用程序;请参阅setWindow(int,long,long,PendingIntent)和setExact(int,long,PendingIntent)。 targetSdkVersion早于API 19的应用程序将继续查看之前在请求时准确传递所有警报的行为。
同时使用alarmManager.SetExact()
方法:
警报将尽可能地传递到请求的触发时间。
因此,如果你想要实现精确的重复警报,那么@Dus said这里有两个建议:
或者:
将Dus的代码转换为C#:
AlarmManager alarmManager = (AlarmManager)this.GetSystemService(Context.AlarmService);
var ALARM_TYPE = AlarmType.RtcWakeup;
if (Build.VERSION.SdkInt >= Android.OS.BuildVersionCodes.M)
{
alarmManager.SetExactAndAllowWhileIdle(ALARM_TYPE, calendar.TimeInMillis, pendingIntent);
}
else if (Build.VERSION.SdkInt >= Android.OS.BuildVersionCodes.Lollipop)
{
alarmManager.SetExact(ALARM_TYPE, calendar.TimeInMillis, pendingIntent);
}
else if
{
alarmManager.Set(ALARM_TYPE, calendar.TimeInMillis, pendingIntent);
}
您可以在发生警报之前立即重新安排警报,然后再做任何可能出错的事情,并防止警报被重新安排。
关于使用SetExactAndAllowWhileIdle
方法实现重复闹钟的简单演示,希望这可以帮助您。
第一次设置闹钟:
var intent = new Intent(this, typeof(RepeatingAlarm));
var source = PendingIntent.GetBroadcast(this, 0, intent, 0);
// Schedule the alarm!
var am = (AlarmManager)GetSystemService(AlarmService);
//After 15s, use the RepeatingAlarm to show a toast
am.SetExactAndAllowWhileIdle(AlarmType.ElapsedRealtimeWakeup, SystemClock.ElapsedRealtime() + 15 * 1000, source);
在RepeatingAlarm
:
[BroadcastReceiver]
public class RepeatingAlarm : BroadcastReceiver
{
public override void OnReceive(Context context, Intent intent)
{
//Every time the `RepeatingAlarm` is fired, set the next alarm
var intentForRepeat = new Intent(context, typeof(RepeatingAlarm));
var source = PendingIntent.GetBroadcast(context, 0, intent, 0);
var am = (AlarmManager)Android.App.Application.Context.GetSystemService(Context.AlarmService);
am.SetExactAndAllowWhileIdle(AlarmType.ElapsedRealtimeWakeup, SystemClock.ElapsedRealtime() + 15 * 1000, source);
Toast.MakeText(context, "repeating_received and after 15s another alarm will be fired", ToastLength.Short).Show();
}
}