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

Android通知点击ID重复及Alarm取消Receiver选择问题

Let's Fix Your Android Notification & Alarm Issues

Hey there, let's break down and solve your two problems step by step:


1. Fix: MyFlagBroadcastReceiver Gets Same Notification ID Every Time

The root cause here is how you're creating the PendingIntent for your notification action. Right now, you're using a fixed requestCode of 0—this causes Android to reuse the same PendingIntent instance for all your notifications, so the extra data (your notification ID) never updates.

Here's the Fix in Your Notification Receiver Code:

In your onReceive method where you build the notification action, change the PendingIntent creation to use the unique notification ID as the requestCode, and add a flag to ensure the intent extras are updated:

// Replace this line:
// PendingIntent flagIt = PendingIntent.getBroadcast(context, 0, snoozeIntent, 0);

// With this:
PendingIntent flagIt = PendingIntent.getBroadcast(
    context, 
    notificationAdministration.getId(), 
    snoozeIntent, 
    PendingIntent.FLAG_UPDATE_CURRENT | (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M ? PendingIntent.FLAG_IMMUTABLE : 0)
);

Why This Works:

  • The requestCode parameter is a key identifier for PendingIntents. Using each notification's unique ID ensures Android creates a separate PendingIntent for every notification action.
  • FLAG_UPDATE_CURRENT makes sure that if a PendingIntent for this ID already exists, its extras are updated with the latest values (so you get the correct notification ID when the action is clicked).
  • FLAG_IMMUTABLE is required for API 31+ to comply with Android's security guidelines (use FLAG_MUTABLE only if you need to modify the intent later—immutable is safer for notification actions).

2. Which Receiver to Use When Canceling Alarms?

When canceling an alarm, you need to match the exact same PendingIntent you used to set the alarm. That means:

  • The Intent must target the original receiver class you used in setAlarm() (likely your MyReceiverAdministration class, since that's what triggers the notification).
  • You must use the same requestCode (which is notificationAdministration.getId() in your setup code).
  • Use matching flags (consistent with what you used when setting the alarm).

Corrected Cancel Alarm Code:

AlarmManager alarmManager = (AlarmManager) context.getSystemService(Context.ALARM_SERVICE);
// Target the SAME receiver you used in setAlarm() (e.g., MyReceiverAdministration.class)
Intent myIntent = new Intent(context, MyReceiverAdministration.class); 
PendingIntent pendingIntent = PendingIntent.getBroadcast(
    context, 
    notificationAdministration.getId(), // Same requestCode as setAlarm()
    myIntent, 
    PendingIntent.FLAG_NO_CREATE | (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M ? PendingIntent.FLAG_IMMUTABLE : 0)
);

if (pendingIntent != null) {
    alarmManager.cancel(pendingIntent);
    pendingIntent.cancel(); // Clean up the PendingIntent
}

Key Notes:

  • FLAG_NO_CREATE ensures we don't create a new PendingIntent—we only retrieve the existing one that was used to set the alarm. If it doesn't exist, we skip canceling (avoids unnecessary operations).
  • Always match the receiver class, requestCode, and flags between setting and canceling the alarm—otherwise, Android won't find the correct alarm to cancel.

Formatted Core Code Reference

Set Alarm Code

public void setAlarm(Cell cell, Long timeStamp, String title, String message) { 
    Integer id = (int) System.currentTimeMillis(); 
    Intent notificationIntent = new Intent(context, receiver); 
    notificationIntent.putExtra("ID", id); 
    PendingIntent pendingIntent = PendingIntent.getBroadcast(context, id, notificationIntent, 0); 
    AlarmManager alarmManager = (AlarmManager) context.getSystemService(Context.ALARM_SERVICE); 
    assert alarmManager != null; 
    alarmManager.setRepeating(AlarmManager.RTC_WAKEUP, timeStamp, 2 * 60 * DateUtils.SEC_TO_MILLIS, pendingIntent); 
    RepositoryManager repositoryManager = RepositoryManager.getInstance(); 
    repositoryManager.storeNotificationAdministration(new NotificationAdministration(id, timeStamp, 2, title, message, 1, null, cell, StatusNotification.NOT_YET_NOTIFIED.getId())); 
}

Notification Receiver Code (Fixed Action PendingIntent)

@Override 
public void onReceive(Context context, Intent intent) { 
    RepositoryManager controllerDatabase = RepositoryManager.getInstance(ControllerDatabase.getInstance(context)); 
    NotificationMedicine notificationMedicine = controllerDatabase.getNotificationMedicine(); 
    if (notificationMedicine.getEnable()) { 
        if (intent.hasExtra("ID")) { 
            int id = intent.getIntExtra("ID", 0); 
            NotificationManager mNotifyMgr = (NotificationManager) context.getSystemService(Context.NOTIFICATION_SERVICE); 
            Log.d("DEBUG", "MyReceiverAdministration " + id); 
            try { 
                NotificationAdministration notificationAdministration = controllerDatabase.findNotificationAdministrationById(id); 
                NotificationCompat.Builder mBuilder = new NotificationCompat.Builder(context) 
                    .setSmallIcon(R.drawable.ic_medicine) 
                    .setLargeIcon(BitmapFactory.decodeResource(context.getResources(), R.mipmap.ic_launcher)) 
                    .setContentTitle(notificationAdministration.getTitle()) 
                    .setContentText(notificationAdministration.getMessage()) 
                    .setOngoing(false) 
                    .setPriority(NotificationCompat.PRIORITY_HIGH) 
                    .setAutoCancel(false); 
                Intent i = new Intent(context, MainActivity.class); 
                i.putExtra(SettingsData.TAG_CELL, notificationAdministration.getCell().getId()); 
                PendingIntent pendingIntent = PendingIntent.getActivity( 
                    context, notificationAdministration.getId(), i, 0 
                ); 
                Intent snoozeIntent = new Intent(context, MyFlagBroadcastReceiver.class); 
                snoozeIntent.putExtra(SettingsData.TAG_CELL, notificationAdministration.getId()); 
                // Fixed PendingIntent here
                PendingIntent flagIt = PendingIntent.getBroadcast(
                    context, 
                    notificationAdministration.getId(), 
                    snoozeIntent, 
                    PendingIntent.FLAG_UPDATE_CURRENT | (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M ? PendingIntent.FLAG_IMMUTABLE : 0)
                ); 
                mBuilder.setLights(0x6098CF, 1000, 2000); 
                Uri uriRingtone = notificationMedicine.getRingtone(); 
                mBuilder.setSound(uriRingtone); 
                mBuilder.setContentIntent(pendingIntent); 
                mBuilder.addAction(R.drawable.ic_timer_black_24dp, context.getString("Do my action"), flagIt); 
                mNotifyMgr.notify(notificationAdministration.getId(), mBuilder.build()); 
                Vibrator v = (Vibrator) context.getSystemService(Context.VIBRATOR_SERVICE); 
                v.vibrate(700); 
                notificationAdministration.setStatus(StatusNotification.NOTIFIED.getId()); 
                controllerDatabase.storeNotificationAdministration(notificationAdministration); 
            } catch (ObjectNotFoundException e) { 
                e.printStackTrace(); 
            } 
        } 
    } 
}

Notification Action Receiver Code

RepositoryManager controllerDatabase = RepositoryManager.getInstance(ControllerDatabase.getInstance(context)); 
if (intent.hasExtra(SettingsData.TAG_CELL)) { 
    int id = intent.getIntExtra(SettingsData.TAG_CELL, 0); 
    try { 
        NotificationAdministration notificationAdministration = controllerDatabase.findNotificationAdministrationById(id); 
        Device device = controllerDatabase.getDefaultDeviceByUser(controllerDatabase.getLoggedUser().getUser()); 
        Cell cell = controllerDatabase.findCellById(device, notificationAdministration.getCell().getId()); 
        Calendar calendar = Calendar.getInstance(); 
        Long now = calendar.getTimeInMillis() / DateUtils.SEC_TO_MILLIS; 
        controllerDatabase.flagMedicineTaken(cell, now); 
        NotificationManager mNotificationManager = (NotificationManager) context.getSystemService(Context.NOTIFICATION_SERVICE); 
        if (mNotificationManager != null) { 
            mNotificationManager.cancel(id); 
        } 
    } catch (ObjectNotFoundException e) { 
        e.printStackTrace(); 
    } 
}

内容的提问来源于stack exchange,提问作者I love coding

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.27 10:09:23