Les appareils équipés d'Android 7.0 (niveau d'API 24) ou version ultérieure sont compatibles avec le mode multifenêtre. , qui permet aux utilisateurs déplacer des données d'une application à une autre par glisser-déposer.
Les données sont fournies par l'application source, où l'opération démarre. L'application cible, où l'opération se termine, reçoit les données.
Lorsque l'utilisateur commence à faire glisser du contenu, l'application source doit définir le paramètre
l'option DRAG_FLAG_GLOBAL
pour
indiquer que l'utilisateur peut faire glisser
des données vers une autre application.
Étant donné que les données sont déplacées au-delà des limites de l'application, celles-ci partagent l'accès aux données à l'aide d'un URI de contenu. Pour ce faire, vous devez disposer des éléments suivants:
- L'application source doit définir au moins l'une des
DRAG_FLAG_GLOBAL_URI_READ
etDRAG_FLAG_GLOBAL_URI_WRITE
d'options, en fonction de l'accès en lecture ou en écriture aux données que l'application source souhaite accorder à l'application cible. - L'application cible doit appeler
requestDragAndDropPermissions()
immédiatement avant de traiter les données que l'utilisateur fait glisser dans l'application. Si l'application cible n'a plus besoin d'accéder aux données déplacées, l'application peut puis appelezrelease()
activé L'objet renvoyé parrequestDragAndDropPermissions()
Sinon, les autorisations sont libérées lorsque l'activité parent est détruit. Si votre implémentation implique de démarrer une nouvelle activité pour traiter le supprimés, vous devrez accorder à la nouvelle activité les mêmes autorisations. Vous devez définir les données sur les extraits et un indicateur:Kotlin
intent.setClipData(clipData) intent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION)
Java
intent.setClipData(clipData); intent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);
Les extraits de code suivants montrent comment accorder un accès en lecture seule à les données glissées immédiatement après que l'opération de dépôt de l'utilisateur a eu lieu. Consultez le Démonstration du glisser-déposer sur GitHub pour obtenir un exemple plus complet.
Activité de la source
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();
Activité cible
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; });