最近公司的 app 有个风险安全整改的需求,要求 app 在任务列表的时候展示要进行高斯模糊,效果如下图所示:

 

一开始看到自己手机上(Redmi K20)的银行类 APP 都实现了这样的效果,觉得应该是可以实现的,就开始百度查相关的实现方法。但是基本上百度出来的99%都是 ios 的实现方式,安卓的几乎没有,下面是我唯一找到的两篇跟安卓相关的文章。

1、https://blog.csdn.net/henkun/article/details/102763654

2、https://blog.csdn.net/f0ed9czn4ly992g/article/details/80970691

二话不说先照着第一篇博客写个 demo 验证一下(其他代码都跟第一篇博客里的一样,下面我只贴我做了改动的代码,增加了一行我在自己手机上监听到的广播)

public class DeviceKeyMonitor {

    private static final String SYSTEM_REASON = "reason";
    private static final String SYSTEM_HOME_RECENT_APPS = "recentapps";

    private Context mContext;
    private BroadcastReceiver mDeviceKeyReceiver = null;
    private OnKeyListener mListener;

    public DeviceKeyMonitor(Context context, final OnKeyListener listener) {
        mContext = context;
        mListener = listener;
        mDeviceKeyReceiver = new BroadcastReceiver() {
            @Override
            public void onReceive(Context context, Intent intent) {
                String action=intent.getAction();
                if(!TextUtils.isEmpty(action)){

                    if (intent.getAction().equals(Intent.ACTION_CLOSE_SYSTEM_DIALOGS)) {
                        String reason = intent.getStringExtra(SYSTEM_REASON);

                        if (reason == null)
                            return;
                        Log.e("reason", reason);
                        // 最近任务列表键+RedMi K20 手势划出到任务列表的广播
                        if (reason.equals(SYSTEM_HOME_RECENT_APPS) || reason.equals("fs_gesture")) {
                            mListener.onRecentClick();
                        }
                    }
                }
            }
        };
        mContext.registerReceiver(mDeviceKeyReceiver, new IntentFilter(Intent.ACTION_CLOSE_SYSTEM_DIALOGS));
    }

    public interface OnKeyListener{
        void onRecentClick();//多任务键监听
    }

    public void unregister(){
        if (mDeviceKeyReceiver != null){
            mContext.unregisterReceiver(mDeviceKeyReceiver);
            mDeviceKeyReceiver = null;

        }
    }

}

总结:

1、模仿第一篇博客里的代码并没有能实现任务列表将 app 高斯模糊的效果。在使用有实体按键的手机调试时,确实在按下任务列表按键的时候可以接收到 “recentapps”的广播,实现高斯模糊的代码也确实执行了,但是效果并没有出来。

2、查阅资料是说安卓任务列表是系统对 app 当前页面进行截图然后再显示的,才呈现出我们在手机上看到的任务列表的效果,所以我猜测是不是我接收到广播后进行高斯模糊的时机已经在系统的截图操作之后了,所以才没有出效果。

3、在全屏手机(不显示虚拟键,使用手势操作)上, 通过手势退出 APP 到任务列表时,是捕捉不到 ”recentapps“ 这个广播的。但是我在自己手机(Redmi K20)上退出到任务列表时,捕捉到另外一个广播 “fs_gesture”,(参照上述代码)当捕捉到这个广播时,使用第一篇博客里那一套代码是可以实现我们想要的效果的。(有兴趣的朋友可以找相同机型试一下)但是遗憾的是只在我自己手机可以,在其他手机上就捕捉不到相同的广播了,甚至其实是捕捉不到广播了,猜测每个手机厂商实现退出任务列表的机制不一样。所以如果通过这样子去适配不同机型的手机,也是不现实的。

4、后面又看了一下其他银行 APP 在不同手机上的实现效果,发现主流的银行 APP (农业银行、建设银行之类的)在有些手机上也并没有实现我们所说的高斯模糊的效果,包括在华为的手机、三星的手机上面。

5、这个时候第二篇博客的观点我其实比较能接受,就是这种高斯模糊的效果其实是手机厂商实现的,具体实现机制可能是app名称涉及支付、或者特定包名之类的。这样也可以解释同一款 app 在不同手机上的实现情况。

6、最后我采用了第二篇博客提到的其中一种替代方案,就是在 Activity 中去设置这样一个安全属性:getWindow().setFlags(WindowManager.LayoutParams.FLAG_SECURE, WindowManager.LayoutParams.FLAG_SECURE),这样在 app 退出到任务列表时页面会显示白屏,也达到了安全的目的,只是这个方案有两个比较明显的缺点:

(1)白屏其实很难看,只是要在安全和好看之间做一个取舍

(2)设置这个属性之后会连带一个防截屏的功能,app 也不能截屏了

最后的最后,如果有大牛知道如何实现最初提到的效果的话,希望您不吝赐教!!!

Logo

为开发者提供学习成长、分享交流、生态实践、资源工具等服务,帮助开发者快速成长。

更多推荐