Programing

EditText에서 복사 / 붙여 넣기를 비활성화하는 방법

lottogame 2020. 7. 19. 09:48
반응형

EditText에서 복사 / 붙여 넣기를 비활성화하는 방법


내 응용 프로그램에는 사용자가 텍스트를 EditText필드 에 복사 / 붙여 넣기를 원하지 않는 등록 화면이 있습니다 . 복사 / 붙여 넣기 / 입력 방법 및 기타 옵션을 표시하는 상황에 맞는 메뉴가 표시되지 않도록 onLongClickListener각각 을 설정 EditText했습니다. 따라서 사용자는 편집 필드에 복사 / 붙여 넣기를 할 수 없습니다.

 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 기본값 이외의 타사 키보드를 사용하도록 설정하면 복사 / 붙여 넣기 버튼이 있거나 동일한 상황에 맞는 메뉴가 표시 될 수 있습니다. 그렇다면 해당 시나리오에서 복사 / 붙여 넣기를 어떻게 비활성화합니까?

복사 / 붙여 넣기 방법이 더 있으면 알려주세요. (그리고 아마도 그들을 비활성화하는 방법)

도움을 주시면 감사하겠습니다.


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를 반환하면 동작 모드가 시작되지 않습니다 (모두 선택, 잘라 내기, 복사 및 붙여 넣기 동작).


가장 좋은 방법은 다음을 사용하는 것입니다.

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

그것이 당신을 위해 작동하기를 바랍니다 ;-)


모든 버전에서 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를 반환하는 것보다 긴 클릭에서 일부 기능을 수행해야하므로 true를 반환하는 것이 좋습니다.

편집 텍스트 긴 클릭은 다음과 같습니다.

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

문서에 따라 "참"을 반환하면 긴 클릭이 처리되어 기본 작업을 수행 할 필요가 없음을 나타냅니다.

나는 이것을 API 레벨 16, 22 및 25에서 테스트했습니다. 그것은 잘 작동합니다. 이것이 도움이되기를 바랍니다.


코 틀린 솔루션 :

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

https://github.com/neopixl/PixlUIEditText메소드를 제공합니다

myEditText.disableCopyAndPaste().

그리고 그것은 오래된 API에서 작동합니다.


다음은 "붙여 넣기"팝업을 비활성화하는 해킹입니다. EditText메소드 를 대체해야합니다 .

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

다른 작업에서도 비슷한 작업을 수행 할 수 있습니다.


클립 보드를 읽고 입력과 입력이 "입력 된"시간을 확인하십시오. 클립 보드의 텍스트가 같고 너무 빠르면 붙여 넣은 입력을 삭제하십시오.


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

해결책은 매우 간단합니다

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

GnrlKnowledge와 유사하게 클립 보드를 지울 수 있습니다

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

원하는 경우 클립 보드에 텍스트를 유지 한 다음 onDestroy에서 다시 설정할 수 있습니다.


원치 않는 문자가 입력되는 것을 피하기 위해 입력 필터를 만들 때 해당 문자를 편집 텍스트에 붙여 넣는 것은 효과가 없다는 것을 알았습니다. 따라서 이런 종류의 문제도 해결됩니다.


android : focusableInTouchMode = "false"를 사용해보십시오.


나를 위해 일한 해결책은 사용자 정의 편집 텍스트를 만들고 다음 방법을 재정의하는 것입니다.

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

}


사용하십시오.

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

참고 URL : https://stackoverflow.com/questions/6275299/how-to-disable-copy-paste-from-to-edittext

반응형