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

Android通知Action点击后无法同步执行跳转与取消通知问题

带操作按钮的通知点击同步关闭实现方案

已实现的基础功能

通过addAction方法为通知添加操作按钮,点击「Start」按钮可跳转至MainActivity,在WebView中加载指定URL,基础功能可正常运行,实现代码如下:

Intent intent = new Intent(this, MainActivity.class);
        intent.putExtra("uri", uri);
        intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP | Intent.FLAG_ACTIVITY_SINGLE_TOP);
        PendingIntent pendingIntent = PendingIntent.getActivity(this, 0, intent, PendingIntent.FLAG_UPDATE_CURRENT);

        //int notification_id = nid!=null ? Integer.parseInt(nid) : MainActivity.ASWV_FCM_ID;

        int m = (int) ((new Date().getTime() / 1000L) % Integer.MAX_VALUE);
        int notification_id=m;

        Intent buttonIntent = new Intent(this, ButtonReceiver.class);
        buttonIntent.putExtra("notificationId",notification_id);

//Create the PendingIntent
        PendingIntent btPendingIntent = PendingIntent.getBroadcast(this, 0, buttonIntent,0);

        String channelId = MainActivity.asw_fcm_channel;
        Uri soundUri=Uri.parse(ContentResolver.SCHEME_ANDROID_RESOURCE + "://" + getPackageName() + "/raw/pristine");


        NotificationCompat.Action action = new NotificationCompat.Action.Builder(R.mipmap.ic_launcher, tag, pendingIntent).build();
        NotificationCompat.Action action1 = new NotificationCompat.Action.Builder(R.mipmap.ic_launcher, "Dismiss", btPendingIntent).build();

            NotificationManager notificationManager = (NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE);

NotificationCompat.Builder notificationBuilder1 = new NotificationCompat.Builder(this, MainActivity.asw_fcm_channel)
                .setSmallIcon(R.mipmap.ic_launcher)
                .setContentTitle(title)
                .setContentText(message)
                .setDefaults(Notification.DEFAULT_ALL)
                .setPriority(NotificationCompat.PRIORITY_HIGH)
                .setSound(RingtoneManager.getDefaultUri(RingtoneManager.TYPE_NOTIFICATION))
                .setAutoCancel(false)
                .addAction(action)
                .addAction(action1)
                .setVisibility(NotificationCompat.VISIBILITY_PUBLIC)
                .setVibrate(new long[]{100, 200, 300, 400, 500, 400, 300, 200, 400});


        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
            NotificationChannel mChannel = new NotificationChannel(channelId, "My Notifications", NotificationManager.IMPORTANCE_HIGH);


            AudioAttributes attributes = new AudioAttributes.Builder()
                    .setContentType(AudioAttributes.CONTENT_TYPE_SONIFICATION)
                    .setUsage(AudioAttributes.USAGE_NOTIFICATION)
                    .build();


            // Configure the notification channel.

            mChannel.setDescription("Common notifications");
            mChannel.enableLights(true);
            mChannel.setLightColor(Color.RED);
            mChannel.setSound(soundUri, attributes);
            mChannel.enableVibration(true);
            mChannel.setVibrationPattern(new long[]{0, 1000, 500, 1000});
            mChannel.setLockscreenVisibility(Notification.VISIBILITY_PUBLIC);
            notificationManager.createNotificationChannel(mChannel);

        }
        
        
            Notification noti = notificationBuilder1.build();
            noti.flags = Notification.DEFAULT_LIGHTS | Notification.DEFAULT_SOUND | Notification.DEFAULT_VIBRATE | Notification.FLAG_AUTO_CANCEL;
            notificationManager.notify(notification_id, notificationBuilder1.build());

现存问题

已经在Start按钮对应的Intent中传入notificationId参数,也编写了removeNotification方法用于取消通知,但点击Start按钮时仅会执行WebView加载URL的跳转逻辑,无法同步关闭通知。尝试过设置.setAutoCancel(true)、添加FLAG_AUTO_CANCEL通知标志位均未生效,相关代码片段如下:

Intent intent = new Intent(this, MainActivity.class);
intent.putExtra("uri", uri);
intent.putExtra("notificationId",notification_id);
intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP | Intent.FLAG_ACTIVITY_SINGLE_TOP);
PendingIntent pendingIntent = PendingIntent.getActivity(this, 0, intent, PendingIntent.FLAG_UPDATE_CURRENT);

public static void removeNotification(int notification_id) {
            try {
                if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.M) {
                    NotificationManager notificationManager = (NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE);
                    notificationManager.cancel(notification_id);
                }
            } catch (Exception e) {

            }
        }

问题原因

setAutoCancel(true)和FLAG_AUTO_CANCEL标志仅在用户点击通知主体时触发自动取消逻辑,点击通知上自定义的Action按钮时不会触发该逻辑,必须手动调用取消通知的方法。

具体实现步骤

  • 第一步:修改Start按钮的PendingIntent绑定逻辑,不要直接绑定跳转Activity的Intent,和Dismiss按钮一样先绑定广播接收器,把需要打开的URL和通知ID都传入广播Intent。注意两个按钮的PendingIntent requestCode不能重复,避免PendingIntent被覆盖。
// 替换原来Start按钮直接跳Activity的PendingIntent逻辑
Intent startBtnIntent = new Intent(this, ButtonReceiver.class);
startBtnIntent.putExtra("notificationId", notification_id);
startBtnIntent.putExtra("targetUri", uri); // 传入需要打开的URL
// 第二个参数requestCode设为1,和Dismiss按钮的0做区分
PendingIntent startPendingIntent = PendingIntent.getBroadcast(this, 1, startBtnIntent, PendingIntent.FLAG_UPDATE_CURRENT);

// 绑定到Start按钮的Action上
NotificationCompat.Action action = new NotificationCompat.Action.Builder(R.mipmap.ic_launcher, "Start", startPendingIntent).build();
  • 第二步:在ButtonReceiver的onReceive回调中,先执行取消通知的逻辑,再判断如果是Start按钮的点击事件,就手动启动MainActivity并传入URL参数。注意广播中启动Activity必须添加FLAG_ACTIVITY_NEW_TASK标志,否则会启动失败。
public class ButtonReceiver extends BroadcastReceiver {
    @Override
    public void onReceive(Context context, Intent intent) {
        // 第一步先取消对应通知
        int notificationId = intent.getIntExtra("notificationId", -1);
        if (notificationId != -1) {
            NotificationManager manager = (NotificationManager) context.getSystemService(Context.NOTIFICATION_SERVICE);
            manager.cancel(notificationId);
        }
        // 处理Start按钮的跳转逻辑
        if (intent.hasExtra("targetUri")) {
            String openUrl = intent.getStringExtra("targetUri");
            Intent activityIntent = new Intent(context, MainActivity.class);
            activityIntent.putExtra("uri", openUrl);
            activityIntent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP | Intent.FLAG_ACTIVITY_SINGLE_TOP | Intent.FLAG_ACTIVITY_NEW_TASK);
            context.startActivity(activityIntent);
        }
    }
}
  • 第三步:修正原有removeNotification方法的逻辑问题。原方法存在两个问题:一是多余的Android M版本判断,notificationManager.cancel()方法从Android 1.0版本就支持,不需要版本限制;二是静态方法中不能直接调用getSystemService,需要传入Context对象。修正后的方法如下:
public static void removeNotification(Context context, int notification_id) {
    try {
        NotificationManager notificationManager = (NotificationManager) context.getSystemService(Context.NOTIFICATION_SERVICE);
        notificationManager.cancel(notification_id);
    } catch (Exception e) {
        e.printStackTrace();
    }
}

注意事项

  • 同一条通知的多个Action按钮对应的PendingIntent必须使用不同的requestCode,否则会出现后设置的PendingIntent覆盖先设置的、按钮点击逻辑错乱的问题
  • 不要依赖自动取消标志处理Action按钮的通知关闭,所有自定义按钮点击后的通知关闭逻辑都需要手动调用cancel方法
  • 广播接收器中启动Activity必须添加FLAG_ACTIVITY_NEW_TASK窗口标志,否则会抛出异常

内容的提问来源于stack exchange,提问作者Ahamed

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.28 16:54:42