Das Android-basierte Clipboard-Framework zum Kopieren und Einfügen unterstützt primitive und komplexe Datentypen, darunter:
- Textstrings
- 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 Anwendung zum Einfügen mit einem Inhaltsanbieter 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 nutzt, In diesem Dokument wird 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 den in der folgenden Tabelle.
Komponente | Text wird kopiert | Text einfügen |
---|---|---|
BasicTextField | ✅ | ✅ |
TextField | ✅ | ✅ |
SelectionContainer | ✅ |
Sie können beispielsweise den Text auf der Karte im folgenden Snippet in die Zwischenablage kopieren und ihn dann in TextField
einfügen.
Sie zeigen das Menü zum Einfügen des Textes mit einer
Touch- & Halten Sie das TextField
gedrückt oder tippen Sie auf den Cursorziehpunkt.
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 ebenfalls standardmäßig verfügbar. Weitere Informationen finden Sie unter Tastaturaktionen verarbeiten.
Mit ClipboardManager
kopieren
Mit ClipboardManager
können Sie Text in die Zwischenablage kopieren.
Die zugehörige Methode setText() kopiert
das übergebene String-Objekt in die Zwischenablage.
Mit dem folgenden Snippet wird „Hallo, Zwischenablage“ kopiert.
in die Zwischenablage einfügen, 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("Hello, clipboard")
}
) {
Text("Click to copy a text")
}
Das folgende Snippet führt dasselbe aus, bietet aber mehr Kontrolle.
Ein häufiger Anwendungsfall ist das Kopieren vertraulicher Inhalte, z. B. Passwörter. Mit ClipEntry
wird ein Element in der Zwischenablage beschrieben.
Es enthält ein ClipData
-Objekt, das Daten in der Zwischenablage beschreibt.
Die Methode ClipData.newPlainText()
ist eine praktische Methode,
ein ClipData
-Objekt aus einem String-Objekt erstellen.
Sie können das erstellte ClipEntry
-Objekt in die Zwischenablage kopieren, indem Sie die Methode setClip() über 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
Du kannst auf den in die Zwischenablage kopierten Text zugreifen
durch Aufrufen der Methode getText()
über ClipboardManager
.
Die getText()
-Methode gibt ein AnnotatedString
-Objekt zurück.
Ein Text aus der Zwischenablage wird kopiert.
Im folgenden Snippet wird der Text in der Zwischenablage an den Text in TextField
angehängt.
var 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(text.toString())
}
}
}
) {
Text("Click to paste the text in the clipboard")
}
}
Mit Rich Content arbeiten
Nutzer mögen Bilder, Videos und andere ausdrucksstarke Inhalte.
Ihre App kann es Nutzern ermöglichen, Rich Content mit
ClipboardManager
und ClipEntry
.
Mit dem Modifikator contentReceiver
können Sie das Einfügen von Rich-Content implementieren.
Rich Content kopieren
Ihre App kann keine Rich Content-Inhalte direkt in die Zwischenablage kopieren.
Stattdessen übergibt Ihre App ein URI
-Objekt an die Zwischenablage und gewährt über ein ContentProvider
Zugriff auf die Inhalte.
Im folgenden Code-Snippet wird gezeigt, 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 Rich-Content in der geänderten Komponente in BasicTextField
einfügen.
Mit dem folgenden Code-Snippet wird der eingefügte URI eines Bilddaten-Snippets hinzugefügt.
zu einer Liste von Uri
-Objekten hinzu.
// A URI list of images
val imageList by remember{ mutableListOf<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
nimmt ein ReceiveContentListener
-Objekt als Argument an und ruft die Methode onReceive
des übergebenen Objekts auf, wenn der Nutzer Daten in die BasicTextField
innerhalb der geänderten Komponente einfügt.
Ein TransferableContent
-Objekt wird an die onReceive-Methode übergeben,
Hier werden die Daten beschrieben, die zwischen Apps übertragen werden können.
in diesem Fall durch Einfügen.
Sie können auf das ClipEntry
-Objekt zugreifen, indem Sie sich auf das clipEntry
-Attribut beziehen.
Ein ClipEntry
-Objekt kann mehrere ClipData.Item
-Objekte haben, wenn der Nutzer beispielsweise mehrere Bilder auswählt und in die Zwischenablage kopiert.
Sie sollten jedes ClipData.Item
-Objekt als „verbraucht“ oder „ignoriert“ kennzeichnen und ein TransferableContent
mit den ignorierten ClipData.Item
-Objekten zurückgeben, damit es vom nächstgelegenen übergeordneten contentReceiver
-Modifikator empfangen werden kann.
Mit der Methode TransferableContent.hasMediaType()
kannst du feststellen, ob das TransferableContent
-Objekt ein Element mit dem Medientyp bereitstellen kann.
Der folgende Methodenaufruf gibt beispielsweise true
zurück.
Das TransferableContent
-Objekt kann ein Bild bereitstellen.
transferableContent.hasMediaType(MediaType.Image)
Mit komplexen Daten arbeiten
Sie können komplexe Daten in die Zwischenablage kopieren genauso wie bei Rich Content. Weitere Informationen finden Sie unter Inhaltsanbieter zum Kopieren komplexer Daten verwenden.
Sie können auch das Einfügen komplexer Daten
auf die gleiche Weise für Rich Content.
Sie können einen URI für die 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
Nutzende erwarten Feedback, wenn sie Inhalte in die Zwischenablage kopieren, Neben dem Framework, das Kopieren und Einfügen ermöglicht, Android zeigt Nutzern beim Kopieren unter Android 13 (API-Level 33) eine Standard-UI an. und höher. Aufgrund dieser Funktion besteht das Risiko, dass Sie doppelte Benachrichtigungen erhalten. Weitere Informationen zu diesem Grenzfall finden Sie unter Doppelte Benachrichtigungen vermeiden.
Nutzern manuell Feedback geben beim Kopieren in Android 12L (API-Level 32) und niedriger. Weitere Informationen finden Sie in der Empfehlung.
Sensible Inhalte
Wenn Sie in Ihrer App zulassen, dass Nutzer sensible Inhalte wie Passwörter in die Zwischenablage kopieren, muss Ihre App das System darüber informieren, damit das System die kopierten sensiblen Inhalte nicht in der Benutzeroberfläche anzeigt (Abbildung 2).
Du musst ClipDescription
in ClipData
ein Flag hinzufügen, bevor du die setClip()
-Methode über das ClipboardManager
-Objekt aufrufst:
// 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)
}
}