Android Intercept Paste\Copy\Cut on Edittext

android paste event

Create menu.xml with position 'paste'

Register contextMenu to your EditText

EditText et=(EditText)findViewById(R.id.et);
registerForContextMenu(et);

Create contextMenu

@Override
public void onCreateContextMenu(ContextMenu menu, View v,
ContextMenuInfo menuInfo) {
MenuInflater inflater = getMenuInflater();
inflater.inflate(R.menu.menu, menu);
AdapterContextMenuInfo info = (AdapterContextMenuInfo) menuInfo;
menu.setHeaderTitle("title");
}

Create method menu onClick

@Override
public boolean onContextItemSelected(MenuItem item) {
AdapterContextMenuInfo info = (AdapterContextMenuInfo)item.getMenuInfo();
switch (item.getItemId()) {
case R.id.paste:
break;
}
return true;
}

Android intercept paste\copy\cut on editText

Seems there isn't much you can do by using the API: android paste event

Source reading to the rescue!

I dug into the Android Source of the TextView (EditText is a TextView with some different configuration) and found out that the menu used to offer the cut/copy/paste options is just a modified ContextMenu (source).

As for a normal context-menu, the View must create the menu (source) and then handle the interaction in a callback-method (source).

Because the handling method is public, we can simply hook into it by extending EditText and overwriting the method to react on the different actions. Here is an example-implementation:

import android.content.Context;
import android.util.AttributeSet;
import android.widget.EditText;
import android.widget.Toast;

/**
* An EditText, which notifies when something was cut/copied/pasted inside it.
* @author Lukas Knuth
* @version 1.0
*/
public class MonitoringEditText extends EditText {

private final Context context;

/*
Just the constructors to create a new EditText...
*/
public MonitoringEditText(Context context) {
super(context);
this.context = context;
}

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

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

/**
* <p>This is where the "magic" happens.</p>
* <p>The menu used to cut/copy/paste is a normal ContextMenu, which allows us to
* overwrite the consuming method and react on the different events.</p>
* @see <a href="http://grepcode.com/file/repository.grepcode.com/java/ext/com.google.android/android/2.3_r1/android/widget/TextView.java#TextView.onTextContextMenuItem%28int%29">Original Implementation</a>
*/
@Override
public boolean onTextContextMenuItem(int id) {
// Do your thing:
boolean consumed = super.onTextContextMenuItem(id);
// React:
switch (id){
case android.R.id.cut:
onTextCut();
break;
case android.R.id.paste:
onTextPaste();
break;
case android.R.id.copy:
onTextCopy();
}
return consumed;
}

/**
* Text was cut from this EditText.
*/
public void onTextCut(){
Toast.makeText(context, "Cut!", Toast.LENGTH_SHORT).show();
}

/**
* Text was copied from this EditText.
*/
public void onTextCopy(){
Toast.makeText(context, "Copy!", Toast.LENGTH_SHORT).show();
}

/**
* Text was pasted into the EditText.
*/
public void onTextPaste(){
Toast.makeText(context, "Paste!", Toast.LENGTH_SHORT).show();
}
}

Now, when the user uses cut/copy/paste, a Toast is shown (of course you could do other things, too).

The neat thing is that this works down to Android 1.5 and you don't need to re-create the context-menu (like suggested in the above linked question), which will keep the constant look of the platform (for example with HTC Sense).

How to detect the paste event in editext of the application?

You can set Listener Class:

public interface GoEditTextListener {
void onUpdate();
}

Сreate self class for EditText:

public class GoEditText extends EditText
{
ArrayList<GoEditTextListener> listeners;

public GoEditText(Context context)
{
super(context);
listeners = new ArrayList<>();
}

public GoEditText(Context context, AttributeSet attrs)
{
super(context, attrs);
listeners = new ArrayList<>();
}

public GoEditText(Context context, AttributeSet attrs, int defStyle)
{
super(context, attrs, defStyle);
listeners = new ArrayList<>();
}

public void addListener(GoEditTextListener listener) {
try {
listeners.add(listener);
} catch (NullPointerException e) {
e.printStackTrace();
}
}

/**
* Here you can catch paste, copy and cut events
*/
@Override
public boolean onTextContextMenuItem(int id) {
boolean consumed = super.onTextContextMenuItem(id);
switch (id){
case android.R.id.cut:
onTextCut();
break;
case android.R.id.paste:
onTextPaste();
break;
case android.R.id.copy:
onTextCopy();
}
return consumed;
}

public void onTextCut(){
}

public void onTextCopy(){
}

/**
* adding listener for Paste for example
*/
public void onTextPaste(){
for (GoEditTextListener listener : listeners) {
listener.onUpdate();
}
}
}

xml:

<com.yourname.project.GoEditText
android:layout_width="match_parent"
android:layout_height="match_parent"
android:id="@+id/editText1"/>

And in your activity:

private GoEditText editText1;

editText1 = (GoEditText) findViewById(R.id.editText1);

editText1.addListener(new GoEditTextListener() {
@Override
public void onUpdate() {
//here do what you want when text Pasted
}
});

Android how to detect Copy event of Edittext in android

I got solutions:
I create one service :
on that in oncreate :

         ClipboardManager clipBoard = (ClipboardManager) getSystemService(CLIPBOARD_SERVICE);
clipBoard.addPrimaryClipChangedListener(new ClipboardListener());

and add in service :

        class ClipboardListener implements
ClipboardManager.OnPrimaryClipChangedListener {
public void onPrimaryClipChanged() {
ClipboardManager clipBoard = (ClipboardManager) getSystemService(CLIPBOARD_SERVICE);
CharSequence pasteData = "";
ClipData.Item item = clipBoard.getPrimaryClip().getItemAt(0);
pasteData = item.getText();
Toast.makeText(getApplicationContext(), "copied val=" + pasteData,
Toast.LENGTH_SHORT).show();

}
}

Android Spannable: Copy/Cut custom Span in Edittext only Pastes the base class

You inspired me to have some fun with Spannables. There is no chance to extend BackgroundColorSpan and implement own ParcelableSpan's. Framework doesn't allow it, check it on ParcelableSpan reference. Otherwise I tried to resolve your copy spannable problem and answer is simple:

 SpannableString spannableString = new SpannableString(firstEditText.getText().toString());
spannableString.setSpan(new BackgroundColorSpan(Color.GREEN), 0, spannableString.length(), 0);
spannableString.setSpan(new ForegroundColorSpan(Color.RED), 0, spannableString.length(), 0);

String can be copy-paste contains before set span, I've checked it. You can connect those two span to one class and use it with others colors.

Custom cut/copy action bar for EditText that shows text selection handles

I figured out the answer to my own question; TextView (and therefore EditText) has a method setCustomSelectionActionModeCallback() which should be used instead of startActionMode(). Using this enables customisation of the menu used by TextView for text selection. Sample code:

bodyView.setCustomSelectionActionModeCallback(new StyleCallback());

where StyleCallback customises the text selection menu by removing Select All and adding some styling actions:

class StyleCallback implements ActionMode.Callback {

public boolean onCreateActionMode(ActionMode mode, Menu menu) {
Log.d(TAG, "onCreateActionMode");
MenuInflater inflater = mode.getMenuInflater();
inflater.inflate(R.menu.style, menu);
menu.removeItem(android.R.id.selectAll);
return true;
}

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

public boolean onActionItemClicked(ActionMode mode, MenuItem item) {
Log.d(TAG, String.format("onActionItemClicked item=%s/%d", item.toString(), item.getItemId()));
CharacterStyle cs;
int start = bodyView.getSelectionStart();
int end = bodyView.getSelectionEnd();
SpannableStringBuilder ssb = new SpannableStringBuilder(bodyView.getText());

switch(item.getItemId()) {

case R.id.bold:
cs = new StyleSpan(Typeface.BOLD);
ssb.setSpan(cs, start, end, 1);
bodyView.setText(ssb);
return true;

case R.id.italic:
cs = new StyleSpan(Typeface.ITALIC);
ssb.setSpan(cs, start, end, 1);
bodyView.setText(ssb);
return true;

case R.id.underline:
cs = new UnderlineSpan();
ssb.setSpan(cs, start, end, 1);
bodyView.setText(ssb);
return true;
}
return false;
}

public void onDestroyActionMode(ActionMode mode) {
}
}

The XML for the menu additions is:

<?xml version="1.0" encoding="utf-8"?>
<menu xmlns:android="http://schemas.android.com/apk/res/android">
<item android:id="@+id/italic"
android:showAsAction="always"
android:icon="@drawable/italic"
android:title="Italic"/>
<item android:id="@+id/bold"
android:showAsAction="always"
android:icon="@drawable/bold"
android:title="Bold"/>
<item android:id="@+id/underline"
android:showAsAction="always"
android:icon="@drawable/underline"
android:title="Underline"/>
</menu>

android 4.0 and higher : Copy/paste/cut panel disappears onLongClick Listener on the EditText

As I used TabHost and nested Activity in it, I solved it by using the

  android:windowSoftInputMode="stateUnspecified" 

for the TabActivity and for the nested Activity :

  android:windowSoftInputMode = "adjustResize"

It solved my issue.



Related Topics



Leave a reply



Submit