Освой Android играючи
/* Моя кошка замечательно разбирается в программировании. Стоит мне объяснить проблему ей - и все становится ясно. */
John Robbins, Debugging Applications, Microsoft Press, 2000
Пример копирования и вставки текста (Kotlin)
Слушатель для буфера обмена
Android поддерживает функции копирования-вставки. Работа с буфером обмена в целом идентична работе с аналогичной функциональностью в Windows. Мы копируем данные в одном приложении и вставляем данные в другом приложении/активности или в другом объекте этого же экрана.
На сайте разработки под Android есть картинка, иллюстрирующая работу с буфером обмена

Копировать можно текстовые строки, URI, Intent. Буфер обмена может содержать один объект, поэтому каждый новый копируемый объект вытесняет предыдущий.
Для работы с буфером обмена предназначен класс ClipBoardManager.
Существует устаревший класс из пакета android.text и новый класс из пакета android.content. Будьте бдительны, не путайте их при импорте классов. Также у нового класса есть несколько устаревших методов типа getText() и setText().
Чтобы добавить данные в буфер обмена, необходимо создать объект ClipData, содержащий описание данных и сами данные. Буфер обмена может содержать только один объект ClipData. ClipData содержит объект ClipDescription и один или больше объектов ClipData.Item.
Объект ClipDescription содержит метаданные о скопированном объекте - массив возможных MIME-типов для данных. Когда вы что-то копируете в буфер, данный массив доступен для приложений, которые могут определить, могут ли они работать с этими данными.
Объект ClipData.Item содержит текст, URI или данные для Intent.
Класс ClipData имеет в своём составе несколько удобных методов для создания объекта ClipData, содержащим объект ClipData.Item и объект ClipDescription:
Метод coerceToText() позволяет преобразовать скопированные данные в текст. Если в буфере содержится текст, то он так и останется текстом, а если содержит URI или Intent, то данные будет преобразованы (как Uri.toString() и Intent.toUri(URI_INTENT_SCHEME)).
Разместим на экране приложения текстовую метку, из которой будем копировать текст. Вставлять текст будем в текстовое поле. Также нам понадобятся две кнопки для самих операций копирования и вставки текста.
<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".MainActivity">
<Button
android:id="@+id/paste_button"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="32dp"
android:text="Paste From Clipboard"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@+id/textView" />
<Button
android:id="@+id/copy_button"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="16dp"
android:text="Copy To Clipboard"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
<TextView
android:id="@+id/textView"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="16dp"
android:text="Hello Kitty"
android:textAppearance="@style/TextAppearance.AppCompat.Medium"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintTop_toBottomOf="@+id/copy_button" />
<EditText
android:id="@+id/editText"
android:layout_width="409dp"
android:layout_height="wrap_content"
android:layout_marginStart="8dp"
android:layout_marginTop="16dp"
android:layout_marginEnd="8dp"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@+id/paste_button" />
</androidx.constraintlayout.widget.ConstraintLayout>
Теперь напишем код для активности. Первая кнопка копирует текст в буфер обмена, вторая - вставляет из буфера обмена.
// Если этот код работает, его написал Александр Климов,
// а если нет, то не знаю, кто его писал.
package ru.alexanderklimov.hellokot
import android.content.ClipData
import android.content.ClipboardManager
import android.content.Context
import android.os.Bundle
import androidx.appcompat.app.AppCompatActivity
import kotlinx.android.synthetic.main.activity_main.*
class MainActivity : AppCompatActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
val clipboard = getSystemService(Context.CLIPBOARD_SERVICE) as ClipboardManager
copy_button.setOnClickListener {
// Copy text from TextView to clipboard
val textToCopy = textView.text
val clip = ClipData.newPlainText("simple text", textToCopy)
//clipboard.primaryClip = clip // Kotlin-style doesn't work in SDK 29
clipboard.setPrimaryClip(clip)
}
paste_button.setOnClickListener {
// Paste clipboard text to EditText
val clipData: ClipData? = clipboard.primaryClip
clipData?.apply {
val textToPaste: String = this.getItemAt(0).text.toString().trim()
editText.setText(textToPaste)
}
}
}
}
Мы можем отслеживать появление текста в буфере обмена через метод addPrimaryClipChangedListener(). Получим текст из буфера обмена из предыдущего примера не через кнопку вставить, а через слушатель и вставим текст в текстовое поле минуя щелчок кнопки.
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
val clipboard = getSystemService(Context.CLIPBOARD_SERVICE) as ClipboardManager
clipboard.addPrimaryClipChangedListener {
val textToPaste: String = clipboard.primaryClip?.getItemAt(0)?.text.toString().trim()
editText.setText(textToPaste)
}
copy_button.setOnClickListener {
// Copy text from TextView to clipboard
val textToCopy = textView.text
val clip = ClipData.newPlainText("simple text", textToCopy)
//clipboard.primaryClip = clip // Kotlin-style doesn't work in SDK 29
clipboard.setPrimaryClip(clip)
}
paste_button.setOnClickListener {
...
}
}
Забавно, что в эмуляторе буфер обмена работает и в Windows. Скопируйте какой-нибудь текст на компьютере и он появится в текстовом поле в эмуляторе.