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

点击通知时避免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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.18 04:50:00