Drag-and-drop im Mehrfenstermodus
Mit Sammlungen den Überblick behalten
Sie können Inhalte basierend auf Ihren Einstellungen speichern und kategorisieren.
Geräte mit Android 7.0 (API-Level 24) oder höher unterstützen den Mehrfenstermodus
, mit der Nutzer
Daten per Drag-and-drop von einer App in eine andere verschieben.
Die Daten werden von der Quellanwendung bereitgestellt, in der der Vorgang beginnt.
Die Zielanwendung, in der der Vorgang endet, empfängt die Daten.
Wenn der Nutzer beginnt, Inhalte zu ziehen, sollte die Quell-App
DRAG_FLAG_GLOBAL
-Flag in
anzeigen, dass der Nutzer Daten in eine andere App ziehen kann.
Da die Daten über Anwendungsgrenzen hinweg verschoben werden, teilen die Anwendungen den Zugriff auf die Daten.
mit einem Inhalts-URI. Dazu ist Folgendes erforderlich:
- Die Quell-App muss eines oder beide der
DRAG_FLAG_GLOBAL_URI_READ
und
DRAG_FLAG_GLOBAL_URI_WRITE
Flags, je nach Lese- oder Schreibzugriff auf die Daten, die die Quellanwendung
die Sie der Ziel-App gewähren möchten.
- Die Ziel-App muss
requestDragAndDropPermissions()
unmittelbar bevor er die Daten verarbeitet,
die Nutzende in die App ziehen. Wenn
die Ziel-App keinen Zugriff mehr
auf die per Drag-and-drop eingefügten Daten benötigt,
dann anrufen
release()
an
Das Objekt, das von requestDragAndDropPermissions()
zurückgegeben wurde.
Andernfalls werden die Berechtigungen freigegeben, wenn die enthaltende Aktivität
zerstört.
Wenn Ihre Implementierung das Starten einer neuen Aktivität zur Verarbeitung des
entfernten URIs enthalten ist, müssen Sie der neuen Activity-Klasse dieselben Berechtigungen erteilen.
Du musst die Clipdaten und ein Flag festlegen:
Kotlin
intent.setClipData(clipData)
intent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION)
Java
intent.setClipData(clipData);
intent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);
Die folgenden Code-Snippets veranschaulichen, wie der schreibgeschützte Zugriff
die per Drag-and-drop eingefügt werden. Weitere Informationen finden Sie in der
Drag-and-drop-Demo
auf GitHub.
Quellaktivität
Kotlin
// Drag a file stored in an images/ directory in internal storage.
val internalImagesDir = File(context.filesDir, "images")
val imageFile = File(internalImagesDir, imageFilename)
val uri = FileProvider.getUriForFile(context, contentAuthority, imageFile)
val listener = OnDragStartListener@{ view: View, _: DragStartHelper ->
val clipData = ClipData(ClipDescription("Image Description",
arrayOf("image/*")),
ClipData.Item(uri))
// Must include DRAG_FLAG_GLOBAL to permit dragging data between apps.
// This example provides read-only access to the data.
val flags = View.DRAG_FLAG_GLOBAL or View.DRAG_FLAG_GLOBAL_URI_READ
return@OnDragStartListener view.startDragAndDrop(clipData,
View.DragShadowBuilder(view),
null,
flags)
}
// Container where the image originally appears in the source app.
val srcImageView = findViewById<ImageView>(R.id.imageView)
// Detect and start the drag event.
DragStartHelper(srcImageView, listener).apply {
attach()
}
Java
// Drag a file stored in an images/ directory in internal storage.
File internalImagesDir = new File(context.getFilesDir(), "images");
File imageFile = new File(internalImagesDir, imageFilename);
final Uri uri = FileProvider.getUriForFile(context, contentAuthority, imageFile);
// Container where the image originally appears in the source app.
ImageView srcImageView = findViewById(R.id.imageView);
// Enable the view to detect and start the drag event.
new DragStartHelper(srcImageView, (view, helper) -> {
ClipData clipData = new ClipData(new ClipDescription("Image Description",
new String[] {"image/*"}),
new ClipData.Item(uri));
// Must include DRAG_FLAG_GLOBAL to permit dragging data between apps.
// This example provides read-only access to the data.
int flags = View.DRAG_FLAG_GLOBAL | View.DRAG_FLAG_GLOBAL_URI_READ;
return view.startDragAndDrop(clipData,
new View.DragShadowBuilder(view),
null,
flags);
}).attach();
Zielaktivität
Kotlin
// Container where the image is to be dropped in the target app.
val targetImageView = findViewById<ImageView>(R.id.imageView)
targetImageView.setOnDragListener { view, event ->
when (event.action) {
ACTION_DROP -> {
val imageItem: ClipData.Item = event.clipData.getItemAt(0)
val uri = imageItem.uri
// Request permission to access the image data being dragged into
// the target activity's ImageView element.
val dropPermissions = requestDragAndDropPermissions(event)
(view as ImageView).setImageURI(uri)
// Release the permission immediately afterward because it's no
// longer needed.
dropPermissions.release()
return@setOnDragListener true
}
// Implement logic for other DragEvent cases here.
// An unknown action type is received.
else -> {
Log.e("DragDrop Example", "Unknown action type received by View.OnDragListener.")
return@setOnDragListener false
}
}
}
Java
// Container where the image is to be dropped in the target app.
ImageView targetImageView = findViewById(R.id.imageView);
targetImageView.setOnDragListener( (view, event) -> {
switch (event.getAction()) {
case ACTION_DROP:
ClipData.Item imageItem = event.getClipData().getItemAt(0);
Uri uri = imageItem.getUri();
// Request permission to access the image data being dragged into
// the target activity's ImageView element.
DragAndDropPermissions dropPermissions =
requestDragAndDropPermissions(event);
((ImageView)view).setImageURI(uri);
// Release the permission immediately afterward because it's no
// longer needed.
dropPermissions.release();
return true;
// Implement logic for other DragEvent cases here.
// An unknown action type was received.
default:
Log.e("DragDrop Example","Unknown action type received by View.OnDragListener.");
break;
}
return false;
});
Alle Inhalte und Codebeispiele auf dieser Seite unterliegen den Lizenzen wie im Abschnitt Inhaltslizenz beschrieben. Java und OpenJDK sind Marken oder eingetragene Marken von Oracle und/oder seinen Tochtergesellschaften.
Zuletzt aktualisiert: 2025-07-27 (UTC).
[[["Leicht verständlich","easyToUnderstand","thumb-up"],["Mein Problem wurde gelöst","solvedMyProblem","thumb-up"],["Sonstiges","otherUp","thumb-up"]],[["Benötigte Informationen nicht gefunden","missingTheInformationINeed","thumb-down"],["Zu umständlich/zu viele Schritte","tooComplicatedTooManySteps","thumb-down"],["Nicht mehr aktuell","outOfDate","thumb-down"],["Problem mit der Übersetzung","translationIssue","thumb-down"],["Problem mit Beispielen/Code","samplesCodeIssue","thumb-down"],["Sonstiges","otherDown","thumb-down"]],["Zuletzt aktualisiert: 2025-07-27 (UTC)."],[],[],null,["# Drag and drop in multi-window mode\n\nDevices that run Android 7.0 (API level 24) or higher support [multi-window\nmode](/develop/ui/views/layout/support-multi-window-mode), which lets users\nmove data from one app to another by dragging and dropping.\n\nThe *source app* , where the operation starts, provides the data.\nThe *target app*, where the operation ends, receives the data.\n\nWhen the user starts to drag content, the source app should set the\n[`DRAG_FLAG_GLOBAL`](/reference/android/view/View#DRAG_FLAG_GLOBAL) flag to\nindicate that the user can drag data to another app.\n\nBecause the data moves across app boundaries, the apps share access to the data\nusing a content URI. This requires the following:\n\n- The source app must set either or both of the [`DRAG_FLAG_GLOBAL_URI_READ`](/reference/android/view/View#DRAG_FLAG_GLOBAL_URI_READ) and [`DRAG_FLAG_GLOBAL_URI_WRITE`](/reference/android/view/View#DRAG_FLAG_GLOBAL_URI_WRITE) flags, depending on the read or write access to the data that the source app wants to grant to the target app.\n- The target app must call [`requestDragAndDropPermissions()`](/reference/android/app/Activity#requestDragAndDropPermissions(android.view.DragEvent)) immediately before handling the data that the user drags into the app. If the target app no longer needs access to the dragged data, the app can then call [`release()`](/reference/android/view/DragAndDropPermissions#release()) on the object that was returned from `requestDragAndDropPermissions()`. Otherwise, the permissions are released when the containing activity is destroyed. If your implementation involves starting a new Activity to process the dropped URIs, you will need to grant the new Activity the same permissions. You must set the clip data and a flag: \n\n ### Kotlin\n\n ```kotlin\n intent.setClipData(clipData)\n intent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION)\n ```\n\n ### Java\n\n ```java\n intent.setClipData(clipData);\n intent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);\n ```\n\nThe following code snippets demonstrate how to release read-only access to\ndragged data immediately after the user drop operation takes place. See the\n[Drag and Drop Demo](https://github.com/android/user-interface-samples/tree/main/DragAndDrop)\non GitHub for a more complete example.\n\nSource activity\n---------------\n\n### Kotlin\n\n```kotlin\n// Drag a file stored in an images/ directory in internal storage.\nval internalImagesDir = File(context.filesDir, \"images\")\nval imageFile = File(internalImagesDir, imageFilename)\nval uri = FileProvider.getUriForFile(context, contentAuthority, imageFile)\n\nval listener = OnDragStartListener@{ view: View, _: DragStartHelper -\u003e\n val clipData = ClipData(ClipDescription(\"Image Description\",\n arrayOf(\"image/*\")),\n ClipData.Item(uri))\n // Must include DRAG_FLAG_GLOBAL to permit dragging data between apps.\n // This example provides read-only access to the data.\n val flags = View.DRAG_FLAG_GLOBAL or View.DRAG_FLAG_GLOBAL_URI_READ\n return@OnDragStartListener view.startDragAndDrop(clipData,\n View.DragShadowBuilder(view),\n null,\n flags)\n}\n\n// Container where the image originally appears in the source app.\nval srcImageView = findViewById\u003cImageView\u003e(R.id.imageView)\n\n// Detect and start the drag event.\nDragStartHelper(srcImageView, listener).apply {\n attach()\n}\n```\n\n### Java\n\n```java\n// Drag a file stored in an images/ directory in internal storage.\nFile internalImagesDir = new File(context.getFilesDir(), \"images\");\nFile imageFile = new File(internalImagesDir, imageFilename);\nfinal Uri uri = FileProvider.getUriForFile(context, contentAuthority, imageFile);\n\n// Container where the image originally appears in the source app.\nImageView srcImageView = findViewById(R.id.imageView);\n\n// Enable the view to detect and start the drag event.\nnew DragStartHelper(srcImageView, (view, helper) -\u003e {\n ClipData clipData = new ClipData(new ClipDescription(\"Image Description\",\n new String[] {\"image/*\"}),\n new ClipData.Item(uri));\n // Must include DRAG_FLAG_GLOBAL to permit dragging data between apps.\n // This example provides read-only access to the data.\n int flags = View.DRAG_FLAG_GLOBAL | View.DRAG_FLAG_GLOBAL_URI_READ;\n return view.startDragAndDrop(clipData,\n new View.DragShadowBuilder(view),\n null,\n flags);\n}).attach();\n```\n\nTarget activity\n---------------\n\n### Kotlin\n\n```kotlin\n// Container where the image is to be dropped in the target app.\nval targetImageView = findViewById\u003cImageView\u003e(R.id.imageView)\n\ntargetImageView.setOnDragListener { view, event -\u003e\n\n when (event.action) {\n\n ACTION_DROP -\u003e {\n val imageItem: ClipData.Item = event.clipData.getItemAt(0)\n val uri = imageItem.uri\n\n // Request permission to access the image data being dragged into\n // the target activity's ImageView element.\n val dropPermissions = requestDragAndDropPermissions(event)\n (view as ImageView).setImageURI(uri)\n\n // Release the permission immediately afterward because it's no\n // longer needed.\n dropPermissions.release()\n return@setOnDragListener true\n }\n\n // Implement logic for other DragEvent cases here.\n\n // An unknown action type is received.\n else -\u003e {\n Log.e(\"DragDrop Example\", \"Unknown action type received by View.OnDragListener.\")\n return@setOnDragListener false\n }\n\n }\n}\n```\n\n### Java\n\n```java\n// Container where the image is to be dropped in the target app.\nImageView targetImageView = findViewById(R.id.imageView);\n\ntargetImageView.setOnDragListener( (view, event) -\u003e {\n\n switch (event.getAction()) {\n\n case ACTION_DROP:\n ClipData.Item imageItem = event.getClipData().getItemAt(0);\n Uri uri = imageItem.getUri();\n\n // Request permission to access the image data being dragged into\n // the target activity's ImageView element.\n DragAndDropPermissions dropPermissions =\n requestDragAndDropPermissions(event);\n\n ((ImageView)view).setImageURI(uri);\n\n // Release the permission immediately afterward because it's no\n // longer needed.\n dropPermissions.release();\n\n return true;\n\n // Implement logic for other DragEvent cases here.\n\n // An unknown action type was received.\n default:\n Log.e(\"DragDrop Example\",\"Unknown action type received by View.OnDragListener.\");\n break;\n }\n\n return false;\n});\n```"]]