点击通知时避免MyActivity重复启动的问题求助
解决方案
要实现你需要的三个通知点击行为,需要从Activity启动模式配置和动态判断前台状态两方面调整:
1. 配置Activity启动模式
在AndroidManifest.xml中给MyActivity设置launchMode="singleTop",确保当Activity已存在时不会重复创建,而是复用实例:
<activity android:name=".MyActivity" android:launchMode="singleTop"> <!-- 其他原有配置 --> </activity>
2. 调整通知构建逻辑
添加判断当前MyActivity是否处于前台的工具方法,然后根据状态设置不同的PendingIntent:
第一步:实现前台状态判断方法
在你的通知构建类中添加以下方法(Android 11及以上需改用UsageStatsManager,低版本用ActivityManager):
private boolean isMyActivityForeground() { if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.R) { UsageStatsManager usageStatsManager = (UsageStatsManager) getSystemService(Context.USAGE_STATS_SERVICE); long endTime = System.currentTimeMillis(); long startTime = endTime - 1000 * 60; // 检查最近1分钟的应用使用情况 List<UsageStats> usageStatsList = usageStatsManager.queryUsageStats(UsageStatsManager.INTERVAL_BEST, startTime, endTime); if (usageStatsList != null && !usageStatsList.isEmpty()) { UsageStats latestStats = Collections.max(usageStatsList, Comparator.comparingLong(UsageStats::getLastTimeUsed)); return latestStats.getPackageName().equals(getPackageName()); } } else { ActivityManager activityManager = (ActivityManager) getSystemService(Context.ACTIVITY_SERVICE); List<ActivityManager.RunningTaskInfo> tasks = activityManager.getRunningTasks(1); if (!tasks.isEmpty()) { ComponentName topActivity = tasks.get(0).topActivity; return topActivity.getClassName().equals(MyActivity.class.getName()); } } return false; }
第二步:修改通知构建代码
根据前台状态决定PendingIntent内容:前台时用空Intent实现无操作,后台/未启动时用唤起Activity的Intent:
private Notification buildNotification() { Notification.Builder builder; if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) { builder = new Notification.Builder(this, CHANNEL_ID); } else { builder = new Notification.Builder(this); } PendingIntent pendingIntent; if (isMyActivityForeground()) { // 前台时点击通知无操作,使用空Intent的PendingIntent pendingIntent = PendingIntent.getActivity(this, 0, new Intent(), PendingIntent.FLAG_IMMUTABLE); } else { Intent intent = new Intent(this, MyActivity.class); // 保留必要Flag,确保后台唤起或首次启动时复用实例 intent.addFlags(Intent.FLAG_ACTIVITY_SINGLE_TOP | Intent.FLAG_ACTIVITY_NEW_TASK); pendingIntent = PendingIntent.getActivity(this, 0, intent, PendingIntent.FLAG_UPDATE_CURRENT | PendingIntent.FLAG_IMMUTABLE); } builder.setContentTitle(StringUtils.getString(R.string.app_name)) .setContentText(StringUtils.getString(R.string.app_is_running)) .setSmallIcon(R.mipmap.ic_launcher_foreground) .setPriority(Notification.PRIORITY_HIGH) .setOnlyAlertOnce(false) .setAutoCancel(false) .setContentIntent(pendingIntent); return builder.build(); }
3. 后台唤起后的补充处理(可选)
如果需要确保后台唤起时Activity直接回到前台,可以在MyActivity中重写onNewIntent方法:
@Override protected void onNewIntent(Intent intent) { super.onNewIntent(intent); moveTaskToFront(getTaskId(), 0); }
关键调整说明
- 移除
Intent.FLAG_ACTIVITY_CLEAR_TOP:该Flag会清除任务栈中目标Activity之上的所有页面并可能重新创建实例,不符合"唤起而非重启"的需求。 - 动态判断前台状态:精准区分三种场景的处理逻辑,避免前台点击通知时的无效页面切换。
内容的提问来源于stack exchange,提问作者user7954210
相关产品推荐
相关产品推荐

