Android 剪切板敏感信息泄露漏洞解决:禁用EditText的复制粘贴功能_IT酷盖的博客-程序员秘密

技术标签: EditText  个人笔记  android  禁用EditText复制粘贴  

Android 中任何第三方软件都可访问剪切板内容,虽然高版本对剪切板做了访问限制,但是还是需要照顾一下低版本的,解决方法就是要禁用复制剪切选项。下边来看具体实现吧。

1、自定义NoMenuEditText 继承自AppCompatEditText

2、重写isSuggestionsEnabled方法并返回false

     创建canPaste()方法并返回false。该方法是一个隐藏方法

3、实现ActionMode.Callback回调

 private class ActionModeCallbackInterceptor implements ActionMode.Callback {

        public boolean onCreateActionMode(ActionMode mode, Menu menu) {
            //删除复制选项
            MenuItem itemCopy = menu.findItem(android.R.id.copy);
            if (itemCopy != null) {
                menu.removeItem(android.R.id.copy);
            }
            //删除剪切选项
            MenuItem itemCut = menu.findItem(android.R.id.cut);
            if (itemCut != null) {
                menu.removeItem(android.R.id.cut);
            }
            return true;
        }

        public boolean onPrepareActionMode(ActionMode mode, Menu menu) {
            return false;
        }

        public boolean onActionItemClicked(ActionMode mode, MenuItem item) {
            return false;
        }

        public void onDestroyActionMode(ActionMode mode) {
        }
    }

4、设置回调

      this.setLongClickable(false);
        //this.setTextIsSelectable(false);
        this.setCustomSelectionActionModeCallback(new ActionModeCallbackInterceptor());
        //使用该方式基本可以实现禁用粘贴复制功能,6.0以上可用
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
            this.setCustomInsertionActionModeCallback(new ActionModeCallbackInterceptor());
        }

使用以上方式即可禁用掉EditText的复制粘贴功能,但是长按EditTeit控件中的文本时光标会有变化,并且该方式只能在6.0以上版本中使用。如果以上方式不能满足你的需求,请看以下方式:

1、2、3步同上,修改第4步不再用 this.setCustomInsertionActionModeCallback(new ActionModeCallbackInterceptor())方法。

使用以下方式(反射)代替:

 this.setOnTouchListener(new OnTouchListener() {
            @Override
            public boolean onTouch(View v, MotionEvent event) {
                NoMenuEditText.this.clearFocus();
                return false;
            }
        });
@SuppressLint("ClickableViewAccessibility")
    @Override
    public boolean onTouchEvent(MotionEvent event) {
        if (event.getAction() == MotionEvent.ACTION_DOWN) {
            // setInsertionDisabled when user touches the view
            this.setInsertionDisabled();
        }
        return super.onTouchEvent(event);
    }

    private void setInsertionDisabled() {
        try {
            Field editorField = TextView.class.getDeclaredField("mEditor");
            editorField.setAccessible(true);
            Object editorObject = editorField.get(this);

            @SuppressLint("PrivateApi") Class editorClass = Class.forName("android.widget.Editor");
            Field mInsertionControllerEnabledField = editorClass.getDeclaredField("mInsertionControllerEnabled");
            mInsertionControllerEnabledField.setAccessible(true);
            mInsertionControllerEnabledField.set(editorObject, false);
        } catch (Exception ignored) {
        }
    }

使用这种方式即可解决第一种方式的版本兼容问题,并且长按EditText控件中的文本光标也不会有任何变化,完美解决剪切板敏感信息泄露问题。希望以上方案对你有所帮助。

完整代码(别忘了点个赞哦):

@SuppressLint("NewApi")
public class NoMenuEditText extends AppCompatEditText {
    private final Context context;

    /**
     * 该方法为隐藏方法
     */
    boolean canPaste() {
        return false;
    }

    @Override
    public boolean isSuggestionsEnabled() {
        return false;
    }

    public NoMenuEditText(Context context) {
        super(context);
        this.context = context;
        init();
    }

    public NoMenuEditText(Context context, AttributeSet attrs) {
        super(context, attrs);
        this.context = context;
        init();
    }

    public NoMenuEditText(Context context, AttributeSet attrs, int defStyle) {
        super(context, attrs, defStyle);
        this.context = context;
        init();
    }

    @SuppressLint("ClickableViewAccessibility")
    private void init() {
        this.setLongClickable(false);
        //this.setTextIsSelectable(false);
        this.setCustomSelectionActionModeCallback(new ActionModeCallbackInterceptor());
        //使用该方式基本可以实现禁用粘贴复制功能,6.0以上可用
//        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
//            this.setCustomInsertionActionModeCallback(new ActionModeCallbackInterceptor());
//        }
        this.setOnTouchListener(new OnTouchListener() {
            @Override
            public boolean onTouch(View v, MotionEvent event) {
                NoMenuEditText.this.clearFocus();
                return false;
            }
        });
    }

    @SuppressLint("ClickableViewAccessibility")
    @Override
    public boolean onTouchEvent(MotionEvent event) {
        if (event.getAction() == MotionEvent.ACTION_DOWN) {
            // setInsertionDisabled when user touches the view
            this.setInsertionDisabled();
        }
        return super.onTouchEvent(event);
    }

    private void setInsertionDisabled() {
        try {
            Field editorField = TextView.class.getDeclaredField("mEditor");
            editorField.setAccessible(true);
            Object editorObject = editorField.get(this);

            @SuppressLint("PrivateApi") Class editorClass = Class.forName("android.widget.Editor");
            Field mInsertionControllerEnabledField = editorClass.getDeclaredField("mInsertionControllerEnabled");
            mInsertionControllerEnabledField.setAccessible(true);
            mInsertionControllerEnabledField.set(editorObject, false);
        } catch (Exception ignored) {
        }
    }

    /**
     * Prevents the action bar (top horizontal bar with cut,copy,paste,etc.)
     * from appearing by intercepting the callback that would cause it to be
     * created,and returning false.
     */
    private class ActionModeCallbackInterceptor implements ActionMode.Callback {

        public boolean onCreateActionMode(ActionMode mode, Menu menu) {
            //删除复制选项
            MenuItem itemCopy = menu.findItem(android.R.id.copy);
            if (itemCopy != null) {
                menu.removeItem(android.R.id.copy);
            }
            //删除剪切选项
            MenuItem itemCut = menu.findItem(android.R.id.cut);
            if (itemCut != null) {
                menu.removeItem(android.R.id.cut);
            }
            return true;
        }

        public boolean onPrepareActionMode(ActionMode mode, Menu menu) {
            return false;
        }

        public boolean onActionItemClicked(ActionMode mode, MenuItem item) {
            return false;
        }

        public void onDestroyActionMode(ActionMode mode) {
        }
    }
}

参考:https://stackoverflow.com/questions/41673185/disable-edittext-context-menu

版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
本文链接:https://blog.csdn.net/c_furong/article/details/107034827

智能推荐

Python—IP地址与整数之间的转换_weixin_30699443的博客-程序员秘密

1. 将整数转换成IP:思路:将整数转换成无符号32位的二进制,再8位进行分割,每8位转换成十进制即可。方法一:#!usr/bin/python 2 #encoding=utf-8 3 #1. 将整数转换成32位无符号二进制 4 def intToIp(num): 5 s = [] 6 g = [] 7 ...

数据库设计中的英文术语表_数据库英文术语_大强012的博客-程序员秘密

Access method(访问方法):此步骤包括从文件中存储和检索记录。 Alias(别名):某属性的另一个名字。在SQL中,可以用别名替换表名。 Alternate keys(备用键,ER/关系模型):在实体/表中没有被选为主健的候选键。 Anomalies(异常)参见更新异常(update anomalies) Application design(应用程序设计):数据库应用程序生命周期的一...

首款鸿蒙系统终端1,首款搭载鸿蒙系统的华为终端今日亮相_带刀侍卫杨晁跃的博客-程序员秘密

来源:硅谷分析狮8月10日消息,在昨天的开发者大会上,华为正式公布了鸿蒙系统,而现在官方给出新的公告称,全球首款搭载鸿蒙系统的终端将在今天下午14点正式发布,而它就是荣耀智慧屏。对于鸿蒙系统,余承东表示,会逐步应用在可穿戴、智慧屏、车机等更多智能设备中,当然智能手机上也是可以的,目前相应的测试已经完成。首款鸿蒙系统终端之前,荣耀智慧屏的不少卖点已经被官方宣布,比如配备了升降摄像头、取消开机广告等等...

【转载】Linux(CentOS6.3)三种安装方法(U盘,硬盘,光盘)_BlueSkyCjm的博客-程序员秘密

一、U盘安装步骤(推荐用这种方法)使用到的材料:  1、CentOS-6.3-x86_64-bin-DVD1.iso  2、UltraISO  3、U盘一个开始安装:  注意:使用UltraISO制作U盘启动的时候,必须在那个需要安装系统的电脑上面制作,如果你在A电脑上制作了,然后跑到B电脑上安装的时候会报一个错,这个貌似是CentOS系统的一个BUG,估计要后面的版本会改...

计算机网络原理实验8,【石油大学】计算机网络原理(含模拟实验)-第一次在线作业试卷总分:100得分:100第1题,1.(2.5分)在OSI模型中,提供路由选择功能的层次是__________A、物理层..._鲜柚游戏的博客-程序员秘密

【石油大学】计算机网络原理(含模拟实验)-第一次在线作业试卷总分:100 得分:100第1题,1.(2.5分)在OSI模型中,提供路由选择功能的层次是__________A、物理层B、应用层C、数据链路层D、网络层正确答案:第2题,2.(2.5分)以下没有采用存储转发机制的交换方式有()A、电路交换B、报文交换C、分组交换D、信元交换正确答案:第3题,3.(2.5分)Internet最早起源...

linux下源码包安装_fcitx-3.2-050827.tar.bz2_可人冰凌的博客-程序员秘密

顾名思义,源码包就是源代码的可见的软件包,基于Linux和BSD系统的软件最常见;在国内源可见的软件几乎绝迹;大多开源软件都是国外出品;在国内较为出名的开源软件有fcitx;lumaqq;Lumaqq及scim等;但软件的源代码可见并不等于软件是开源的,我们还要以软件的许可为准;比如有些软件是源码可见的,但他约定用户只能按他约定的内容来修改;比如vbb论坛程序;所以一个软件是否是开源软件,

随便推点

View(1) - 绘制原理_四夕口鸟的博客-程序员秘密

体系Activity -> phoneWindow ->DecorView -> 各ViewGroup等1.DecorView(FrameLayout)包含StateView、TitileView、ContentView 等子View ,setContentView 设置的是DecorView子View。2.Activity 托管 phoneWindow实例对象,ph...

POP3、SMTP和IMAP_流浪的侠客的博客-程序员秘密

POP3      POP3是Post Office Protocol 3的简称,即邮局协议的第3个版本,它规定怎样将个人计算机连接到Internet的邮件服务器和下载电子邮件的电子协议。它是因特网电子邮件的第一个离线协议标准,POP3允许用户从服务器上把邮件存储到本地主机(即自己的计算机)上,同时删除保存在邮件服务器上的邮件,而POP3服务器则是遵循POP3协议的接收邮件服务器,用来接收

vue导出excel表格_无名之辈程序媛的博客-程序员秘密

一.安装三个依赖npm install -S file-saver npm insall -S xlsxnpm install -D script-loader二.在src文件夹下新建excel文件夹,后在excel文件夹下新建Bolb.js和Export2Excel.jsBolb.js文件如下代码:(function (view) { "use strict"; view.URL = view.URL || view.webkitURL; if (vie

AngularJs内置指令大全_fenxinzi557的博客-程序员秘密

1、ng-model 这个大家都非常熟悉了,就是将表单控件和当前作用域的属性进行绑定。需要注意绑定的scope的范围(父scope与子scope)。 ng-model主要绑定的元素包括input, select, textarea ng-model的元素都有ng-valid(可用),ng-invalid 不可用 ng-pristine(用户为对这个元素进行操作过), ng-dirty(元素

[UE4]一些常用UE4方法_fsha1::hashbuffer_Jerico.Gu的博客-程序员秘密

PackageName.h得到各種文件的擴展名GetTextMapPackageExtension)GetTextAssetPackageExtension()GetAssetPackageExtension()GetMapPackageExtension()   Paths.cpp 得到各種路徑RootDir()ProjectDir()Pr...

java unicode编码 中文 转换_积跬步方以至千里的博客-程序员秘密

unicode -> 中文public String unicodeToGbk(String unicodeText) { Pattern p = Pattern.compile("[u][\\w]{4}"); Matcher m = p.matcher(unicodeText); StringBuilder sbu = new StringBuilder(); wh

推荐文章

热门文章

相关标签