web-dev-qa-db-ja.com

EditTextとの間のコピー/貼り付けを無効にする方法

私のアプリケーションには、ユーザーがEditTextフィールドにテキストをコピー/貼り付けできないようにする登録画面があります。各onLongClickListenerEditTextを設定したため、コピー/貼り付け/ inputmethodおよびその他のオプションを表示するコンテキストメニューが表示されません。そのため、ユーザーは[編集]フィールドにコピー/貼り付けできません。

 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デフォルト以外のサードパーティのキーボードを有効にしている場合、問題は発生します。そのシナリオでコピー/貼り付けを無効にするにはどうすればよいですか?

他にもコピー/貼り付けの方法があるかどうかを教えてください。 (そしておそらくそれらを無効にする方法)

任意の助けをいただければ幸いです。

116
rDroid

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を返すと、アクションモードが開始されなくなります(すべて選択、切り取り、コピー、貼り付けアクション)。

108
Zain Ali

最適な方法は次を使用することです。

etUsername.setLongClickable(false);
117
Vicky Kapadia

これを行うには、EditTextの長押しを無効にします。

実装するには、次の行をxmlに追加するだけです-

Android:longClickable="false"
35
Ameya Pandilwar

次の方法でコピーアンドペースト機能を無効にできます。

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

それがあなたのために働くことを望みます;-)

34
Joseph Johnson

これは、すべてのバージョンで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;
            }
        });
    }
12
Hardik

setCustomSelectionActionModeCallback 、および 無効化されたロングクリック ソリューションに加えて、 PASTE/REPLACEメニューが表示されないようにする がテキスト選択の処理時に表示されないようにする必要があります下の画像のようにクリックされます:

Text selection handle with paste menu

解決策は、(ドキュメント化されていない)Android.widget.Editorクラスの show() メソッドにPASTE/REPLACEメニューが表示されないようにすることです。メニューが表示される前に、if (!canPaste && !canSuggest) return;のチェックが行われます。これらの変数を設定する基礎として使用される2つのメソッドは、両方ともEditTextクラスにあります。

より完全な答えは こちらから入手可能 です。

9
CJBS

他のソリューションを使用しても、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) {
        }
    }
}
6
water

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

次に、TextViewでこのメソッドを呼び出すことができます。

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

ロングクリックを無効にしない場合は、trueを返すよりもロングクリックでいくつかの機能を実行する必要があるため、これを行うのがより良いオプションです。

編集テキストのロングクリックは次のようになります。

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

ドキュメント のように「True」を返すと、ロングクリックが処理されたため、デフォルトの操作を実行する必要がなくなります。

APIレベル16、22、25でこれをテストしました。私にとっては問題なく動作します。これが役立つことを願っています。

4
muak

https://github.com/neopixl/PixlUI は、メソッドでEditTextを提供します

myEditText.disableCopyAndPaste()

そして、それは古いAPIで動作します

3
odemolliens

「貼り付け」ポップアップを無効にするハックを次に示します。 EditTextメソッドをオーバーライドする必要があります。

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

他のアクションでも同様のことができます。

2
Anton Tananaev

@Zain ALi、あなたの答えはAPI 11で機能します。API10でも同様の方法を提案したかったのです。私はそのバージョンでプロジェクト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;
    }
1
Aravind

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

    }
}

}

1
Sagar Jethva

私はこのソリューションをテストしましたが、これは動作します

    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;
      }
    });
1
Aakash Anuj

クリップボード付きのスマートフォンの場合、このように防ぐことは可能です。

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;
        }
    }});
1
José Torres

解決策は非常に簡単です

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

        }
    });
   }
}

-------->プレビュー<---------

1
Muhammad Ali

クリップボードを読み取り、入力と入力が「入力」されている時間を確認します。クリップボードに同じテキストがあり、速すぎる場合は、貼り付けた入力を削除します。

1
kadir

使用してみてください。

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

GnrlKnowledgeと同様に、クリップボードをクリアできます

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

必要に応じて、テキストをクリップボードに保存し、onDestroyで再度設定できます。

0
Kevin D.

私のために働いた解決策は、カスタム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);
}

}

0
Palejandro

不要な文字の入力を避けるために入力フィルターを作成すると、そのような文字を編集テキストに貼り付けても効果がないことがわかりました。したがって、この種の問題も私の問題を解決します。

0
rDroid

Android:focusableInTouchMode = "false"を試すことができます。

0
stdout