Be Careful of Drag-and-Drop on Android N

As part of a forthcoming book update, I began working
with the revised drag-and-drop APIs for Android N. Drag-and-drop has
been part of Android since 3.0, but since it is limited to a single
activity, it does not seem to be all that popular. Now, with multi-window
support, drag-and-drop can work between apps��� and that is where
you need to be careful.



When you start a drag-and-drop operation via startDragAndDrop()
(or the earlier startDrag()), you can include DRAG_FLAG_GLOBAL
in the request. This indicates that you want the drag-and-drop operation
to work between apps. Without this flag, the drag-and-drop is limited
to your own app. This is wonderful: it is an easy change, but apps
do not accidentally leak data by default.



However, I cannot find an equivalent for handling drops.





When you register a drop target with setOnDragListener(), there is
no flag to say that you want to support cross-app drag-and-drop requests




When you get a DragEvent, there is no built-in means to determine
whether the event arose from your app or from another app





Hence, if you implement drag-and-drop,
you can get drag events originating from other apps on Android N,
without any changes to your code to say that you want this behavior.



IMHO, this is not a good idea. Accepting foreign drag events should
be something you opt into. With luck,
this will get addressed,
though I do not hold out tons of hope.



If you have been using drag-and-drop purely within your app, and you
want your drop target to know whether a DragEvent is from your app
or from another app, you can use a slight hack: pass a non-null
value for the third parameter to startDrag()/startDragAndDrop().
This is called the ���local state���, and the name is accurate: it does not appear
to be passed across process boundaries. For any DragEvent delivered to your
drop target, you can call getLocalState() on the DragEvent to get
the local state value. If that is not null, then you know the
DragEvent initiated in your app. If the local state is null ���
and you are sure that you are providing a value for it in all of your
startDrag()/startDragAndDrop() calls ��� then you know that the
DragEvent came from another app.



Ideally, eventually you support cross-app drag-and-drop. But, since you
are not in control over DragEvent objects originating from other
apps, you will need a lot more defensive programming in your drop target
code. You might be expecting a Uri and get a String, for example.

 •  0 comments  •  flag
Share on Twitter
Published on June 01, 2016 11:04
No comments have been added yet.