Android copy/paste from clipboard manager

2019-01-09 10:48发布

问题:

Is it possible to send past command so that it pastes text into currently focused edit text. Scenario:

  1. Background service listening for notification (done)
  2. When notification is received text needs to be copied to clipboard (done)
  3. Paste text to any currently focused field, if not possible just discard paste command.

I know how to copy text with ClipboardManager, but I don't know how to paste it.

回答1:

you can copy and paste text using following code :

  • for copy :

    ClipboardManager clipboard = (ClipboardManager)getSystemService(Context.CLIPBOARD_SERVICE);
    ClipData clip = ClipData.newPlainText("your_text_to_be_copied");
    clipboard.setPrimaryClip(clip);
    
  • And paste it :

    ClipboardManager clipboard = (ClipboardManager) getSystemService(Context.CLIPBOARD_SERVICE);
    String pasteData = "";
    
     // If it does contain data, decide if you can handle the data.
    if (!(clipboard.hasPrimaryClip())) {
    
    } else if (!(clipboard.getPrimaryClipDescription().hasMimeType(MIMETYPE_TEXT_PLAIN))) {
    
        // since the clipboard has data but it is not plain text
    
    } else {
    
        //since the clipboard contains plain text.
        ClipData.Item item = clipboard.getPrimaryClip().getItemAt(0);
    
        // Gets the clipboard as text.
        pasteData = item.getText().toString(); 
    }
    

for more details check here



回答2:

a short summary of above after honeycomb >= API 13:

public String readFromClipboard() {
    ClipboardManager clipboard = (ClipboardManager) getSystemService(Context.CLIPBOARD_SERVICE);
    if (clipboard.hasPrimaryClip()) {
        android.content.ClipDescription description = clipboard.getPrimaryClipDescription();
        android.content.ClipData data = clipboard.getPrimaryClip();
        if (data != null && description != null && description.hasMimeType(ClipDescription.MIMETYPE_TEXT_PLAIN)) 
            return String.valueOf(data.getItemAt(0).getText());
    }
    return null;
}


回答3:

I do it this way. Clipboard manager for all api levels.

import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.InputStreamReader;

import android.annotation.SuppressLint;
import android.content.ClipData;
import android.content.ClipboardManager;
import android.content.ContentResolver;
import android.content.Context;
import android.content.Intent;
import android.content.res.AssetFileDescriptor;
import android.net.Uri;
import android.util.Log;


public class MyClipboardManager {

    @SuppressLint("NewApi")
    @SuppressWarnings("deprecation")
    public boolean copyToClipboard(Context context, String text) {
        try {
            int sdk = android.os.Build.VERSION.SDK_INT;
            if (sdk < android.os.Build.VERSION_CODES.HONEYCOMB) {
                android.text.ClipboardManager clipboard = (android.text.ClipboardManager) context
                        .getSystemService(context.CLIPBOARD_SERVICE);
                clipboard.setText(text);
            } else {
                android.content.ClipboardManager clipboard = (android.content.ClipboardManager) context
                        .getSystemService(context.CLIPBOARD_SERVICE);
                android.content.ClipData clip = android.content.ClipData
                        .newPlainText(
                                context.getResources().getString(
                                        R.string.message), text);
                clipboard.setPrimaryClip(clip);
            }
            return true;
        } catch (Exception e) {
            return false;
        }
    }

    @SuppressLint("NewApi")
    public String readFromClipboard(Context context) {
        int sdk = android.os.Build.VERSION.SDK_INT;
        if (sdk < android.os.Build.VERSION_CODES.HONEYCOMB) {
            android.text.ClipboardManager clipboard = (android.text.ClipboardManager) context
                    .getSystemService(context.CLIPBOARD_SERVICE);
            return clipboard.getText().toString();
        } else {
            ClipboardManager clipboard = (ClipboardManager) context
                    .getSystemService(Context.CLIPBOARD_SERVICE);

            // Gets a content resolver instance
            ContentResolver cr = context.getContentResolver();

            // Gets the clipboard data from the clipboard
            ClipData clip = clipboard.getPrimaryClip();
            if (clip != null) {

                String text = null;
                String title = null;

                // Gets the first item from the clipboard data
                ClipData.Item item = clip.getItemAt(0);

                // Tries to get the item's contents as a URI pointing to a note
                Uri uri = item.getUri();

                // If the contents of the clipboard wasn't a reference to a
                // note, then
                // this converts whatever it is to text.
                if (text == null) {
                    text = coerceToText(context, item).toString();
                }

                return text;
            }
        }
        return "";
    }

    @SuppressLint("NewApi")
    public CharSequence coerceToText(Context context, ClipData.Item item) {
        // If this Item has an explicit textual value, simply return that.
        CharSequence text = item.getText();
        if (text != null) {
            return text;
        }

        // If this Item has a URI value, try using that.
        Uri uri = item.getUri();
        if (uri != null) {

            // First see if the URI can be opened as a plain text stream
            // (of any sub-type). If so, this is the best textual
            // representation for it.
            FileInputStream stream = null;
            try {
                // Ask for a stream of the desired type.
                AssetFileDescriptor descr = context.getContentResolver()
                        .openTypedAssetFileDescriptor(uri, "text/*", null);
                stream = descr.createInputStream();
                InputStreamReader reader = new InputStreamReader(stream,
                        "UTF-8");

                // Got it... copy the stream into a local string and return it.
                StringBuilder builder = new StringBuilder(128);
                char[] buffer = new char[8192];
                int len;
                while ((len = reader.read(buffer)) > 0) {
                    builder.append(buffer, 0, len);
                }
                return builder.toString();

            } catch (FileNotFoundException e) {
                // Unable to open content URI as text... not really an
                // error, just something to ignore.

            } catch (IOException e) {
                // Something bad has happened.
                Log.w("ClippedData", "Failure loading text", e);
                return e.toString();

            } finally {
                if (stream != null) {
                    try {
                        stream.close();
                    } catch (IOException e) {
                    }
                }
            }

            // If we couldn't open the URI as a stream, then the URI itself
            // probably serves fairly well as a textual representation.
            return uri.toString();
        }

        // Finally, if all we have is an Intent, then we can just turn that
        // into text. Not the most user-friendly thing, but it's something.
        Intent intent = item.getIntent();
        if (intent != null) {
            return intent.toUri(Intent.URI_INTENT_SCHEME);
        }

        // Shouldn't get here, but just in case...
        return "";
    }

}


回答4:

If you just want to "copy and paste" some code into your app, you can use the following.

Copy

String textToCopy = etCodeWindow.getText().toString();

ClipboardManager clipboard = (ClipboardManager) context.getSystemService(Context.CLIPBOARD_SERVICE);
ClipData clip = ClipData.newPlainText(null, textToCopy);
if (clipboard == null) return;
clipboard.setPrimaryClip(clip);

Paste

Get the text to paste

ClipboardManager clipboard = (ClipboardManager) context.getSystemService(Context.CLIPBOARD_SERVICE);
if (clipboard == null) return;
ClipData clip = clipboard.getPrimaryClip();
if (clip == null) return;
ClipData.Item item = clip.getItemAt(0);
if (item == null) return;
CharSequence textToPaste = item.getText();
if (textToPaste == null) return;

or

ClipboardManager clipboard = (ClipboardManager) getSystemService(Context.CLIPBOARD_SERVICE);
try {
    CharSequence textToPaste = clipboard.getPrimaryClip().getItemAt(0).getText();
} catch (Exception e) {
    return;
}

Inserting it at the cursor position

If there is a selection then the selection will be replaced with the paste text.

int start = Math.max(myEditText.getSelectionStart(), 0);
int end = Math.max(myEditText.getSelectionEnd(), 0);
myEditText.getText().replace(Math.min(start, end), Math.max(start, end),
            textToPaste, 0, textToPaste.length());

Notes

  • This answer assumes that you are no longer supporting pre-API 11. If you are then see the edit history.
  • Import android.content.ClipboardManager and android.content.ClipData.
  • I used to just get the paste text in a one liner until I discovered that ClipData was giving a NPE crash sometimes. Now I would either use a try/catch block or check more carefully for nulls.


回答5:

ClipboardManager clipboard = (ClipboardManager) getSystemService(CLIPBOARD_SERVICE); 
String copyedText = clipboard.getText();