You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

使用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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.06 04:39:03