Alarm Manager意外触发广播求助:按数据库时间设闹钟异常
Hey there! Let's figure out why your Alarm Manager is firing when it shouldn't—this is a common gotcha with Android's AlarmManager, so let's break down the likely issues and fixes:
1. Time Parsing & "Past Time" Immediate Trigger
The biggest culprit here is probably that your parsed Date is in the past relative to the current time. When you use AlarmManager.set(), if the target time has already passed today, the system will fire the alarm immediately instead of waiting for tomorrow.
Fix: Adjust for Future Time
First, parse your target time, then compare it to the current time. If it's earlier, add 24 hours to push it to tomorrow:
SimpleDateFormat sdf = new SimpleDateFormat("HH:mm"); sdf.setTimeZone(TimeZone.getDefault()); // Explicitly set timezone to avoid surprises // Use String.format to ensure proper two-digit formatting (e.g., "09:05" instead of "9:5") String temp = String.format("%02d:%02d", h, m); Date targetTime = sdf.parse(temp); Date currentTime = new Date(); // If target time is already today's past time, add one day if (targetTime.before(currentTime)) { Calendar calendar = Calendar.getInstance(); calendar.setTime(targetTime); calendar.add(Calendar.DAY_OF_YEAR, 1); targetTime = calendar.getTime(); }
2. PendingIntent Duplication Issues
If you're reusing the same requestCode for multiple alarms, or not using the right PendingIntent flags, you might be overwriting existing PendingIntents—this can cause old alarms to fire unexpectedly or new ones to not behave as intended.
Fix: Use Unique Request Codes & Proper Flags
- Ensure each alarm has a unique
requestCode(e.g., use a combination of hour, minute, and a unique identifier for the alarm). - Use appropriate flags like
PendingIntent.FLAG_UPDATE_CURRENTorPendingIntent.FLAG_IMMUTABLE(for Android 12+) instead of0:
// Generate a unique request code (example using hour + minute * 100 to avoid collisions) int requestCode = h + m * 100; // For Android 12+, use FLAG_IMMUTABLE unless you need to modify the intent later int flags = Build.VERSION.SDK_INT >= Build.VERSION_CODES.S ? PendingIntent.FLAG_IMMUTABLE : PendingIntent.FLAG_UPDATE_CURRENT; alarmIntent = PendingIntent.getBroadcast(_c, requestCode, intent, flags);
3. AlarmManager API Choice
The basic set() method has limitations, especially on Android 6.0+ (Marshmallow) with Doze mode. If you need precise timing, use more reliable APIs:
- For one-time precise alarms: Use
AlarmManager.setExact()orAlarmManager.setExactAndAllowWhileIdle()(to bypass Doze mode if needed). - For repeating alarms: Use
AlarmManager.setRepeating()(but note it's not precise for API 19+) orsetExactAndAllowWhileIdle()with manual rescheduling.
Updated Alarm Setting Code
alarmMgr = (AlarmManager)_c.getSystemService(Context.ALARM_SERVICE); Intent intent = new Intent(_c, AlarmBroadcastReciever.class); // (Add the request code and flags fix here as above) // Use setExact for precise one-time alarms if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) { alarmMgr.setExact(AlarmManager.RTC_WAKEUP, targetTime.getTime(), alarmIntent); } else { alarmMgr.set(AlarmManager.RTC_WAKEUP, targetTime.getTime(), alarmIntent); }
4. Double-Check Broadcast Receiver Registration
Make sure your AlarmBroadcastReciever is properly registered in the manifest (if using static registration) or dynamically—if it's registered incorrectly, it might receive unintended broadcasts.
Example manifest registration:
<receiver android:name=".AlarmBroadcastReciever" />
Give these fixes a try—most unexpected AlarmManager fires come from one of these issues. Let me know if you still run into problems!
内容的提问来源于stack exchange,提问作者Debodzire Paul

