Receiver App Example: DragAndReceiver

 

The sample application consists of the following files:

 

Files

Description

\src\com\lge\example\dropandreceive\MainActivity.java

Main activity class

\res\layout\activity_main.xml

Layout file for the main activity in Full screen

\res\values\strings.xml

the file including string values

AndroidManifest.xml

manifest file

 

Modifying the AndroidManifest.xml

The AndroidManifest file should be modified.

...
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE"/> ①
<application
...
    <meta-data
        android:name="com.lge.support.SPLIT_WINDOW" ②
        android:value="true" />
    <activity
        android:name="com.lge.example.dropandreceive.MainActivity ③
        ...>
        <intent-filter>
            <action android:name="android.intent.action.MAIN" />
            <category android:name="android.intent.category.LAUNCHER" />
        </intent-filter>
    </activity>
</application>

① The reading external storage permission for dragged image URI from other Dual window applications
② The metadata of the application to be executed in Split window
③ If the application has the above metadata, its main/launcher activity can be included in the Dual window App Drawer

 

Getting Ready

The sample application sets the main layout and retrieves views.

private Context mContext;
private Button button;
private ImageView imageView;
@Override
protected void onCreate(Bundle savedInstanceState) {
...
setContentView(R.layout.activity_main);
mContext = this.getApplicationContext();
button = (Button) findViewById(R.id.id_button);
imageView = (ImageView) findViewById(R.id.id_imageView);
....
}

 

Setting the DragListener to the View to be dropped

....
button.setOnDragListener(draglistener); ①
imageView.setOnDragListener(draglistener); ②
....

① Set the DragListener to the button on which the dragged text will be dropped.
② Set the DragListener to the ImageView on which the dragged image URI will be dropped

 

Implementing DragListener

You can handle the drag event by implementing the DragListener.

View.OnDragListener draglistener = new View.OnDragListener() {

@Override
public boolean onDrag(View v, DragEvent event) {
switch (event.getAction()) { ①
case DragEvent.ACTION_DRAG_STARTED: ②
...
return true;

case DragEvent.ACTION_DRAG_ENTERED: ③
...
v.requestFocus();
break;

case DragEvent.ACTION_DRAG_LOCATION: ④
float x = event.getX();
float y = event.getY();
...
break;

case DragEvent.ACTION_DROP: ⑤
return onDrop(v, event);
...
case DragEvent.ACTION_DRAG_ENDED: ⑥
...
break;

case DragEvent.ACTION_DRAG_EXITED: ⑦
...
break;
}
return true;
}
};

① perform necessary tasks when the drag shadow is no longer within the bounding box of the listener's View.Get the action types of DragEvent by calling getAction()
② Perform necessary tasks when the drag and drop is started.
③ Get the focus for the View by calling requestFocus() when the drag point has entered the bounding box of the View.
④ Get the location of the drag touch point.
⑤ Perform necessary tasks when the view is dropped.
⑥ Perform necessary tasks when the drag and drop is finished.
⑦ Perform necessary tasks when the drag shadow is no longer within the bounding box of the listener's View.

 

Responding to the Drop

In response to the drop, the application gets the ClipData and processes it appropriately.

 

Getting the Text ClipData

If the dragged object is text, the application gets the text in ClipData directly.

private boolean onDrop(View v, DragEvent event) {
// Let's put the Text on the Button.
if(v instanceof Button &&
event.getClipData().getItemAt(0).getText() != null) { ①
ClipData clip = event.getClipData(); ②
ClipData.Item item = clip.getItemAt(0); ③
button.setText(item.getText()); ④
...
return true;
}
...
}

① determine whether the dragged object is text
② get the ClipData object
③ get the actual text from ClipData.Item in ClipData object.
④ change the button’s text to the string included in ClipData.Item

 

Getting the URI ClipData

If the dragged object is an image, the application gets the saved URI in ClipData and gets the image indirectly from the URI.

private boolean onDrop(View v, DragEvent event) {
// Let's put the Text on the Button.
if(v instanceof Button &&
event.getClipData().getItemAt(0).getText() != null) {
...
} else if (v instanceof ImageView) { ①
// Handling the dropped clipdata (example)
// Gets the item containing the dragged data
ClipData clip = event.getClipData(); ②
// Gets the text data from the item.
Uri uri = getUri(clip); ③-1
// Null check is essential,
//because clip data couldn't include uri
if(uri != null && hasValidMimeType(clip)){ ④
// Getting the Thumbnail image from the URI
// Setting its thumbnail to the ImageView
...
return true; ⑤
}
}
...
return false; ⑤
}
public static Uri getUri(ClipData clip) { ③-2
if (clip == null) {
return null;
}
ClipData.Item item;
Uri uri;
for (int i = 0 ; i < clip.getItemCount(); i++) {
item = clip.getItemAt(i);
uri = item.getUri();
if(uri != null) {
return uri;
}
}
return null;
}

① determine whether the dragged object is text
② get the ClipData object
③ get the URI in ClipData
④ check if the mimeType of the URI is valid
⑤ If the mimeType is valid, return true. Otherwise, return false

 

Checking whether the MIME type is valid or not

The application gets the mimeType using ClipDescription or URI and checks if the mimeType is valid for the image.

private boolean hasValidMimeType(ClipData clip) { ①
//retrieve the mimeType either ClipDescription or URI in Clip Data
String mimeType = getUriMimeType(this.getApplicationContext(), clip);
//Check whether mimeType is vaild
if(isValidUriMimeType(mimeType)) {
// For the valid mime type, return the ture
return true;
}

// Or, return the false
return false;
}

public static String getUriMimeType(Context context, ClipData clip) { ②
...
// retrieve mimeType inside ClipDescription
String uriMimeType = getUriMimeType(clip.getDescription());
// if there's no mime type in ClipDescription
if(uriMimeType == null) {
//get the mimeType from uri in clip data
uriMimeType = getMimeTypeFromUri(context, uri);
}
...
// return the mime type
return uriMimeType;
}
public static String getUriMimeType(ClipDescription desc) { ③
String uriMimeType = null;
...
// retrieve the mimetype from the ClipDescription
// and return it.
return uriMimeType;
}
public static String getMimeTypeFromUri(Context context, Uri uri) { ④
String mimeType = null;
...
// retrieve the mimetype using the URI in clip data
// and return it.
return mimeType;
}
private boolean isValidUriMimeType(String mimeType) { ⑤
// check if Mime type is valid
if(mimeType != null && mimeType.startsWith("image")) {
return true;
}
return false;
}

① This method returns true if the mimeType is valid, otherwise return false
② This method calls the other methods to get the mimeType and return the mimeType
③ This method gets the mimeType from ClipDescription and return it
④ This method gets the mimeType from the URI in ClipData.Item and return it
⑤ This method checks if the mimeType is valid for the image

 

Getting the Image from the URI and Setting it to the ImageView

The application creates a thumbnail image from the obtained URI and sets it to the ImageView.

Bitmap thumbnail = getThumbnail(this.getApplicationContext(), uri, 8); ...①
if (thumbnail == null) {
Toast.makeText(mContext,
mContext.getString(R.string.contents_toastForError),
Toast.LENGTH_SHORT).show() ②
...
}
...
imageView.setImageBitmap(thumbnail); ③

① creates bitmap thumbnail from obtained URI
② makes a toast to show that thumbnail is not created normally
③ sets the thumbnail to the ImageView of the dragged image that was dropped

 

Navigation