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

Android应用进入最近任务列表时模糊显示的实现方案咨询

实现方案:应用内允许截图 + 最近任务列表模糊显示

以下是针对需求的几种可行实现方案,覆盖不同场景和兼容性需求:

方案一:利用窗口可见性变化监听(推荐)

重写Activity的onWindowVisibilityChanged方法,该方法会在窗口可见性发生变化时触发(包括进入最近任务列表的场景,无论Activity是否处于resumed状态),精准控制FLAG_SECURE的添加与移除。

@Override
public void onWindowVisibilityChanged(int visibility) {
    super.onWindowVisibilityChanged(visibility);
    if (visibility == View.INVISIBLE) {
        // 进入最近任务列表,开启模糊保护
        getWindow().setFlags(WindowManager.LayoutParams.FLAG_SECURE, 
                            WindowManager.LayoutParams.FLAG_SECURE);
    } else if (visibility == View.VISIBLE) {
        // 返回应用,移除保护以允许截图
        getWindow().clearFlags(WindowManager.LayoutParams.FLAG_SECURE);
    }
}

这个方案是系统级实现,性能最优,且能覆盖所有进入最近任务的场景。

方案二:全局应用生命周期监听(多Activity场景)

如果应用包含多个Activity,可以通过ProcessLifecycleOwner统一监听应用前后台状态,批量控制所有Activity的窗口保护。

首先在Application类中初始化监听:

@Override
public void onCreate() {
    super.onCreate();
    ProcessLifecycleOwner.get().getLifecycle().addObserver(new LifecycleEventObserver() {
        @Override
        public void onStateChanged(@NonNull LifecycleOwner source, @NonNull Lifecycle.Event event) {
            if (event == Lifecycle.Event.ON_STOP) {
                // 应用进入后台,为所有存活Activity设置FLAG_SECURE
                for (Activity activity : ActivityCollector.getActivities()) {
                    if (activity.getWindow() != null) {
                        activity.getWindow().setFlags(WindowManager.LayoutParams.FLAG_SECURE,
                                                    WindowManager.LayoutParams.FLAG_SECURE);
                    }
                }
            } else if (event == Lifecycle.Event.ON_START) {
                // 应用回到前台,移除所有Activity的FLAG_SECURE
                for (Activity activity : ActivityCollector.getActivities()) {
                    if (activity.getWindow() != null) {
                        activity.getWindow().clearFlags(WindowManager.LayoutParams.FLAG_SECURE);
                    }
                }
            }
        }
    });
}

需要配合一个Activity管理类ActivityCollector,用来跟踪所有Activity实例:

public class ActivityCollector {
    private static final List<Activity> ACTIVITIES = new ArrayList<>();

    public static void addActivity(Activity activity) {
        ACTIVITIES.add(activity);
    }

    public static void removeActivity(Activity activity) {
        ACTIVITIES.remove(activity);
    }

    public static List<Activity> getActivities() {
        return new ArrayList<>(ACTIVITIES);
    }
}

在每个Activity的onCreate中调用ActivityCollector.addActivity(this),onDestroy中调用ActivityCollector.removeActivity(this)即可。

方案三:自定义模糊遮罩层(兼容特殊设备)

如果部分厂商设备对FLAG_SECURE支持不佳,可以通过自定义全屏模糊遮罩的方式实现。核心逻辑是在应用进入后台时,显示覆盖整个窗口的模糊视图。

示例代码:

private View blurOverlay;

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);
    blurOverlay = findViewById(R.id.blur_overlay);
    blurOverlay.setVisibility(View.GONE);
}

@Override
public void onWindowVisibilityChanged(int visibility) {
    super.onWindowVisibilityChanged(visibility);
    if (visibility == View.INVISIBLE) {
        blurOverlay.setVisibility(View.VISIBLE);
        // 截取当前界面并模糊后设置为遮罩背景
        Bitmap screenshot = captureScreen();
        Bitmap blurredBitmap = blurImage(screenshot, this);
        ((ImageView) blurOverlay).setImageBitmap(blurredBitmap);
    } else {
        blurOverlay.setVisibility(View.GONE);
    }
}

// 截取当前界面
private Bitmap captureScreen() {
    View rootView = getWindow().getDecorView().getRootView();
    rootView.setDrawingCacheEnabled(true);
    Bitmap bitmap = Bitmap.createBitmap(rootView.getDrawingCache());
    rootView.setDrawingCacheEnabled(false);
    return bitmap;
}

// 模糊处理图片(使用RenderScript)
private Bitmap blurImage(Bitmap bitmap, Context context) {
    RenderScript rs = RenderScript.create(context);
    Allocation input = Allocation.createFromBitmap(rs, bitmap);
    Allocation output = Allocation.createTyped(rs, input.getType());
    ScriptIntrinsicBlur blurScript = ScriptIntrinsicBlur.create(rs, Element.U8_4(rs));
    blurScript.setRadius(18f);
    blurScript.setInput(input);
    blurScript.forEach(output);
    output.copyTo(bitmap);
    rs.destroy();
    return bitmap;
}

布局中需要添加一个全屏的ImageView作为遮罩:

<ImageView
    android:id="@+id/blur_overlay"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:scaleType="centerCrop"
    android:visibility="gone"/>

注意事项

  • 兼容性测试:部分厂商对FLAG_SECURE的实现有差异,需在目标设备上验证效果。
  • 多窗口适配:若应用支持多窗口模式,需额外处理窗口大小变化时的可见性逻辑。
  • 性能优化:自定义模糊方案需注意Bitmap的内存回收,避免内存泄漏。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.20 03:53:18