Search code examples
androidmediastoreandroid-11storage-access-frameworkscoped-storage

How to copy Images/Videos from DocumentFile Object to Gallery Folder using MediaStore Api


I gained access to this folder using Document Tree Intent :-

content://com.android.externalstorage.documents/tree/primary%3AExampleApp%2FMedia%2F.hiddenMedia

The URI of a image present in the above folder :-

content://com.android.externalstorage.documents/tree/primary%3AExampleFolder%2FMedia%2F.hiddenMedia/document/primary%3AExampleFolder%2FMedia%2F.hiddenMedia%2FCristiano.jpg

Now I have that image as a DocumentFile and its URI from the above folder.

DocumentFile documentFile = DocumentFile.fromSingleUri(context, fileUri);

fileUri is the URI of the DocumentFile.

Note :- The files in the folder cannot be accessed via MediaStore API because the folder is hidden

Usually this DocumentFile can be either an Image or a Video file.
How do I copy the Image/Video from the DocumentFile to Pictures/My App using MediaStore API.

Thanks in Advance!


Solution

  • Thanks to @blackapps!
    All I had to do was to request a writable URI from the MediaStore using the insert() method and then open a InputStream for source URI and OutputStream for destination URI.

    Code for above action :-

    public void saveFile(Uri sourceUri, String fileName, String mimeType) throws IOException{
    
        ContentValues values = new ContentValues();
        Uri destinationUri;
    
        if (Build.VERSION.SDK_INT > Build.VERSION_CODES.P){
            values.put(MediaStore.MediaColumns.DISPLAY_NAME, fileName);
            values.put(MediaStore.MediaColumns.MIME_TYPE, mimeType);
    
            if (fileName.endsWith(".mp4")){
                values.put(MediaStore.MediaColumns.RELATIVE_PATH, Environment.DIRECTORY_MOVIES + "/MyFolder");
                destinationUri = context.getContentResolver().insert(MediaStore.Video.Media.EXTERNAL_CONTENT_URI, values);
            } else {
                values.put(MediaStore.MediaColumns.RELATIVE_PATH, Environment.DIRECTORY_PICTURES + "/MyFolder");
                destinationUri = context.getContentResolver().insert(MediaStore.Images.Media.EXTERNAL_CONTENT_URI, values);
            }
    
            InputStream inputStream = context.getContentResolver().openInputStream(sourceUri);
            OutputStream outputStream = context.getContentResolver().openOutputStream(destinationUri);
    
            IOUtils.copy(inputStream, outputStream);
            Toast.makeText(context, "The File has been saved!", Toast.LENGTH_SHORT).show();
    
    }
    

    Note :- You have to add the Commons-io dependency in your build.gradle file to access IOUtils.copy() function

    If you find any better way to do this, Do share it!