带全屏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
相关产品推荐
相关产品推荐

