如何禁用从/到 EditText 的复制/粘贴

在我的应用程序中,有一个注册屏幕,我不希望用户能够复制/粘贴文本到 EditText字段。我已经在每个 EditText上设置了一个 onLongClickListener,这样就不会显示显示拷贝/粘贴/inputmethod 和其他选项的上下文菜单。因此,用户将无法复制/粘贴到 Edit 字段中。

 OnLongClickListener mOnLongClickListener = new OnLongClickListener() {


@Override
public boolean onLongClick(View v) {
// prevent context menu from being popped up, so that user
// cannot copy/paste from/into any EditText fields.
return true;
}
};

但是,如果用户启用了 Android 默认设置以外的第三方键盘,可能会出现问题,因为它可能有一个复制/粘贴按钮,或者显示相同的上下文菜单。那么在这种情况下我该如何禁用复制/粘贴呢?

如果还有其他复制/粘贴的方法,请告诉我(可能还有禁用它们的方法)

如果你能帮忙,我将不胜感激。

129845 次浏览

阅读剪贴板,检查输入和输入“键入”的时间。如果剪贴板具有相同的文本且速度太快,请删除粘贴的输入。

与 GnrlKnowledge 类似,您可以清除剪贴板

Http://developer.android.com/reference/android/text/clipboardmanager.html

如果需要,可以保留剪贴板中的文本,在 onDestroy 上,可以重新设置它。

我发现,当您创建一个输入过滤器以避免输入不需要的字符时,将这些字符粘贴到编辑文本中是没有效果的。这也解决了我的问题。

我可以通过以下方式禁用复制粘贴功能:

textField.setCustomSelectionActionModeCallback(new ActionMode.Callback() {


public boolean onCreateActionMode(ActionMode actionMode, Menu menu) {
return false;
}


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


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


public void onDestroyActionMode(ActionMode actionMode) {
}
});


textField.setLongClickable(false);
textField.setTextIsSelectable(false);

希望对你有用; -)

如果您使用的是 API 级别11或更高,那么您可以停止复制、粘贴、剪切和自定义上下文菜单出现在。

edittext.setCustomSelectionActionModeCallback(new ActionMode.Callback() {


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


public void onDestroyActionMode(ActionMode mode) {
}


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


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

从 onCreateActionMode (ActionMode,Menu)返回 false 将阻止操作模式启动(选择所有、剪切、复制和粘贴操作)。

@ Zain Ali 你的答案在 API 11上有效。我只是想建议一种方法,做在 API 10以及。因为我必须在那个版本上维护我的项目 API,所以我一直在使用2.3.3中可用的函数,并得到了这样做的可能性。我已经分享了下面的片段。我测试了代码,它对我很有用。我做了这个片段的紧急情况。如果可以进行任何更改,请随意改进代码。.

// A custom TouchListener is being implemented which will clear out the focus
// and gain the focus for the EditText, in few milliseconds so the selection
// will be cleared and hence the copy paste option wil not pop up.
// the respective EditText should be set with this listener
// tmpEditText.setOnTouchListener(new MyTouchListener(tmpEditText, tmpImm));


public class MyTouchListener implements View.OnTouchListener {


long click = 0;
EditText mEtView;
InputMethodManager imm;


public MyTouchListener(EditText etView, InputMethodManager im) {
mEtView = etView;
imm = im;
}


@Override
public boolean onTouch(View v, MotionEvent event) {


if (event.getAction() == MotionEvent.ACTION_DOWN) {
long curr = System.currentTimeMillis();
if (click !=0 && ( curr - click) < 30) {


mEtView.setSelected(false);
new Handler().postDelayed(new Runnable() {
@Override
public void run() {
mEtView.setSelected(true);
mEtView.requestFocusFromTouch();
imm.showSoftInput(mEtView, InputMethodManager.RESULT_SHOWN);
}
},25);


return true;
}
else {
if (click == 0)
click = curr;
else
click = 0;
new Handler().postDelayed(new Runnable() {
@Override
public void run() {
mEtView.requestFocusFromTouch();
mEtView.requestFocusFromTouch();
imm.showSoftInput(mEtView, InputMethodManager.RESULT_SHOWN);
}
},25);
return true;
}


} else if (event.getAction() == MotionEvent.ACTION_MOVE) {
mEtView.setSelected(false);
new Handler().postDelayed(new Runnable() {
@Override
public void run() {
mEtView.setSelected(true);
mEtView.requestFocusFromTouch();
mEtView.requestFocusFromTouch();
imm.showSoftInput(mEtView, InputMethodManager.RESULT_SHOWN);
}
},25);
return true;
}
return false;
}

最好的方法是:

etUsername.setLongClickable(false);

Https://github.com/neopixl/pixlui EditText提供了一种方法

myEditText.disableCopyAndPaste().

它在旧的 API 上运行正常

这里有一个最好的方法来禁用所有版本的 EdText 工作剪切复制粘贴

if (android.os.Build.VERSION.SDK_INT < 11) {
editText.setOnCreateContextMenuListener(new OnCreateContextMenuListener() {


@Override
public void onCreateContextMenu(ContextMenu menu, View v,
ContextMenuInfo menuInfo) {
// TODO Auto-generated method stub
menu.clear();
}
});
} else {
editText.setCustomSelectionActionModeCallback(new ActionMode.Callback() {


public boolean onPrepareActionMode(ActionMode mode, Menu menu) {
// TODO Auto-generated method stub
return false;
}


public void onDestroyActionMode(ActionMode mode) {
// TODO Auto-generated method stub


}


public boolean onCreateActionMode(ActionMode mode, Menu menu) {
// TODO Auto-generated method stub
return false;
}


public boolean onActionItemClicked(ActionMode mode,
MenuItem item) {
// TODO Auto-generated method stub
return false;
}
});
}

为此,可以禁用 EditText 的长按

要实现它,只需在 xml-中添加以下代码行

android:longClickable="false"

除了 回调禁用长按解决方案,当单击文本选择句柄时,有必要避免出现 防止粘贴/替换菜单,如下图所示:

Text selection handle with paste menu

解决方案在于防止 PASTE/REPLACE 菜单出现在 android.widget.Editor类的 show()方法中。在菜单出现之前,对 if (!canPaste && !canSuggest) return;进行检查。作为设置这些变量的基础的两个方法都在 EditText类中:

更完整的答案是 可在此下载

你可以试试 android: focus usableInTouchMode = “ false”。

我使用的解决方案是创建自定义 Edittext 并重写以下方法:

public class MyEditText extends EditText {


private int mPreviousCursorPosition;


@Override
protected void onSelectionChanged(int selStart, int selEnd) {
CharSequence text = getText();
if (text != null) {
if (selStart != selEnd) {
setSelection(mPreviousCursorPosition, mPreviousCursorPosition);
return;
}
}
mPreviousCursorPosition = selStart;
super.onSelectionChanged(selStart, selEnd);
}

}

下面是一个禁用“粘贴”弹出窗口的技巧。你必须重写 EditText方法:

@Override
public int getSelectionStart() {
for (StackTraceElement element : Thread.currentThread().getStackTrace()) {
if (element.getMethodName().equals("canPaste")) {
return -1;
}
}
return super.getSelectionStart();
}

其他动作也可以这样做。

Kotlin 解决方案:

fun TextView.disableCopyPaste() {
isLongClickable = false
setTextIsSelectable(false)
customSelectionActionModeCallback = object : ActionMode.Callback {
override fun onCreateActionMode(mode: ActionMode?, menu: Menu): Boolean {
return false
}


override fun onPrepareActionMode(mode: ActionMode?, menu: Menu): Boolean {
return false
}


override fun onActionItemClicked(mode: ActionMode?, item: MenuItem): Boolean {
return false
}


override fun onDestroyActionMode(mode: ActionMode?) {}
}
}

然后你可以简单地在你的 TextView上调用这个方法:

override fun onCreate() {
priceEditText.disableCopyPaste()
}

如果你不想禁用长点击,因为你需要在长点击上执行一些功能,那么返回 true 是一个更好的选择。

您的编辑文本长点击将是这样的。

edittext.setOnLongClickListener(new View.OnLongClickListener() {
@Override
public boolean onLongClick(View v) {
//  Do Something or Don't
return true;
}
});

根据 < a href = “ https://developer.android.com/reference/android/view/View.OnLongClickListener.html”rel = “ norefrer”> 文档 返回“ True”将表示已经处理了长时间单击,因此不需要执行默认操作。

我在 API 级别16、22和25上测试了它。它对我来说工作得很好。希望这能有所帮助。

尝试使用。

myEditext.setCursorVisible(false);


myEditext.setCustomSelectionActionModeCallback(new ActionMode.Callback() {


public boolean onPrepareActionMode(ActionMode mode, Menu menu) {
// TODO Auto-generated method stub
return false;
}


public void onDestroyActionMode(ActionMode mode) {
// TODO Auto-generated method stub


}


public boolean onCreateActionMode(ActionMode mode, Menu menu) {
// TODO Auto-generated method stub
return false;
}


public boolean onActionItemClicked(ActionMode mode,
MenuItem item) {
// TODO Auto-generated method stub
return false;
}
});

解决方法很简单

public class MainActivity extends AppCompatActivity {


EditText et_0;


@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);


et_0 = findViewById(R.id.et_0);


et_0.setCustomSelectionActionModeCallback(new ActionMode.Callback() {
@Override
public boolean onCreateActionMode(ActionMode mode, Menu menu) {
//to keep the text selection capability available ( selection cursor)
return true;
}


@Override
public boolean onPrepareActionMode(ActionMode mode, Menu menu) {
//to prevent the menu from appearing
menu.clear();
return false;
}


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


@Override
public void onDestroyActionMode(ActionMode mode) {


}
});
}
}

—— > 预览 < ————-

尝试遵循自定义类,以便在 Edittext中预先复制和粘贴

public class SegoeUiEditText extends AppCompatEditText {
private final Context context;




@Override
public boolean isSuggestionsEnabled() {
return false;
}
public SegoeUiEditText(Context context) {
super(context);
this.context = context;
init();
}


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


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




private void setFonts(Context context) {
this.setTypeface(Typeface.createFromAsset(context.getAssets(), "Fonts/Helvetica-Normal.ttf"));
}


private void init() {


setTextIsSelectable(false);
this.setCustomSelectionActionModeCallback(new ActionModeCallbackInterceptor());
this.setLongClickable(false);


}
@Override
public int getSelectionStart() {


for (StackTraceElement element : Thread.currentThread().getStackTrace()) {
if (element.getMethodName().equals("canPaste")) {
return -1;
}
}
return super.getSelectionStart();
}
/**
* 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, android.view.ActionMode.Callback {
private final String TAG = SegoeUiEditText.class.getSimpleName();


public boolean onCreateActionMode(ActionMode mode, Menu menu) { return false; }
public boolean onPrepareActionMode(ActionMode mode, Menu menu) { return false; }
public boolean onActionItemClicked(ActionMode mode, MenuItem item) { return false; }
public void onDestroyActionMode(ActionMode mode) {}


@Override
public boolean onCreateActionMode(android.view.ActionMode mode, Menu menu) {
return false;
}


@Override
public boolean onPrepareActionMode(android.view.ActionMode mode, Menu menu) {
menu.clear();
return false;
}


@Override
public boolean onActionItemClicked(android.view.ActionMode mode, MenuItem item) {
return false;
}


@Override
public void onDestroyActionMode(android.view.ActionMode mode) {


}
}

}

对于带有剪贴板的智能手机,可以这样防止。

editText.setFilters(new InputFilter[]{new InputFilter() {
@Override
public CharSequence filter(CharSequence source, int start, int end, Spanned dest, int dstart, int dend) {
if (source.length() > 1) {
return "";
}  return null;
}
}});

我已经测试过这个解决方案,这个很有效

    mSubdomainEditText.setLongClickable(false);
mSubdomainEditText.setCustomSelectionActionModeCallback(new ActionMode.Callback() {


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


public void onDestroyActionMode(ActionMode mode) {
}


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


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

谁正在 Kotlin 寻找一个解决方案使用下面的类作为一个自定义小部件,并在 xml 中使用它。

类 SecureEditText: TextInputEditText {

/** This is a replacement method for the base TextView class' method of the same name. This method
* is used in hidden class android.widget.Editor to determine whether the PASTE/REPLACE popup
* appears when triggered from the text insertion handle. Returning false forces this window
* to never appear.
* @return false
*/
override fun isSuggestionsEnabled(): Boolean {
return false
}


override fun getSelectionStart(): Int {
for (element in Thread.currentThread().stackTrace) {
if (element.methodName == "canPaste") {
return -1
}
}
return super.getSelectionStart()
}


public override fun onSelectionChanged(start: Int, end: Int) {


val text = text
if (text != null) {
if (start != text.length || end != text.length) {
setSelection(text.length, text.length)
return
}
}


super.onSelectionChanged(start, end)
}


companion object {
private val EDITTEXT_ATTRIBUTE_COPY_AND_PASTE = "isCopyPasteDisabled"
private val PACKAGE_NAME = "http://schemas.android.com/apk/res-auto"
}


constructor(context: Context, attrs: AttributeSet) : super(context, attrs) {
disableCopyAndPaste(context, attrs)
}


/**
* Disable Copy and Paste functionality on EditText
*
* @param context Context object
* @param attrs   AttributeSet Object
*/
private fun disableCopyAndPaste(context: Context, attrs: AttributeSet) {
val isDisableCopyAndPaste = attrs.getAttributeBooleanValue(
PACKAGE_NAME,
EDITTEXT_ATTRIBUTE_COPY_AND_PASTE, true
)
if (isDisableCopyAndPaste && !isInEditMode()) {
val inputMethodManager =
context.getSystemService(Context.INPUT_METHOD_SERVICE) as InputMethodManager
this.setLongClickable(false)
this.setOnTouchListener(BlockContextMenuTouchListener(inputMethodManager))
}
}


/**
* Perform Focus Enabling Task to the widget with the help of handler object
* with some delay
* @param inputMethodManager is used to show the key board
*/
private fun performHandlerAction(inputMethodManager: InputMethodManager) {
val postDelayedIntervalTime: Long = 25
Handler().postDelayed(Runnable {
this@SecureEditText.setSelected(true)
this@SecureEditText.requestFocusFromTouch()
inputMethodManager.showSoftInput(
this@SecureEditText,
InputMethodManager.RESULT_SHOWN
)
}, postDelayedIntervalTime)
}


/**
* Class to Block Context Menu on double Tap
* A custom TouchListener is being implemented which will clear out the focus
* and gain the focus for the EditText, in few milliseconds so the selection
* will be cleared and hence the copy paste option wil not pop up.
* the respective EditText should be set with this listener
*
* @param inputMethodManager is used to show the key board
*/
private inner class BlockContextMenuTouchListener internal constructor(private val inputMethodManager: InputMethodManager) :
View.OnTouchListener {
private var lastTapTime: Long = 0
val TIME_INTERVAL_BETWEEN_DOUBLE_TAP = 30
override fun onTouch(v: View, event: MotionEvent): Boolean {
if (event.getAction() === MotionEvent.ACTION_DOWN) {
val currentTapTime = System.currentTimeMillis()
if (lastTapTime != 0L && currentTapTime - lastTapTime < TIME_INTERVAL_BETWEEN_DOUBLE_TAP) {
this@SecureEditText.setSelected(false)
performHandlerAction(inputMethodManager)
return true
} else {
if (lastTapTime == 0L) {
lastTapTime = currentTapTime
} else {
lastTapTime = 0
}
performHandlerAction(inputMethodManager)
return true
}
} else if (event.getAction() === MotionEvent.ACTION_MOVE) {
this@SecureEditText.setSelected(false)
performHandlerAction(inputMethodManager)
}
return false
}
}

}

我用 科特林语言添加了 扩展功能:

fun EditText.disableTextSelection() {
this.setCustomSelectionActionModeCallback(object : android.view.ActionMode.Callback {
override fun onActionItemClicked(mode: android.view.ActionMode?, item: MenuItem?): Boolean {
return false
}
override fun onCreateActionMode(mode: android.view.ActionMode?, menu: Menu?): Boolean {
return false
}
override fun onPrepareActionMode(mode: android.view.ActionMode?, menu: Menu?): Boolean {
return false
}
override fun onDestroyActionMode(mode: android.view.ActionMode?) {
}
})
}

你可以这样使用它:

edit_text.disableTextSelection()

还在 xml 中添加了以下代码行:

                android:longClickable="false"
android:textIsSelectable="false"

如果要禁用用于复制/粘贴的 ActionMode,则需要覆盖2个回调。这对 TextViewEditText(或 TextInputEditText)都适用

import android.view.ActionMode


fun TextView.disableCopyPaste() {
isLongClickable = false
setTextIsSelectable(false)
customSelectionActionModeCallback = object : ActionMode.Callback {
override fun onCreateActionMode(mode: ActionMode?, menu: Menu) = false
override fun onPrepareActionMode(mode: ActionMode?, menu: Menu) = false
override fun onActionItemClicked(mode: ActionMode?, item: MenuItem) = false
override fun onDestroyActionMode(mode: ActionMode?) {}
}
//disable action mode when edittext gain focus at first
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
customInsertionActionModeCallback = object : ActionMode.Callback {
override fun onCreateActionMode(mode: ActionMode?, menu: Menu) = false
override fun onPrepareActionMode(mode: ActionMode?, menu: Menu) = false
override fun onActionItemClicked(mode: ActionMode?, item: MenuItem) = false
override fun onDestroyActionMode(mode: ActionMode?) {}
}
}
}

这个扩展基于以上@Alexandr 解决方案,对我来说工作得很好。

一个广泛兼容的解决方案(从 Android 1.5开始)是

@Override
public boolean onTextContextMenuItem(int id) {
switch (id){
case android.R.id.cut:
onTextCut();
return false;
case android.R.id.paste:
onTextPaste();
return false;
case android.R.id.copy:
onTextCopy();
return false;
}
return true;
}

在花费了大量时间之后,删除了 EditText 的 上下文菜单中的粘贴选项,我遵循了下面的 Java 代码。

编辑文本

import android.content.Context;
import android.os.Handler;
import android.util.AttributeSet;
import android.view.MotionEvent;
import android.view.View;
import android.view.inputmethod.InputMethodManager;
import androidx.appcompat.widget.AppCompatEditText;


/**
* custom edit text
*/




public class NoMenuEditText extends AppCompatEditText {


private static final String EDITTEXT_ATTRIBUTE_COPY_AND_PASTE = "isCopyPasteDisabled";
private static final String PACKAGE_NAME = "http://schemas.android.com/apk/res-auto";


public NoMenuEditText(Context context) {
super(context);
}


public NoMenuEditText(Context context, AttributeSet attrs) {
super(context, attrs);
EnableDisableCopyAndPaste(context, attrs);
}


/**
* Enable/Disable Copy and Paste functionality on EditText
*
* @param context Context object
* @param attrs   AttributeSet Object
*/
private void EnableDisableCopyAndPaste(Context context, AttributeSet attrs) {
boolean isDisableCopyAndPaste = attrs.getAttributeBooleanValue(PACKAGE_NAME,
EDITTEXT_ATTRIBUTE_COPY_AND_PASTE, false);
if (isDisableCopyAndPaste && !isInEditMode()) {
InputMethodManager inputMethodManager = (InputMethodManager)
context.getSystemService(Context.INPUT_METHOD_SERVICE);
this.setLongClickable(false);
this.setOnTouchListener(new BlockContextMenuTouchListener
(inputMethodManager));
}
}


/**
* Perform Focus Enabling Task to the widget with the help of handler object
* with some delay
*/
private void performHandlerAction(final InputMethodManager inputMethodManager) {
int postDelayedIntervalTime = 25;
new Handler().postDelayed(new Runnable() {
@Override
public void run() {
NoMenuEditText.this.setSelected(true);
NoMenuEditText.this.requestFocusFromTouch();
inputMethodManager.showSoftInput(NoMenuEditText.this,
InputMethodManager.RESULT_SHOWN);
}
}, postDelayedIntervalTime);
}


/**
* Class to Block Context Menu on double Tap
* A custom TouchListener is being implemented which will clear out the focus
* and gain the focus for the EditText, in few milliseconds so the selection
* will be cleared and hence the copy paste option wil not pop up.
* the respective EditText should be set with this listener
*/
private class BlockContextMenuTouchListener implements View.OnTouchListener {
private static final int TIME_INTERVAL_BETWEEN_DOUBLE_TAP = 30;
private InputMethodManager inputMethodManager;
private long lastTapTime = 0;


BlockContextMenuTouchListener(InputMethodManager inputMethodManager) {
this.inputMethodManager = inputMethodManager;
}


@Override
public boolean onTouch(View v, MotionEvent event) {
if (event.getAction() == MotionEvent.ACTION_DOWN) {
long currentTapTime = System.currentTimeMillis();
if (lastTapTime != 0 && (currentTapTime - lastTapTime)
< TIME_INTERVAL_BETWEEN_DOUBLE_TAP) {
NoMenuEditText.this.setSelected(false);
performHandlerAction(inputMethodManager);
return true;
} else {
if (lastTapTime == 0) {
lastTapTime = currentTapTime;
} else {
lastTapTime = 0;
}
performHandlerAction(inputMethodManager);
return true;
}
} else if (event.getAction() == MotionEvent.ACTION_MOVE) {
NoMenuEditText.this.setSelected(false);
performHandlerAction(inputMethodManager);
}
return false;
}
}


@Override
protected void onSelectionChanged(int selStart, int selEnd) {
CharSequence text = getText();
if (text != null) {
if (selStart != text.length() || selEnd != text.length()) {
setSelection(text.length(), text.length());
return;
}
}
super.onSelectionChanged(selStart, selEnd);
}




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


@Override
public int getSelectionStart() {
for (StackTraceElement element : Thread.currentThread().getStackTrace()) {
if (element.getMethodName().equals("canPaste")) {
return -1;
}
}
return super.getSelectionStart();
}






}

主要活动

import androidx.appcompat.app.AppCompatActivity;
import android.content.ClipboardManager;
import android.content.Context;
import android.os.Bundle;
import android.view.ActionMode;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;


public class MainActivity extends AppCompatActivity {


NoMenuEditText edt_username;


@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);


edt_username = (NoMenuEditText) findViewById(R.id.edt_username);


   

edt_username.setLongClickable(false);
edt_username.setTextIsSelectable(false);


edt_username.setCustomSelectionActionModeCallback(new ActionMode.Callback() {
@Override
public boolean onCreateActionMode(ActionMode actionMode, Menu menu) {
return false;


}


@Override
public boolean onPrepareActionMode(ActionMode actionMode, Menu menu) {
return false;
}


@Override
public boolean onActionItemClicked(ActionMode actionMode, MenuItem menuItem) {


return false;
}


@Override
public void onDestroyActionMode(ActionMode actionMode) {


}
});
        

}


}

Draable-zeropx.xml

<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android"
android:shape="rectangle">


<size
android:width="0dp"
android:height="0dp"/>


</shape>

Xml

<?xml version="1.0" encoding="utf-8"?>
<resources>
<declare-styleable name="NoMenuEditText">
<attr name="isCopyPasteDisabled" format="boolean" />
</declare-styleable>
</resources>

最后,我终于从 编辑文本上下文菜单中移除了 粘贴选项

谢谢 StackOverflow 职位http://androidinformative.com/disabling-context-menu/

 editText.apply {
setOnTouchListener { v, event ->
if (event.action == KeyEvent.ACTION_DOWN) {
requestFocus()
setSelection(text.toString().length)
showKeyboard()
return@setOnTouchListener true
}
}
}


fun View.showKeyboard() {
val imm = context.getSystemService(Context.INPUT_METHOD_SERVICE) as InputMethodManager
imm.showSoftInput(this, 0)
}

上面的解决方案没有考虑到硬件键盘的粘贴(Ctrl + v)。最简单的解决方案是在 EditText 上设置 TextWatcher,并在 after TextChanged 方法中筛选您想要或不想要的字符。这适用于所有情况,例如键入字符、粘贴、自动建议和自动更正。

实际上在我的情况下,我必须设置 选择插入的回调,只有这样我才能得到复制/粘贴弹出窗口不再出现。 就像这样:

 private void disableCopyPaste() {
input.setLongClickable(false);
input.setTextIsSelectable(false);
final ActionMode.Callback disableCopyPasteCallback = new ActionMode.Callback() {
@Override
public boolean onCreateActionMode(ActionMode actionMode, Menu menu) {
return false;
}
@Override
public boolean onPrepareActionMode(ActionMode actionMode, Menu menu) {
return false;
}


@Override
public boolean onActionItemClicked(ActionMode actionMode, MenuItem menuItem) {
return false;
}


@Override
public void onDestroyActionMode(ActionMode actionMode) {
}
};
input.setCustomSelectionActionModeCallback(disableCopyPasteCallback);
input.setCustomInsertionActionModeCallback(disableCopyPasteCallback);
}

与其完全禁用 EditText 上的所有操作,不如只防止某些操作(比如剪切/复制,但不要粘贴) :

/**
* Prevent copy/cut of the (presumably sensitive) contents of this TextView.
*/
fun TextView.disableCopyCut() {
setCustomSelectionActionModeCallback(
object : Callback {
override fun onActionItemClicked(mode: ActionMode?, item: MenuItem?) = false


override fun onCreateActionMode(mode: ActionMode?, menu: Menu?): Boolean {
menu?.apply {
removeItem(android.R.id.copy)
removeItem(android.R.id.cut)
}
return true
}


override fun onPrepareActionMode(mode: ActionMode?, menu: Menu?) = false


override fun onDestroyActionMode(mode: ActionMode?) {
// no-op
}
}
)
}

可有选择地删除的行动:

removeItem(android.R.id.copy)
removeItem(android.R.id.cut)
removeItem(android.R.id.paste)
removeItem(android.R.id.shareText) // Share
removeItem(android.R.id.textAssist) // Open with Chrome

现在很晚了,但愿它能帮助某人。

在您的 edit text xml 中添加这些行

android:longClickable="false"
android:textIsSelectable="false"
android:importantForAutofill="no"