Das Android-Framework für die Zwischenablage zum Kopieren und Einfügen unterstützt primitive und komplexe Datentypen, darunter:
- Text strings
- Komplexe Datenstrukturen
- Text- und Binärstreamdaten
- Anwendungs-Assets
Einfache Textdaten werden direkt in der Zwischenablage gespeichert, während komplexe Daten als Referenz gespeichert werden, die die einfügende Anwendung mit einem Contentanbieter auflöst.
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 Text, wie in der folgenden Tabelle dargestellt.
| Komponente | Text kopieren | Text einfügen |
|---|---|---|
| BasicTextField | ✅ | ✅ |
| TextField | ✅ | ✅ |
| SelectionContainer | ✅ |
Sie können beispielsweise den Text auf der Karte im folgenden Snippet in die Zwischenablage kopieren und den kopierten Text in TextField einfügen.
Sie können das Menü zum Einfügen des Texts aufrufen, indem Sie die TextField berühren und 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 verfügbar. Weitere Informationen finden Sie unter Tastaturaktionen verarbeiten.
Mit ClipboardManager kopieren
Mit ClipboardManager können Sie Texte in die Zwischenablage kopieren.
Die Methode setText() kopiert das übergebene AnnotatedString-Objekt in die Zwischenablage.
Im folgenden Snippet wird „Hello, clipboard“ 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 tut dasselbe, bietet Ihnen aber mehr Kontrolle.
Ein häufiger Anwendungsfall ist das Kopieren vertraulicher Inhalte wie Passwörter. ClipEntry beschreibt ein Element in der Zwischenablage.
Es enthält ein ClipData-Objekt, das Daten in der Zwischenablage beschreibt.
Die Methode ClipData.newPlainText() ist eine praktische Methode, um ein ClipData-Objekt aus einem String-Objekt zu erstellen.
Sie können das erstellte ClipEntry-Objekt in die Zwischenablage kopieren, indem Sie die Methode setClip() 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() für ClipboardManager aufrufen.
Die Methode getText() gibt ein AnnotatedString-Objekt zurück, wenn ein Text in die Zwischenablage kopiert wird.
Mit dem folgenden Snippet wird Text in der Zwischenablage an den Text in 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.
In Ihrer App können Nutzer Rich Content mit ClipboardManager und ClipEntry kopieren.
Mit dem Modifikator contentReceiver 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 den Inhalt mit einem ContentProvider.
Das folgende Code-Snippet zeigt, wie ein JPEG-Bild in die Zwischenablage kopiert wird.
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 Modifikator contentReceiver können Sie das Einfügen von Rich Content in BasicTextField in der geänderten Komponente verarbeiten.
Im folgenden Code-Snippet wird der eingefügte URI von Bilddaten 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 innerhalb der geänderten Komponente einfügt.
Ein TransferableContent-Objekt wird an die onReceive-Methode übergeben. Es beschreibt die Daten, die in diesem Fall durch Einfügen zwischen Apps übertragen werden können.
Sie können auf das ClipEntry-Objekt zugreifen, indem Sie auf das Attribut clipEntry verweisen.
Ein ClipEntry-Objekt kann mehrere ClipData.Item-Objekte enthalten, wenn der Nutzer beispielsweise mehrere Bilder auswählt und in die Zwischenablage kopiert.
Sie sollten jedes ClipData.Item-Objekt als verwendet oder ignoriert markieren und ein TransferableContent mit den ignorierten ClipData.Item-Objekten zurückgeben, damit der nächste übergeordnete contentReceiver-Modifikator es empfangen kann.
Mit der Methode TransferableContent.hasMediaType() können Sie feststellen, 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 die gleiche Weise für Rich Content handhaben.
Sie können einen URI der eingefügten Daten erhalten.
Die tatsächlichen Daten können aus 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. Daher zeigt Android unter Android 13 (API-Level 33) und höher zusätzlich zum Framework, das Kopieren und Einfügen ermöglicht, eine Standard-UI an, wenn Nutzer Inhalte kopieren. Aufgrund dieser Funktion besteht die Gefahr, dass Benachrichtigungen doppelt gesendet werden. Weitere Informationen zu diesem Sonderfall finden Sie unter Doppelte Benachrichtigungen vermeiden.
Gib Nutzern beim Kopieren in Android 12L (API-Level 32) und niedriger manuell Feedback. Weitere Informationen finden Sie in der Empfehlung.
Sensible Inhalte
Wenn Sie zulassen, dass Nutzer vertrauliche Inhalte wie Passwörter in die Zwischenablage kopieren, muss Ihre App das System darüber informieren, damit die kopierten vertraulichen Inhalte nicht in der Benutzeroberfläche angezeigt werden (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) } }