Search code examples
javaandroidfiledrag-and-dropuri

Read file from ClipData in OnDragListener


I'm trying to implement drag and drop feature in the android app that when you drag file from file explorer and drop it in the app, the file will be read and displayed in the app. Without using file picker, only uri from ClipData in OnDragListener.

Is this even possible to make?

When I tryed readin the file like this:

FileInputStream inputStream = getContentResolver().openInputStream(uri);

it shows me this exception

java.lang.SecurityException: UID 10366 does not have permission to content://com.android.externalstorage.documents/document/... [user 0]; you could obtain access using ACTION_OPEN_DOCUMENT or related APIs

and

java.lang.SecurityException: Permission Denial: opening provider com.android.externalstorage.ExternalStorageProvider from ProcessRecord{ecf77b0 23430:com.app.package.name/u0a366} (pid=23430, uid=10366) requires that you obtain access using ACTION_OPEN_DOCUMENT or related APIs

Here is some code for this

dropTarget.setOnDragListener((v, event) -> {
            switch (event.getAction()) {
                ...
                case DragEvent.ACTION_DROP:
                    if (event.getClipDescription().hasMimeType("application/json")) {
                        ClipData.Item item = event.getClipData().getItemAt(0);
                        readFile(item.getUri());

                    }
                    return true;
            }

            return false;
        });
void readFile(Uri uri){
            FileInputStream inputStream = getContentResolver().openInputStream(uri);
            BufferedReader reader = new BufferedReader(new InputStreamReader(inputStream));

            //Reading file
            ...
}

Solution

  • Thanks to blackapps comment the issue is that I was not requesting DragAndDrop Permissions. Just needed to add this code in setOnDragListener:

    DragAndDropPermissions dropPermissions = null;
    if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.N) {
             dropPermissions = requestDragAndDropPermissions(event);
    }
    
    readFile(item.getUri());
    
    if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.N && dropPermissions != null) {
             dropPermissions.release();
    }