How to disable copy/paste from/to EditText

In my application, there is a registration screen, where i do not want the user to be able to copy/paste text into the EditText поле. I have set an onLongClickListener на каждой EditText so that the context menu showing copy/paste/inputmethod and other options does not show up. So the user won't be able to copy/ paste into the Edit fields.

 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 по умолчанию, которая может иметь кнопку для копирования / вставки или которая может отображать то же контекстное меню. Так как же отключить копирование / вставку в этом сценарии?

Пожалуйста, дайте мне знать, если есть и другие способы копирования / вставки. (и, возможно, как их отключить)

Любая помощь будет оценена.

32 ответа

Решение

Если вы используете 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;
            }
        });

Возврат false из onCreateActionMode(ActionMode, Menu) предотвратит запуск режима действия (действия "Выбрать все", "Вырезать", "Копировать" и "Вставить").

Лучший метод заключается в использовании:

etUsername.setLongClickable(false);

Вы можете сделать это, отключив долгое нажатие EditText

Чтобы реализовать это, просто добавьте следующую строку в xml -

android:longClickable="false"

Я могу отключить функцию копирования и вставки с помощью следующего:

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

Надеюсь, это работает для вас;-)

Котлин раствор:

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

Тогда вы можете просто вызвать этот метод на вашем TextView:

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

Вот лучший способ отключить вырезать копировать вставить текст EditText работать во всех версиях

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

В дополнение к setCustomSelectionActionModeCallback и отключенным решениям для длинных щелчков необходимо предотвратить появление меню PASTE/REPLACE при нажатии на дескриптор выделения текста, как показано на рисунке ниже:

Ручка выделения текста с меню вставки

Решение заключается в предотвращении появления меню PASTE/REPLACE в show() метод (недокументированный) android.widget.Editor учебный класс. Прежде чем появится меню, выполняется проверка if (!canPaste && !canSuggest) return;, Два метода, которые используются в качестве основы для установки этих переменных, находятся в EditText учебный класс:

Более полный ответ доступен здесь.

Используя другие решения, API 26 (Oreo) по-прежнему отображал дескриптор курсора одним нажатием на введенный текст, после чего можно было отобразить меню. Только комбинация решений может решить мою проблему.

public class CustomEditText extends EditText {

    public CustomEditText(Context context) {
        super(context);
        init();
    }

    public CustomEditText(Context context, AttributeSet attrs) {
        super(context, attrs);
        init();
    }

    public CustomEditText(Context context, AttributeSet 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) {
        }
    }
}

Если вы не хотите отключать длинный щелчок, потому что вам нужно выполнить некоторые функции при длинном щелчке, лучше выбрать вариант возврата true.

Ваш длинный текст редактирования будет таким.

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

В соответствии с документацией, возвращение "True" будет означать, что длинный щелчок был обработан, поэтому нет необходимости выполнять операции по умолчанию.

Я проверил это на уровне API 16, 22 и 25. Он отлично работает для меня. Надеюсь, это поможет.

Вот взломать, чтобы отключить "вставить" всплывающее окно. Вы должны переопределить EditText метод:

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

Подобное можно сделать для других действий.

Я добавил функцию расширения на языке Kotlin:

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"

Я протестировал это решение, и оно работает

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

https://github.com/neopixl/PixlUI предоставляет EditText с методом

myEditText.disableCopyAndPaste(),

И это работает на старом API

это очень поздно, но может это поможет кому-то.

добавьте эти строки в свой edittext xml

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

Если вы хотите отключить ActionModeдля копирования / вставки вам нужно переопределить 2 обратных вызова. Это работает как для TextView и EditText (или же 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 и отлично сработало для меня.

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

Для смартфона с буфером обмена возможно предотвратить подобное.

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

Прочитайте буфер обмена, проверьте ввод и время, когда ввод "напечатан". Если в буфере обмена тот же текст, и он слишком быстрый, удалите вставленный ввод.

Попробуйте следовать классу обычного для преобладающего копирования и вставки в 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) {

    }
}

}

На самом деле в моем случае мне пришлось установить обратный вызов как для выбора , так и для вставки , и только тогда всплывающее окно копирования/вставки больше не появлялось. Что-то вроде этого :

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

Приведенные выше решения не учитывают вставку с помощью аппаратных клавиатур (Ctrl+v). Самое простое решение — установить TextWatcher в вашем EditText и отфильтровать символы, которые вы хотите или не хотите, в методе afterTextChanged. Это работает для всех ситуаций, т. е. для набранных символов, вставок, автоматических предложений и автоматических исправлений.

Вместо того, чтобы полностью отключать все действия в 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

Решение очень простое

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

        }
    });
   }
}

--------> предварительный просмотр <---------

Потратив много времени, удалив опцию вставки в ContextMenu в EditText, я выполнил приведенный ниже код на Java.

NoMenuEditText.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) {

            }
        });
        
    }

}

drawable- 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>

attrs.xml

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

Наконец, я наконец Убрана опция вставки из контекстного меню из EditText

Спасибо за сообщения StackOverflow и http://androidinformative.com/disables-context-menu/

Кто ищет решение в Kotlin, используйте приведенный ниже класс в качестве настраиваемого виджета и используйте его в xml.

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

}

Я обнаружил, что когда вы создаете фильтр ввода, чтобы избежать ввода нежелательных символов, вставка таких символов в текст редактирования не оказывает никакого влияния. Так что этот вид решает и мою проблему.

Широко совместимое решение (начиная с 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.apply {
        setOnTouchListener { v, event ->
               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)
 }

Попробуй использовать.

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

Решение, которое работало для меня, состояло в том, чтобы создать собственный 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);
}

}

Другие вопросы по тегам