Как программно скопировать текст в моем приложении для Android?

231

Я создаю приложение для Android и хочу скопировать текстовое значение виджета EditText. Пользователь может нажать Menu+Aзатем, Menu+Cчтобы скопировать значение, но как мне сделать это программно?

Zach
источник
Это в основном повторяющийся вопрос: stackoverflow.com/a/13517876/2116185
user2116185

Ответы:

419

Используйте ClipboardManager#setPrimaryClipметод:

import android.content.ClipboardManager;

// ...

ClipboardManager clipboard = (ClipboardManager) getSystemService(CLIPBOARD_SERVICE); 
ClipData clip = ClipData.newPlainText("label", "Text to copy");
clipboard.setPrimaryClip(clip);

ClipboardManager Справочник по API

FlySwat
источник
7
Использованиеimport android.content.ClipboardManager;
MatheusJardimB
Эта функция работает на API 11+ (включая леденец) или нет?
Ашраф Альшахави
22
Что такое label?
Алаа М.
2
Вы также можете добавить сообщение об успешном завершении копирования, чтобы сообщить пользователю о том, что текст скопированContext context = getApplicationContext(); Toast.makeText(context, "text copied", Toast.LENGTH_LONG).show();
Shady
1
@AlaaM. Я думаю, что этот лоток с клипсой является опцией от LG, и вы не можете контролировать его
Shady
217

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

int sdk = android.os.Build.VERSION.SDK_INT;
if(sdk < android.os.Build.VERSION_CODES.HONEYCOMB) {
    android.text.ClipboardManager clipboard = (android.text.ClipboardManager) getSystemService(Context.CLIPBOARD_SERVICE);
    clipboard.setText("text to clip");
} else {
    android.content.ClipboardManager clipboard = (android.content.ClipboardManager) getSystemService(Context.CLIPBOARD_SERVICE); 
    android.content.ClipData clip = android.content.ClipData.newPlainText("text label","text to clip");
    clipboard.setPrimaryClip(clip);
}

Я предполагаю, что у вас есть что-то вроде следующего, объявленного в манифесте:

<uses-sdk android:minSdkVersion="7" android:targetSdkVersion="14" />
Warpzit
источник
Это не работает, потому что компилятор выдает ошибку: для вызова требуется уровень API 11 (текущий минимум 7): android.content.ClipboardManager # setPrimaryClip line 245 Проблема Android Lint.
JavaRunner
2
Вы добавили target и min sdk в свой манифест? Если да, отключите предупреждение о ворсе.
Warpzit
4
Добавьте следующие 3 строки над вашим методом @SuppressLint ({"NewApi", "NewApi", "NewApi", "NewApi"}), @SuppressWarnings ("deprecation"), @TargetApi (11) ........ Это то, что я сделал, и это работает.
RRTW
2
Может кто-нибудь сказать, пожалуйста, что именно используется labelв newPlainTextметоде? Документация гласит label User-visible label for the clip data.. Но когда он labelвиден пользователю? И какое значение / имя мне следует указать label?
shadyinside
@tannerjohn Я предполагаю, что это какой-то предварительный просмотр, который где-то используется. Но я не знаю где. Но вы могли бы просто использовать один и тот же текст дважды ...
Warpzit
15

Googling приводит вас к android.content.ClipboardManager, и вы можете, как и я, решить, что буфер обмена недоступен в API <11, потому что на странице документации написано «С: API Level 11».

На самом деле существует два класса, второй расширяет первый - android.text.ClipboardManager и android.content.ClipboardManager.

android.text.ClipboardManager существует с API 1, но работает только с текстовым содержимым.

android.content.ClipboardManager является предпочтительным способом работы с буфером обмена, но он недоступен на уровне API <11 (Honeycomb).

Чтобы получить любой из них вам нужен следующий код:

ClipboardManager clipboard = (ClipboardManager) getSystemService(CLIPBOARD_SERVICE);

Но для API <11 вы должны импортировать, android.text.ClipboardManagerа для API> = 11 android.content.ClipboardManager

Вячеслав Тысянчук
источник
14
public void onClick (View v) 
{
    switch (v.getId())
    {
        case R.id.ButtonCopy:
            copyToClipBoard();
            break;
        case R.id.ButtonPaste:
            pasteFromClipBoard();
            break;
        default:
            Log.d(TAG, "OnClick: Unknown View Received!");
            break;
    }
}

// Copy EditCopy text to the ClipBoard
private void copyToClipBoard() 
{
    ClipboardManager clipMan = (ClipboardManager) getSystemService(Context.CLIPBOARD_SERVICE);
    clipMan.setPrimaryClip(editCopy.getText());
}

Вы можете попробовать это ..

ayrina
источник
8

Вот некоторый код для реализации некоторых функций копирования и вставки из EditText (спасибо Warpzit за проверку версии). Вы можете привязать их к событию нажатия кнопки.

public void copy(View v) {      
    int startSelection = txtNotes.getSelectionStart();
    int endSelection = txtNotes.getSelectionEnd();      
    if ((txtNotes.getText() != null) && (endSelection > startSelection ))
    {
        String selectedText = txtNotes.getText().toString().substring(startSelection, endSelection);                
        int sdk = android.os.Build.VERSION.SDK_INT;
        if(sdk < android.os.Build.VERSION_CODES.HONEYCOMB) {
            android.text.ClipboardManager clipboard = (android.text.ClipboardManager) getSystemService(Context.CLIPBOARD_SERVICE);
            clipboard.setText(selectedText);
        } else {
            android.content.ClipboardManager clipboard = (android.content.ClipboardManager) getSystemService(Context.CLIPBOARD_SERVICE); 
            android.content.ClipData clip = android.content.ClipData.newPlainText("WordKeeper",selectedText);
            clipboard.setPrimaryClip(clip);
        }
    }
}   

public void paste(View v) {
    int sdk = android.os.Build.VERSION.SDK_INT;
    if (sdk < android.os.Build.VERSION_CODES.HONEYCOMB) {
        android.text.ClipboardManager clipboard = (android.text.ClipboardManager) getSystemService(Context.CLIPBOARD_SERVICE);
        if (clipboard.getText() != null) {
            txtNotes.getText().insert(txtNotes.getSelectionStart(), clipboard.getText());
        }
    } else {
        android.content.ClipboardManager clipboard = (android.content.ClipboardManager) getSystemService(Context.CLIPBOARD_SERVICE);
        android.content.ClipData.Item item = clipboard.getPrimaryClip().getItemAt(0);
        if (item.getText() != null) {
            txtNotes.getText().insert(txtNotes.getSelectionStart(), item.getText());
        }
    }
}
живи любя
источник
Разве нельзя вызывать методы копирования / вставки / вырезки андроида, не записывая их, как вы делаете? Я сделал пользовательскую панель инструментов для выделения текста с функциональностью, позволяющей пользователю выделять выделенный текст жирным шрифтом / курсивом / подчеркиванием и т. Д., Но после настройки функции по умолчанию копировать / вставлять / вырезать больше не работают, но значки для они все еще появляются?
Для чего нужен "WordKeeper"?
разработчик Android
7

Обновление библиотеки поддержки Android

Начиная с Android Oreo, библиотека поддержки работает только до API 14. Большинство новых приложений, вероятно, также имеют минимальный API 14, и, таким образом, не нужно беспокоиться о проблемах с API 11, упомянутых в некоторых других ответах. Большая часть кода может быть очищена. (Но посмотрите мою историю редактирования, если вы по-прежнему поддерживает более низкие версии.)

копия

ClipboardManager clipboard = (ClipboardManager) getSystemService(Context.CLIPBOARD_SERVICE);
ClipData clip = ClipData.newPlainText("label", selectedText);
if (clipboard == null || clip == null) return;
clipboard.setPrimaryClip(clip);

Вставить

Я добавляю этот код в качестве бонуса, потому что копирование / вставка обычно выполняется парами.

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

Ноты

  • Обязательно импортируйте android.content.ClipboardManagerверсию, а не старую android.text.ClipboardManager. То же самое для ClipData.
  • Если вы не в деятельности, вы можете получить услугу с context.getSystemService().
  • Я использовал блок try / catch для получения текста вставки, потому что может быть несколько вещей null. Вы можете проверить каждый из них, если найдете этот способ более читабельным.
Suragch
источник
1
Для чего нужна «текстовая метка»?
Android-разработчик
@androiddeveloper, я никогда не использовал этот ярлык для чего-либо, но посмотрите этот вопрос и ответ .
Сурагч
Таким образом, несмотря на то, что он говорит, что он виден пользователям, на самом деле это не так, и разработчики используют его в случае необходимости.
Android-разработчик
5

Чтобы включить стандартное копирование / вставку для TextView, U может выбрать один из следующих:

Изменение в файле макета: добавьте свойство ниже к вашему TextView

android:textIsSelectable="true"

В вашем Java-классе напишите эту строку два грамматически.

myTextView.setTextIsSelectable(true);

И долгое нажатие на TextView вы можете увидеть панель действий копирования / вставки.

Король масс
источник
5
ClipboardManager clipboard = (ClipboardManager) getSystemService(CLIPBOARD_SERVICE); 
ClipData clip = ClipData.newPlainText("label", "Text to copy");
if (clipboard == null || clip == null)
    return;
clipboard.setPrimaryClip(clip);

И импорт import android.content.ClipboardManager;

Mor2
источник
3

@FlySwat уже дал правильный ответ, я просто делюсь полным ответом:

Используйте метод ClipboardManager.setPrimaryClip ( http://developer.android.com/reference/android/content/ClipboardManager.html ):

ClipboardManager clipboard = (ClipboardManager) getSystemService(CLIPBOARD_SERVICE); 
ClipData clip = ClipData.newPlainText("label", "Text to copy");
clipboard.setPrimaryClip(clip); 

Где label видимая пользователем метка для данных клипа и textфактический текст в клипе. Согласно официальным документам .

Важно использовать этот импорт:

import android.content.ClipboardManager;
Троица
источник
Почему вы копируете \ вставляете ответы? Что такое лейбл?
AlexS
@AlexS, как я уже сказал, другой друг уже дал правильный ответ, я просто выкладываю другой способ с более подробной информацией, я думаю, что это будет полезно для кого-то
Trinity
1

Вот мой рабочий код

/**
 * Method to code text in clip board
 *
 * @param context context
 * @param text    text what wan to copy in clipboard
 * @param label   label what want to copied
 */
public static void copyCodeInClipBoard(Context context, String text, String label) {
    if (context != null) {
        ClipboardManager clipboard = (ClipboardManager) context.getSystemService(CLIPBOARD_SERVICE);
        ClipData clip = ClipData.newPlainText(label, text);
        if (clipboard == null || clip == null)
            return;
        clipboard.setPrimaryClip(clip);

    }
}
Мехул Богра
источник
Когда вы поделитесь кодом, попробуйте объяснить его. Вы можете посетить и проверить, как ответить на вопрос .
Юнус Темурленк
@YunusTemurlenk Спасибо за ваши предложения, в следующий раз я отредактирую свои ответы с описанием
Mehul Boghra
1

Для Kotlin мы можем использовать следующий метод. Вы можете вставить этот метод внутри действия или фрагмента.

fun copyToClipBoard(context: Context, message: String) {

    val clipBoard = context.getSystemService(Context.CLIPBOARD_SERVICE) as ClipboardManager
    val clipData = ClipData.newPlainText("label",message)
    clipBoard.setPrimaryClip(clipData)

}
Виджаякумар Г
источник
Спасибо! Это context.была та часть, по которой я скучал - возможно, потому что я делаю это внутри фрагмента.
Cullub