技术标签: 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
1. 将整数转换成IP:思路:将整数转换成无符号32位的二进制,再8位进行分割,每8位转换成十进制即可。方法一:#!usr/bin/python 2 #encoding=utf-8 3 #1. 将整数转换成32位无符号二进制 4 def intToIp(num): 5 s = [] 6 g = [] 7 ...
Access method(访问方法):此步骤包括从文件中存储和检索记录。 Alias(别名):某属性的另一个名字。在SQL中,可以用别名替换表名。 Alternate keys(备用键,ER/关系模型):在实体/表中没有被选为主健的候选键。 Anomalies(异常)参见更新异常(update anomalies) Application design(应用程序设计):数据库应用程序生命周期的一...
来源:硅谷分析狮8月10日消息,在昨天的开发者大会上,华为正式公布了鸿蒙系统,而现在官方给出新的公告称,全球首款搭载鸿蒙系统的终端将在今天下午14点正式发布,而它就是荣耀智慧屏。对于鸿蒙系统,余承东表示,会逐步应用在可穿戴、智慧屏、车机等更多智能设备中,当然智能手机上也是可以的,目前相应的测试已经完成。首款鸿蒙系统终端之前,荣耀智慧屏的不少卖点已经被官方宣布,比如配备了升降摄像头、取消开机广告等等...
一、U盘安装步骤(推荐用这种方法)使用到的材料: 1、CentOS-6.3-x86_64-bin-DVD1.iso 2、UltraISO 3、U盘一个开始安装: 注意:使用UltraISO制作U盘启动的时候,必须在那个需要安装系统的电脑上面制作,如果你在A电脑上制作了,然后跑到B电脑上安装的时候会报一个错,这个貌似是CentOS系统的一个BUG,估计要后面的版本会改...
【石油大学】计算机网络原理(含模拟实验)-第一次在线作业试卷总分: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和BSD系统的软件最常见;在国内源可见的软件几乎绝迹;大多开源软件都是国外出品;在国内较为出名的开源软件有fcitx;lumaqq;Lumaqq及scim等;但软件的源代码可见并不等于软件是开源的,我们还要以软件的许可为准;比如有些软件是源码可见的,但他约定用户只能按他约定的内容来修改;比如vbb论坛程序;所以一个软件是否是开源软件,
体系Activity -> phoneWindow ->DecorView -> 各ViewGroup等1.DecorView(FrameLayout)包含StateView、TitileView、ContentView 等子View ,setContentView 设置的是DecorView子View。2.Activity 托管 phoneWindow实例对象,ph...
POP3 POP3是Post Office Protocol 3的简称,即邮局协议的第3个版本,它规定怎样将个人计算机连接到Internet的邮件服务器和下载电子邮件的电子协议。它是因特网电子邮件的第一个离线协议标准,POP3允许用户从服务器上把邮件存储到本地主机(即自己的计算机)上,同时删除保存在邮件服务器上的邮件,而POP3服务器则是遵循POP3协议的接收邮件服务器,用来接收
一.安装三个依赖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
1、ng-model 这个大家都非常熟悉了,就是将表单控件和当前作用域的属性进行绑定。需要注意绑定的scope的范围(父scope与子scope)。 ng-model主要绑定的元素包括input, select, textarea ng-model的元素都有ng-valid(可用),ng-invalid 不可用 ng-pristine(用户为对这个元素进行操作过), ng-dirty(元素
PackageName.h得到各種文件的擴展名GetTextMapPackageExtension)GetTextAssetPackageExtension()GetAssetPackageExtension()GetMapPackageExtension() Paths.cpp 得到各種路徑RootDir()ProjectDir()Pr...
unicode -> 中文public String unicodeToGbk(String unicodeText) { Pattern p = Pattern.compile("[u][\\w]{4}"); Matcher m = p.matcher(unicodeText); StringBuilder sbu = new StringBuilder(); wh