Xamarin Android 设置指定日月本地通知却每日重复触发问题求助
问题排查与修复方案
核心错误
你调用SetInexactRepeating时参数顺序完全传反了,这是问题的根本原因:
Android AlarmManager.SetInexactRepeating的参数定义为:
SetInexactRepeating(AlarmType 类型, long 首次触发时间戳, long 重复间隔毫秒数, PendingIntent 回调意图)
你代码里把3600000(1小时对应的毫秒数,对应1970-01-01 01:00:00的时间戳,远早于当前时间)传给了首次触发时间参数,系统检测到触发时间已过期就会立刻触发闹钟,所以通知几秒就弹出;同时你把目标日期的时间戳传给了重复间隔参数,才会出现不符合预期的重复频率。
额外注意点
如果设置闹钟时,当年的目标日期(比如当年9月24日)已经过了,也会触发立即响铃的逻辑,需要额外判断日期是否已过期,过期就自动顺延到下一年的对应日期。
修正后代码
private void Remind_Click(object sender, System.EventArgs e) { string title = "If you see this"; string message = "it means it works"; Intent alarmIntent = new Intent(Application.Context, typeof(AlarmReceiver)); alarmIntent.PutExtra("message", message); alarmIntent.PutExtra("title", title); // 后续如果要设置多个不同时间的闹钟,requestCode需要设为唯一值避免覆盖 var pendingIntent = PendingIntent.GetBroadcast(this, 0, alarmIntent, PendingIntentFlags.UpdateCurrent); var alarmManager = GetSystemService(AlarmService).JavaCast<AlarmManager>(); DateTime nowDate = DateTime.Now; int month = 09; int day = 24; DateTime newDate = new DateTime(nowDate.Year, month, day); // 新增逻辑:当年目标日期已过就顺延到下一年 if (newDate < nowDate) { newDate = newDate.AddYears(1); } // 转UTC时间计算Unix时间戳,避免时区误差 var triggerAtMs = (long)(newDate.ToUniversalTime() - new DateTime(1970, 1, 1, 0, 0, 0, DateTimeKind.Utc)).TotalMilliseconds; // 用系统提供的年间隔常量,比手动计算更规范 long intervalMs = AlarmManager.IntervalYear; // 修正参数顺序 alarmManager.SetInexactRepeating(AlarmType.RtcWakeup, triggerAtMs, intervalMs, pendingIntent); ShowSnack(main, $"Set date: {newDate} "); }
其他适配建议
- 若需要精准触发,不要用
SetInexactRepeating,Android 4.4之后该方法为了降低功耗做了批量唤醒优化,触发时间会有偏差。对精准度要求高可以用SetExactAndAllowWhileIdle设置单次闹钟,每次触发后再手动设置下一年的闹钟即可。 - 安卓12及以上版本需要申请
SCHEDULE_EXACT_ALARM权限才能正常设置精确闹钟,需要提前做权限判断和申请。 - 确保你在AndroidManifest中注册了
AlarmReceiver,否则广播无法正常接收。
内容的提问来源于stack exchange,提问作者Michał Schmude
相关产品推荐
相关产品推荐

