Comment désactiver le copier / coller depuis / vers EditText

Dans mon application, il y a un écran d’enregistrement, dans lequel je ne souhaite pas que l’utilisateur puisse copier / coller du texte dans le champ EditText . J’ai défini un onLongClickListener sur chaque EditText afin que le menu contextuel affichant la méthode copier / coller / saisir et les autres options ne s’affiche pas. Ainsi, l’utilisateur ne pourra pas copier / coller dans les champs d’édition.

  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; } }; 

Mais le problème se pose si l’utilisateur a activé un clavier tiers autre que celui d’Android par défaut, qui peut avoir un bouton pour copier / coller ou afficher le même menu contextuel. Alors, comment puis-je désactiver le copier / coller dans ce scénario?

S’il vous plaît laissez-moi savoir s’il existe d’autres moyens de copier / coller ainsi. (et éventuellement comment les désactiver)

Toute aide serait appréciée.

Si vous utilisez une API de niveau 11 ou supérieur, vous pouvez empêcher les menus contextuels de copier, coller, couper et personnaliser.

 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; } }); 

Le fait de renvoyer false à partir de onCreateActionMode (ActionMode, Menu) empêchera le démarrage du mode d’action (actions Sélectionner tout, Couper, Copier et Coller).

La meilleure méthode est d’utiliser:

 etUsername.setLongClickable(false); 

Vous pouvez le faire en désactivant l’appui long sur le EditText

Pour l’implémenter, ajoutez simplement la ligne suivante dans le fichier XML –

 android:longClickable="false" 

Je suis en mesure de désactiver la fonctionnalité copier-coller avec les éléments suivants:

 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); 

J’espère que ça marche pour toi 😉

voici le meilleur moyen de désactiver le copier-coller de editText dans toutes les versions

 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; } }); } 

Outre les solutions de clic long setCustomSelectionActionModeCallback et disabled , il est nécessaire d’ empêcher l’affichage des menus PASTE / REPLACE lorsque l’utilisateur clique sur le sélecteur de texte , comme illustré ci-dessous:

Poignée de sélection de texte avec le menu coller

La solution consiste à empêcher le menu PASTE / REPLACE d’apparaître dans la méthode show() de la classe (non documentée) android.widget.Editor . Avant que le menu apparaisse, une vérification est effectuée pour savoir if (!canPaste && !canSuggest) return; . Les deux méthodes utilisées comme base pour définir ces variables sont toutes deux dans la classe EditText :

  • isSuggestionsEnabled() est public et peut donc être remplacé.
  • canPaste() ne l’est pas et doit donc être caché en introduisant une fonction du même nom dans la classe dérivée.

Une réponse plus complète est disponible ici .

https://github.com/neopixl/PixlUI fournit un EditText avec une méthode

myEditText.disableCopyAndPaste() .

Et ça marche sur l’ancienne API

Solution Kotlin:

 fun TextView.disableCopyPaste() { 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?) {} } isLongClickable = false setTextIsSelectable(false) } 

Ensuite, vous pouvez simplement appeler cette méthode sur votre TextView :

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

Si vous ne voulez pas désactiver le clic long car vous devez effectuer certaines fonctionnalités sur un clic long, il est préférable de le faire.

Votre clic long sur edittext sera comme ceci.

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

Selon la documentation Le retour de “True” indique que le long clic a été traité, donc pas besoin d’effectuer des opérations par défaut.

Je l’ai testé au niveau 16, 22 et 25 de l’API. Cela fonctionne bien pour moi. J’espère que cela aidera.

Voici un hack pour désactiver “coller” popup. Vous devez remplacer la méthode EditText :

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

On peut faire la même chose pour les autres actions.

Lisez le Presse-papiers, vérifiez avec l’entrée et l’heure à laquelle l’entrée est “tapée”. Si le Presse-papiers a le même texte et qu’il est trop rapide, supprimez l’entrée collée.

@ Zain Ali, votre réponse fonctionne sur API 11. Je voulais juste suggérer une façon de faire sur l’API 10 également. Étant donné que je devais maintenir mon API de projet sur cette version, je jouais constamment avec les fonctions disponibles dans la version 2.3.3 et j’ai eu la possibilité de le faire. J’ai partagé l’extrait ci-dessous. J’ai testé le code et cela fonctionnait pour moi. J’ai fait cet extrait sur une urgence. N’hésitez pas à améliorer le code si des modifications peuvent être apscopes.

 // 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; } 

La solution est très simple

 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) { } }); } } 

——–> aperçu <---------

Essayez de suivre la classe custome pour le copier-coller Edittext dans 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, AtsortingbuteSet attrs) { super(context, attrs); this.context = context; init(); } public SegoeUiEditText(Context context, AtsortingbuteSet 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 Ssortingng 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) { } } 

}

Similaire à GnrlKnowledge, vous pouvez effacer le Presse-papiers

http://developer.android.com/reference/android/text/ClipboardManager.html

Si vous le souhaitez, conservez le texte dans le Presse-papiers et sur onDestroy, vous pouvez le définir à nouveau.

J’ai constaté que lorsque vous créez un filtre d’entrée pour éviter la saisie de caractères indésirables, coller de tels caractères dans le texte d’édition n’a aucun effet. Donc, ce genre de problème résout également mon problème.

Vous pouvez essayer Android: focusableInTouchMode = “false”.

La solution qui a fonctionné pour moi consistait à créer un Edittext personnalisé et à remplacer la méthode suivante:

 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); } 

}

Essayez d’utiliser.

 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; } }); 

À l’aide d’autres solutions, l’API 26 (Oreo) affichait toujours la prise en charge du curseur par une simple pression sur le texte saisi, puis le menu pouvait être affiché. Seule la combinaison de solutions peut résoudre mon problème.

 public class CustomEditText extends EditText { public CustomEditText(Context context) { super(context); init(); } public CustomEditText(Context context, AtsortingbuteSet attrs) { super(context, attrs); init(); } public CustomEditText(Context context, AtsortingbuteSet attrs, int defStyle) { super(context, attrs, defStyle); init(); } private void init() { this.setCustomSelectionActionModeCallback(new BlockedActionModeCallback()); this.setLongClickable(false); } @Override public boolean onTouchEvent(MotionEvent event) { if (event.getAction() == MotionEvent.ACTION_DOWN) { this.setInsertionDisabled(); } return super.onTouchEvent(event); } /** * This method sets TextView#Editor#mInsertionControllerEnabled field to false * to return false from the Editor#hasInsertionController() method to PREVENT showing * of the insertionController from EditText * The Editor#hasInsertionController() method is called in Editor#onTouchUpEvent(MotionEvent event) method. */ private void setInsertionDisabled() { try { Field editorField = TextView.class.getDeclaredField("mEditor"); editorField.setAccessible(true); Object editorObject = editorField.get(this); Class editorClass = Class.forName("android.widget.Editor"); Field mInsertionControllerEnabledField = editorClass.getDeclaredField("mInsertionControllerEnabled"); mInsertionControllerEnabledField.setAccessible(true); mInsertionControllerEnabledField.set(editorObject, false); } catch (Exception ignored) { // ignore exception here } } @Override public boolean isSuggestionsEnabled() { return false; } private class BlockedActionModeCallback implements ActionMode.Callback { 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) { } } }