使用AlarmManager触发广播时,onReceive为什么获取不到Intent的extra数据
问题根因
这个问题不属于SDK 30的已知bug,是代码实现问题,核心有两处错误:
- PendingIntent标志位配置不符合系统要求,导致Intent extra无法被正确写入和传递
- 全局复用Intent实例,多次调用设置闹钟方法时会出现数据覆盖或匹配错误
修复方案
1. 调整PendingIntent标志位
Android系统从API 31开始强制要求PendingIntent明确指定可变或不可变属性,API 30版本虽未强制,但默认行为也会限制不可变PendingIntent的extra修改。你需要更新PendingIntent的标志位,允许修改extra内容:
// 替换原PendingIntent创建逻辑 int pendingFlag = PendingIntent.FLAG_UPDATE_CURRENT; if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.S) { // 需要修改Intent内容必须指定FLAG_MUTABLE pendingFlag |= PendingIntent.FLAG_MUTABLE; } pendingIntent = PendingIntent.getBroadcast( TimetableActivity.this, firedAlarm.getRequestedCode(), intent, pendingFlag );
2. 不要复用全局Intent实例
你当前在Alarming构造函数中仅初始化一次Intent作为全局变量,多次调用setSessionAlarm方法时会复用同一个Intent,导致数据覆盖或PendingIntent匹配异常。修改为每次设置闹钟都创建新的Intent实例:
// 删掉Alarming类中的全局Intent成员变量,在setSessionAlarm方法内局部创建 public void setSessionAlarm(FiredAlarm firedAlarm) { // 原有日历逻辑保持不变 Calendar calendar = Calendar.getInstance(); calendar.setTimeInMillis(firedAlarm.getDateInMillis()); Calendar now = Calendar.getInstance(); if (calendar.before(now)) { calendar.set(Calendar.YEAR, now.get(Calendar.YEAR)); calendar.set(Calendar.WEEK_OF_YEAR, now.get(Calendar.WEEK_OF_YEAR)); } firedAlarm.setDateInMillis(calendar.getTimeInMillis()); // 每次创建新的Intent实例 Intent intent = new Intent(TimetableActivity.this, SessionAlarm.class); Bundle args = new Bundle(); // 建议直接用接收端的常量作为key,避免拼写错误 args.putParcelable(SessionAlarm.FIRED_ALARM_KEY, firedAlarm); intent.putExtras(args); intent.putExtra("INT", 54); // 后续PendingIntent、alarmManager设置逻辑保持不变 }
3. 接收端增加非空判断(可选,避免崩溃)
优化BroadcastReceiver的逻辑,避免Intent无extra时出现空指针异常:
@Override public void onReceive(Context context, Intent intent) { Log.i(TAG, " Received Integer : " + intent.getIntExtra("INT", -1)); Bundle bundle = intent.getExtras(); if (bundle != null) { firedAlarm = bundle.getParcelable(FIRED_ALARM_KEY); if (firedAlarm != null) { // 执行业务逻辑 } else { Log.i("onReceive", "no parcelable fired alarm found!"); } } else { Log.i("onReceive", "no extra data found in received intent"); } }
内容的提问来源于stack exchange,提问作者omarb1989
相关产品推荐
相关产品推荐

