Das Android-Framework für das Kopieren und Einfügen über die Zwischenablage unterstützt einfache und komplexe Datentypen, darunter:
- Text strings
- Komplexe Datenstrukturen
- Text- und Binärstreamdaten
- App-Assets
Einfache Textdaten werden direkt in der Zwischenablage gespeichert, während komplexe Daten als Referenz gespeichert werden, die von der einfügenden Anwendung mit einem Contentanbieter aufgelöst wird.
Das Kopieren und Einfügen funktioniert sowohl innerhalb einer Anwendung als auch zwischen Anwendungen, die das Framework implementieren.
Da ein Teil des Frameworks Contentanbieter verwendet, wird in diesem Dokument davon ausgegangen, dass Sie mit der Android Content Provider API vertraut sind.
Mit Text arbeiten
Einige Komponenten unterstützen das Kopieren und Einfügen von Texten direkt, wie in der folgenden Tabelle gezeigt.
| Komponente | Text kopieren | Text einfügen |
|---|---|---|
| BasicTextField | ✅ | ✅ |
| TextField | ✅ | ✅ |
| SelectionContainer | ✅ |
Sie können beispielsweise den Text in der Karte im folgenden Snippet in die Zwischenablage kopieren und den kopierten Text in das TextField einfügen.
Sie können das Menü zum Einfügen des Texts aufrufen, indem Sie das TextField gedrückt halten oder auf den Cursorgriff tippen.
val textFieldState = rememberTextFieldState() Column { Card { SelectionContainer { Text("You can copy this text") } } BasicTextField(state = textFieldState) }
Sie können den Text mit der folgenden Tastenkombination einfügen: Strg+V . Die Tastenkombination ist standardmäßig auch verfügbar. Weitere Informationen finden Sie unter Tastaturaktionen verarbeiten.
Mit ClipboardManager kopieren
Sie können Texte mit ClipboardManager in die Zwischenablage kopieren.
Mit der Methode „setText()“ wird das übergebene AnnotatedString Objekt in die Zwischenablage kopiert.
Im folgenden Snippet wird „Hallo, Zwischenablage“ in die Zwischenablage kopiert, wenn der Nutzer auf die Schaltfläche klickt.
// Retrieve a ClipboardManager object val clipboardManager = LocalClipboardManager.current Button( onClick = { // Copy "Hello, clipboard" to the clipboard clipboardManager.setText(AnnotatedString("Hello, clipboard")) } ) { Text("Click to copy a text") }
Das folgende Snippet macht dasselbe, bietet aber mehr Kontrolle.
Ein häufiger Anwendungsfall ist das Kopieren sensibler Inhalte,
wie Passwörter. ClipEntry beschreibt ein Element in der Zwischenablage.
Es enthält ein ClipData-Objekt, das Daten in der Zwischenablage beschreibt.
ClipData.newPlainText() Methode ist eine Hilfsmethode zum
Erstellen eines ClipData Objekts aus einem String-Objekt.
Sie können das erstellte ClipEntry Objekt in die Zwischenablage einfügen
indem Sie die setClip() Methode
für das ClipboardManager Objekt aufrufen.
// Retrieve a ClipboardManager object val clipboardManager = LocalClipboardManager.current Button( onClick = { val clipData = ClipData.newPlainText("plain text", "Hello, clipboard") val clipEntry = ClipEntry(clipData) clipboardManager.setClip(clipEntry) } ) { Text("Click to copy a text") }
Mit ClipboardManager einfügen
Sie können auf den in die Zwischenablage kopierten Text zugreifen
indem Sie die Methode getText() aufrufen
für das ClipboardManager-Objekt.
Die Methode getText() gibt ein AnnotatedString-Objekt zurück, wenn ein Text in die Zwischenablage kopiert wird.
Im folgenden Snippet wird der Text in der Zwischenablage an den Text im TextField angehängt.
val textFieldState = rememberTextFieldState() Column { TextField(state = textFieldState) Button( onClick = { // The getText method returns an AnnotatedString object or null val annotatedString = clipboardManager.getText() if (annotatedString != null) { // The pasted text is placed on the tail of the TextField textFieldState.edit { append(annotatedString.text) } } } ) { Text("Click to paste the text in the clipboard") } }
Mit Rich Content arbeiten
Nutzer lieben Bilder, Videos und andere ausdrucksstarke Inhalte.
Ihre App kann es Nutzern ermöglichen, Rich Content mit ClipboardManager und ClipEntry zu kopieren.
Mit dem contentReceiver Modifikator können Sie das Einfügen von Rich Content implementieren.
Rich Content kopieren
Ihre App kann Rich Content nicht direkt in die Zwischenablage kopieren.
Stattdessen übergibt Ihre App ein URI Objekt an die Zwischenablage
und ermöglicht den Zugriff auf die Inhalte mit einem ContentProvider.
Im folgenden Code-Snippet wird gezeigt, wie Sie ein JPEG-Bild in die Zwischenablage kopieren.
Weitere Informationen finden Sie unter Datenstreams kopieren.
// Get a reference to the context val context = LocalContext.current Button( onClick = { // URI of the copied JPEG data val uri = Uri.parse("content://your.app.authority/0.jpg") // Create a ClipData object from the URI value // A ContentResolver finds a proper ContentProvider so that ClipData.newUri can set appropriate MIME type to the given URI val clipData = ClipData.newUri(context.contentResolver, "Copied", uri) // Create a ClipEntry object from the clipData value val clipEntry = ClipEntry(clipData) // Copy the JPEG data to the clipboard clipboardManager.setClip(clipEntry) } ) { Text("Copy a JPEG data") }
Rich Content einfügen
Mit dem contentReceiver-Modifikator können Sie das Einfügen von Rich Content
in BasicTextField in der geänderten Komponente verarbeiten.
Im folgenden Code-Snippet wird die eingefügte URI eines Bildes
einer Liste von Uri Objekten hinzugefügt.
// A URI list of images val imageList = remember { mutableStateListOf<Uri>() } // Remember the ReceiveContentListener object as it is created inside a Composable scope val receiveContentListener = remember { ReceiveContentListener { transferableContent -> // Handle the pasted data if it is image data when { // Check if the pasted data is an image or not transferableContent.hasMediaType(MediaType.Image) -> { // Handle for each ClipData.Item object // The consume() method returns a new TransferableContent object containging ignored ClipData.Item objects transferableContent.consume { item -> val uri = item.uri if (uri != null) { imageList.add(uri) } // Mark the ClipData.Item object consumed when the retrieved URI is not null uri != null } } // Return the given transferableContent when the pasted data is not an image else -> transferableContent } } } val textFieldState = rememberTextFieldState() BasicTextField( state = textFieldState, modifier = Modifier .contentReceiver(receiveContentListener) .fillMaxWidth() .height(48.dp) )
Der Modifikator contentReceiver verwendet ein ReceiveContentListener-Objekt
als Argument und ruft die Methode onReceive
des übergebenen Objekts auf, wenn der Nutzer Daten
in das BasicTextField in der geänderten Komponente einfügt.
An die Methode „onReceive“ wird ein TransferableContent-Objekt übergeben,
das die Daten beschreibt, die zwischen Apps übertragen werden können
in diesem Fall durch Einfügen.
Sie können auf das ClipEntry-Objekt zugreifen, indem Sie auf das Attribut clipEntry verweisen.
Ein ClipEntry-Objekt kann mehrere ClipData.Item-Objekte
haben, wenn der Nutzer beispielsweise mehrere Bilder auswählt und in die Zwischenablage kopiert.
Sie sollten für jedes ClipData.Item-Objekt „Verbraucht“ oder „Ignoriert“ markieren und ein TransferableContent-Objekt zurückgeben, das die ignorierten ClipData.Item-Objekte enthält, damit der nächste übergeordnete Modifikator contentReceiver es empfangen kann.
Die TransferableContent.hasMediaType()-Methode kann Ihnen helfen, festzustellen
, ob das TransferableContent-Objekt ein Element
mit dem Medientyp bereitstellen kann.
Der folgende Methodenaufruf gibt beispielsweise true zurück, wenn das TransferableContent-Objekt ein Bild bereitstellen kann.
transferableContent.hasMediaType(MediaType.Image)
Mit komplexen Daten arbeiten
Sie können komplexe Daten auf dieselbe Weise in die Zwischenablage kopieren wie Rich Content. Weitere Informationen finden Sie unter Contentanbieter zum Kopieren komplexer Daten verwenden.
Sie können das Einfügen komplexer Daten auch auf dieselbe Weise wie Rich Content verarbeiten.
Sie können eine URI der eingefügten Daten empfangen.
Die tatsächlichen Daten können von einem ContentProvider abgerufen werden.
Weitere Informationen finden Sie unter Daten vom Anbieter abrufen.
Feedback zum Kopieren von Inhalten
Nutzer erwarten Feedback, wenn sie Inhalte in die Zwischenablage kopieren. Zusätzlich zum Framework, das das Kopieren und Einfügen ermöglicht, wird Nutzern in Android 13 (API‑Level 33) und höher eine Standardbenutzeroberfläche angezeigt, wenn sie Inhalte kopieren. Aufgrund dieser Funktion besteht das Risiko doppelter Benachrichtigungen. Weitere Informationen zu diesem Grenzfall finden Sie unter Doppelte Benachrichtigungen vermeiden.
Geben Sie Nutzern in Android 12L (API‑Level 32) und niedriger manuell Feedback, wenn sie Inhalte kopieren. Weitere Informationen zur Empfehlung.
Sensible Inhalte
Wenn Sie möchten, dass Nutzer in Ihrer App sensible Inhalte wie Passwörter in die Zwischenablage kopieren können, muss Ihre App das System darüber informieren, damit das System die kopierten sensiblen Inhalte nicht auf der Benutzeroberfläche anzeigt (Abbildung 2).
Sie müssen ClipDescription in ClipData
ein Flag hinzufügen, bevor Sie die Methode setClip() für das Objekt ClipboardManager aufrufen:
// If your app is compiled with the API level 33 SDK or higher. clipData.apply { description.extras = PersistableBundle().apply { putBoolean(ClipDescription.EXTRA_IS_SENSITIVE, true) } } // If your app is compiled with a lower SDK. clipData.apply { description.extras = PersistableBundle().apply { putBoolean("android.content.extra.IS_SENSITIVE", true) } }