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

带全屏Intent的Heads-Up通知 Dismiss后卡在全屏模式的技术问题

解决全屏Intent Heads-Up通知被Dismiss后卡在全屏模式的问题

兄弟,这个全屏Intent通知的坑我之前踩过!结合你描述的场景和提供的MainActivity代码片段,下面给你拆解问题原因和可行的解决方案:

问题根源

当系统通过全屏Intent拉起对应的Activity后,如果用户手动Dismiss了Heads-Up通知,这个全屏Activity并不会自动感知到通知的状态变化,导致它一直停留在前台,出现“卡住”的现象。我们需要主动让Activity监听通知的删除事件,或者在生命周期中判断通知是否还存在,从而主动关闭自己。

解决方案

1. 给全屏Activity添加通知删除广播监听

注册一个广播接收器,监听系统发出的通知删除事件,当目标通知被删除时,立即关闭全屏Activity:

首先是你的MainActivity完整代码(补充了缺失的部分):

public class MainActivity extends AppCompatActivity { 
    private static final String CHANNEL = "TestChannel"; 
    public static final int NOTIFICATION_ID = 1; 
    private static final int REQUEST_CODE = 2; 
    private NotificationManager notificationManager; 

    @Override 
    protected void onCreate(Bundle savedInstanceState) { 
        super.onCreate(savedInstanceState); 
        setContentView(R.layout.activity_main); 

        // 初始化通知渠道(Android O及以上必填)
        notificationManager = (NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE);
        createNotificationChannel();
        
        // 绑定按钮点击事件
        Button showNotificationBtn = findViewById(R.id.show_notification_btn);
        showNotificationBtn.setOnClickListener(v -> showFullScreenNotification());
    }

    private void createNotificationChannel() {
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
            NotificationChannel channel = new NotificationChannel(CHANNEL, "测试通知渠道", NotificationManager.IMPORTANCE_HIGH);
            channel.setDescription("用于测试全屏Intent通知的渠道");
            notificationManager.createNotificationChannel(channel);
        }
    }

    private void showFullScreenNotification() {
        // 全屏Intent目标Activity
        Intent fullScreenIntent = new Intent(this, FullScreenActivity.class);
        // 注意API31+需要设置IMMUTABLE/MUTABLE flag
        PendingIntent fullScreenPendingIntent = PendingIntent.getActivity(
                this, 
                REQUEST_CODE, 
                fullScreenIntent, 
                PendingIntent.FLAG_UPDATE_CURRENT | PendingIntent.FLAG_IMMUTABLE);

        NotificationCompat.Builder builder = new NotificationCompat.Builder(this, CHANNEL)
                .setSmallIcon(R.drawable.ic_notification)
                .setContentTitle("全屏通知")
                .setContentText("点击或自动进入全屏页面")
                .setPriority(NotificationCompat.PRIORITY_HIGH)
                .setCategory(NotificationCompat.CATEGORY_ALARM) // 高优先级分类,确保Heads-Up展示
                .setFullScreenIntent(fullScreenPendingIntent, true);

        notificationManager.notify(NOTIFICATION_ID, builder.build());
    }
}

然后是全屏FullScreenActivity的处理代码:

public class FullScreenActivity extends AppCompatActivity {

    private BroadcastReceiver notificationDeleteReceiver;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_full_screen);
        
        // 注册通知删除广播接收器
        notificationDeleteReceiver = new BroadcastReceiver() {
            @Override
            public void onReceive(Context context, Intent intent) {
                // 获取被删除的通知ID
                String deletedNotificationId = intent.getStringExtra(NotificationManager.EXTRA_NOTIFICATION_ID);
                if (deletedNotificationId != null && Integer.parseInt(deletedNotificationId) == MainActivity.NOTIFICATION_ID) {
                    // 目标通知被删除,关闭当前全屏Activity
                    finish();
                }
            }
        };
        IntentFilter filter = new IntentFilter(NotificationManager.ACTION_NOTIFICATION_DELETED);
        registerReceiver(notificationDeleteReceiver, filter);
    }

    @Override
    protected void onDestroy() {
        super.onDestroy();
        // 记得注销广播接收器,避免内存泄漏
        if (notificationDeleteReceiver != null) {
            unregisterReceiver(notificationDeleteReceiver);
        }
    }
}

2. 额外保险:在Activity生命周期中检查通知状态

除了广播监听,还可以在onPause或onStop方法中主动检查目标通知是否还处于活跃状态,如果已经被删除,则关闭Activity:

@Override
protected void onPause() {
    super.onPause();
    NotificationManager notificationManager = (NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE);
    StatusBarNotification[] activeNotifications = notificationManager.getActiveNotifications();
    boolean isTargetNotificationActive = false;
    
    for (StatusBarNotification sbn : activeNotifications) {
        if (sbn.getId() == MainActivity.NOTIFICATION_ID) {
            isTargetNotificationActive = true;
            break;
        }
    }
    
    if (!isTargetNotificationActive) {
        finish();
    }
}

关键注意点

  • Android 12及以上版本,PendingIntent必须设置FLAG_IMMUTABLE或FLAG_MUTABLE,根据你的需求选择(如果不需要修改Intent内容,用IMMUTABLE更安全)。
  • 确保通知渠道的优先级设置为IMPORTANCE_HIGH,否则Heads-Up通知可能无法正常展示。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.25 06:47:04