BroadcastReceiver的onReceive方法中Intent extras为null问题排查
配置Android通知时Intent Extras在广播接收器中为null的问题
配置Android通知时遇到问题:当调度携带extras的Intent时,广播接收器的onReceive方法中接收的extras为null。日志显示调度时Intent的extras是正常的,但广播接收器收到时getStringExtra返回null。
创建Intent和PendingIntent的代码
EditText alertVacName = findViewById(R.id.editVacName); EditText alertHotName = findViewById(R.id.editHotName); EditText alertVacStartDate = findViewById(R.id.editVacStartDate); EditText alertVacEndDate = findViewById(R.id.editVacEndDate); String VacName = alertVacName.getText().toString(); String AlertStartDate = alertVacStartDate.getText().toString(); String AlertEndDate = alertVacEndDate.getText().toString(); String AlertHotName = alertHotName.getText().toString(); long trigger = DateConverter.toDate(sVacStartDate).getTime(); Intent intent = new Intent(VacationDetails.this, Vacation_Alert.class); intent.putExtra("mainText", (VacName + " Starts Today!")); intent.putExtra("Details", ("Start Date: " + AlertStartDate + "\n" + "End Date: " + AlertEndDate + "\n" + "Hotel: " + AlertHotName)); Log.d("Checking Intent Content:", intent.getStringExtra("Details")); PendingIntent sender = PendingIntent.getBroadcast(VacationDetails.this, MainActivity.numAlert, intent, PendingIntent.FLAG_IMMUTABLE); AlarmManager alarmManager = (AlarmManager) getSystemService(ALARM_SERVICE); alarmManager.set(AlarmManager.RTC_WAKEUP, trigger, sender); Log.d("Checking Intent Content After Schedule:", intent.getStringExtra("Details"));
广播接收器代码(含通知渠道创建)
public class Vacation_Alert extends BroadcastReceiver { String channel_id = "test"; static int noteID; @Override public void onReceive(Context context, Intent intent) { createNotificationChannel(context, channel_id); // Make sure to check if the extras are present before retrieving them if (intent != null && intent.getExtras() != null) { String title = intent.getStringExtra("mainText"); String message = intent.getStringExtra("Details"); // Debugging statement to check the value of "Details" Log.d("Vacation_Alert", "Received message: " + message); // Ensure that message is not null; use an empty string if it is if (message == null) { message = ""; } Notification notification = new NotificationCompat.Builder(context, channel_id) .setSmallIcon(R.drawable.vacation) .setContentTitle("Vacation/Excursion Alert!") .setContentText(title) .setContentInfo(message) // Use the retrieved message .build(); // Commented out the Toast for now, as it was causing issues // Toast.makeText(context, message, Toast.LENGTH_LONG).show(); NotificationManager notificationManager = (NotificationManager) context.getSystemService(Context.NOTIFICATION_SERVICE); notificationManager.notify(noteID++, notification); } else { // Handle the case where the intent or extras are null Log.e("Vacation_Alert", "Received null intent or extras"); } } private void createNotificationChannel(Context context, String CHANNEL_ID) { CharSequence name = "Vacation Alert"; String description = "Alert for Vacations"; int importance = NotificationManager.IMPORTANCE_DEFAULT; NotificationChannel channel = new NotificationChannel(CHANNEL_ID, name, importance); channel.setDescription(description); NotificationManager notificationManager = context.getSystemService(NotificationManager.class); notificationManager.createNotificationChannel(channel); } }
日志信息
2023-11-30 20:44:05.779 22344-22389 ProfileInstaller android.reserver.d308project D Installing profile for android.reserver.d308project 2023-11-30 20:44:08.478 22344-22365 EGL_emulation android.reserver.d308project D app_time_stats: avg=206.59ms min=1.40ms max=2407.80ms count=13 2023-11-30 20:44:08.634 22344-22365 OpenGLRenderer android.reserver.d308project E Unable to match the desired swap behavior. 2023-11-30 20:44:09.663 22344-22344 Checking I...t Content: android.reserver.d308project D Start Date: 2023-11-30 End Date: 2023-12-05 Hotel: Text 2023-11-30 20:44:09.664 22344-22344 Compatibil...geReporter android.reserver.d308project D Compat change id reported: 160794467; UID 10190; state: ENABLED 2023-11-30 20:44:09.667 22344-22344 Checking I... Schedule: android.reserver.d308project D Start Date: 2023-11-30 End Date: 2023-12-05 Hotel: Text 2023-11-30 20:44:09.738 22344-22365 EGL_emulation android.reserver.d308project D app_time_stats: avg=52.68ms min=1.84ms max=558.02ms count=18 2023-11-30 20:44:09.807 22344-22365 EGL_emulation android.reserver.d308project D app_time_stats: avg=17.40ms min=1.39ms max=403.42ms count=32 2023-11-30 20:44:09.989 22344-22344 WindowOnBackDispatcher android.reserver.d308project W sendCancelIfRunning: isInProgress=falsecallback=android.view.ViewRootImpl$$ExternalSyntheticLambda17@956e043 2023-11-30 20:44:10.008 22344-22365 OpenGLRenderer android.reserver.d308project D endAllActiveAnimators on 0x7daa5f9caa00 (MenuPopupWindow$MenuDropDownListView) with handle 0x7da94f98c4f0 2023-11-30 20:44:14.671 22344-22344 Vacation_Alert android.reserver.d308project D Received message: null 2023-11-30 20:44:16.380 22344-22365 EGL_emulation android.reserver.d308project D app_time_stats: avg=1643.25ms min=31.65ms max=6418.44ms count=4
问题原因及解决方法
原因
核心问题是PendingIntent的复用机制:当系统检测到已有一个匹配的PendingIntent(相同Context、requestCode、Intent匹配规则),会直接复用旧的PendingIntent,不会更新其中的extras。你当前仅使用PendingIntent.FLAG_IMMUTABLE,没有添加更新extras的标记。
解决方法
- 方法一:添加
FLAG_UPDATE_CURRENT标记
修改PendingIntent创建代码,添加PendingIntent.FLAG_UPDATE_CURRENT,确保Intent的extras更新时,已有的PendingIntent也会同步更新:PendingIntent sender = PendingIntent.getBroadcast(VacationDetails.this, MainActivity.numAlert, intent, PendingIntent.FLAG_IMMUTABLE | PendingIntent.FLAG_UPDATE_CURRENT); - 方法二:保证requestCode唯一
确保MainActivity.numAlert每次创建新提醒时都递增且不重复,避免系统复用旧的PendingIntent。
额外检查
- 确认
MainActivity.numAlert的递增逻辑正确,每次创建新的Alarm时使用不同的requestCode; - 若不需要保留旧的PendingIntent,也可使用
PendingIntent.FLAG_CANCEL_CURRENT先取消旧实例再创建新的,但FLAG_UPDATE_CURRENT更适合仅更新extras的场景。
内容的提问来源于stack exchange,提问作者Allen Klare
相关产品推荐
相关产品推荐

