20

Right now my code opens up the default downloads view and it only shows me the PDFs I downloaded. I choose a PDF file and I get this:

content://com.android.providers.downloads.documents/document/1171

I want to get this:

/storage/emulated/0/Download/ch22Databases.pdf

My question is how do I do this in Android?

My code:

public void PDF() {
    PDF = (Button) findViewById(R.id.FindPDFBtn);//Finds the button in design and put it into a button variable.
    PDF.setOnClickListener(//Listens for a button click.
        new View.OnClickListener() {//Creates a new click listener.
            @Override
            public void onClick(View v) {//does what ever code is in here when the button is clicked
                Intent intent = new Intent();
                intent.setType("application/pdf");
                intent.setAction(Intent.ACTION_GET_CONTENT);
                startActivityForResult(Intent.createChooser(intent, "Select a PDF "), SELECT_PDF);
            }
        }
    );
}

@Override
public void onActivityResult(int requestCode, int resultCode, Intent data) {
    super.onActivityResult(requestCode, resultCode, data);

    //PDF
    if (resultCode == RESULT_OK) {
        if (requestCode == SELECT_PDF) {
            Uri selectedUri_PDF = data.getData();
            SelectedPDF = getPDFPath(selectedUri_PDF);
        }
    }
}

public String getPDFPath(Uri uri) {
    String[] projection = { MediaStore.Images.Media.DATA };
    Cursor cursor = getContentResolver().query(uri, projection, null, null, null);
    int column_index = cursor.getColumnIndexOrThrow(MediaStore.Images.Media.DATA);
    cursor.moveToFirst();
    return cursor.getString(column_index);
}
DaveyDaveDave
  • 9,821
  • 11
  • 64
  • 77
Lazar Kukolj
  • 696
  • 3
  • 15
  • 43
  • 1
    You definitely can't use MediaStore.Images to find a PDF. I would be shocked if Android indexed a PDF as an image. When you get a content URI you typically aren't exposed to the path (for security reasons). Instead you are expected to use a ContentResolver to open a stream to the file contents and read that. Direct access to files is becoming difficult on Android (for security reasons). – Doug Stevenson Mar 20 '16 at 03:14
  • Did your problem was solved? Please mark the question as solved if you find my help valuable ;) – Gueorgui Obregon Mar 20 '16 at 04:23
  • yea i know they changed a lot and now its difficult to get the path, i might have to create my own file manager in my app @DougStevenson – Lazar Kukolj Mar 20 '16 at 04:59
  • In my HTC 816 Desire phone [Note: this device is upgraded to MarshMallow but still has crashes of KitKat. As a developer, I have experienced that Camera opened by intent to get the image captured by it, never releases its resources. This gives me internal crash, when I try to take second picture.], the returned path is starting with "/document/primary:", and it is retained in 'pdfUri.getPath()' resulting in file not found exception. Also when I search in 'MediaStore.Images.Media.DATA', column index returned is -1. – Abhinav Saxena Aug 24 '18 at 07:00

7 Answers7

7

Add this snippet below in your getPDFPath method:

public String getPDFPath(Uri uri){

     final String id = DocumentsContract.getDocumentId(uri);
     final Uri contentUri = ContentUris.withAppendedId(
                    Uri.parse("content://downloads/public_downloads"), Long.valueOf(id));

     String[] projection = { MediaStore.Images.Media.DATA };
     Cursor cursor = getContentResolver().query(contentUri, projection, null, null, null);
     int column_index = cursor.getColumnIndexOrThrow(MediaStore.Images.Media.DATA);
     cursor.moveToFirst();
     return cursor.getString(column_index);
}

In your case, this code is specifically for documents from DownloadProvider, for further implementation check Paul Burke's answer. I personally use his aFileChooser library to avoid this kind of problems.

Quality Catalyst
  • 6,531
  • 8
  • 38
  • 62
Gueorgui Obregon
  • 5,077
  • 3
  • 33
  • 57
6

My question is how do i do this in Android?

You don't. ACTION_GET_CONTENT has little to do with files.

If you absolutely need a file, use a file picker library, not ACTION_GET_CONTENT.

If you want to use ACTION_GET_CONTENT, stop trying to get a filesystem path the content. Use ContentResolver and openInputStream() to read in the contents of the content, if the Uri has a file, content, or android.resource scheme. Use an HTTP client API if the Uri has an http or https scheme.

CommonsWare
  • 986,068
  • 189
  • 2,389
  • 2,491
2

Below are two solutions

1) You can use below code. It can handle any type of file and from any folder.

private String getPath(final Uri uri) {

    final boolean isKitKat = Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT;
    if(isKitKat) {
        // MediaStore (and general)
        return getForApi19(uri);
    } else if ("content".equalsIgnoreCase(uri.getScheme())) {

        // Return the remote address
        if (isGooglePhotosUri(uri))
            return uri.getLastPathSegment();

        return getDataColumn(uri, null, null);
    }
    // File
    else if ("file".equalsIgnoreCase(uri.getScheme())) {
        return uri.getPath();
    }

    return null;
}

@TargetApi(19)
private String getForApi19(Uri uri) {
    Log.e(tag, "+++ API 19 URI :: " + uri);
    if (DocumentsContract.isDocumentUri(this, uri)) {
        Log.e(tag, "+++ Document URI");
        // ExternalStorageProvider
        if (isExternalStorageDocument(uri)) {
            Log.e(tag, "+++ External Document URI");
            final String docId = DocumentsContract.getDocumentId(uri);
            final String[] split = docId.split(":");
            final String type = split[0];

            if ("primary".equalsIgnoreCase(type)) {
                Log.e(tag, "+++ Primary External Document URI");
                return Environment.getExternalStorageDirectory() + "/" + split[1];
            }

            // TODO handle non-primary volumes
        }
        // DownloadsProvider
        else if (isDownloadsDocument(uri)) {
            Log.e(tag, "+++ Downloads External Document URI");
            final String id = DocumentsContract.getDocumentId(uri);
            final Uri contentUri = ContentUris.withAppendedId(
                    Uri.parse("content://downloads/public_downloads"), Long.valueOf(id));

            return getDataColumn(contentUri, null, null);
        }
        // MediaProvider
        else if (isMediaDocument(uri)) {
            Log.e(tag, "+++ Media Document URI");
            final String docId = DocumentsContract.getDocumentId(uri);
            final String[] split = docId.split(":");
            final String type = split[0];

            Uri contentUri = null;
            if ("image".equals(type)) {
                Log.e(tag, "+++ Image Media Document URI");
                contentUri = MediaStore.Images.Media.EXTERNAL_CONTENT_URI;
            } else if ("video".equals(type)) {
                Log.e(tag, "+++ Video Media Document URI");
                contentUri = MediaStore.Video.Media.EXTERNAL_CONTENT_URI;
            } else if ("audio".equals(type)) {
                Log.e(tag, "+++ Audio Media Document URI");
                contentUri = MediaStore.Audio.Media.EXTERNAL_CONTENT_URI;
            }

            final String selection = "_id=?";
            final String[] selectionArgs = new String[] {
                    split[1]
            };

            return getDataColumn(contentUri, selection, selectionArgs);
        }
    } else if ("content".equalsIgnoreCase(uri.getScheme())) {
        Log.e(tag, "+++ No DOCUMENT URI :: CONTENT ");

        // Return the remote address
        if (isGooglePhotosUri(uri))
            return uri.getLastPathSegment();

        return getDataColumn(uri, null, null);
    }
    // File
    else if ("file".equalsIgnoreCase(uri.getScheme())) {
        Log.e(tag, "+++ No DOCUMENT URI :: FILE ");
        return uri.getPath();
    }
    return null;
}

/**
 * Get the value of the data column for this Uri. This is useful for
 * MediaStore Uris, and other file-based ContentProviders.
 *
 * @param uri The Uri to query.
 * @param selection (Optional) Filter used in the query.
 * @param selectionArgs (Optional) Selection arguments used in the query.
 * @return The value of the _data column, which is typically a file path.
 */
public String getDataColumn(Uri uri, String selection,
                            String[] selectionArgs) {

    Cursor cursor = null;
    final String column = "_data";
    final String[] projection = {
            column
    };

    try {
        cursor = getContentResolver().query(uri, projection, selection, selectionArgs,
                null);
        if (cursor != null && cursor.moveToFirst()) {
            final int index = cursor.getColumnIndexOrThrow(column);
            return cursor.getString(index);
        }
    } finally {
        if (cursor != null)
            cursor.close();
    }
    return null;
}


/**
 * @param uri The Uri to check.
 * @return Whether the Uri authority is ExternalStorageProvider.
 */
public static boolean isExternalStorageDocument(Uri uri) {
    return "com.android.externalstorage.documents".equals(uri.getAuthority());
}

/**
 * @param uri The Uri to check.
 * @return Whether the Uri authority is DownloadsProvider.
 */
public static boolean isDownloadsDocument(Uri uri) {
    return "com.android.providers.downloads.documents".equals(uri.getAuthority());
}

/**
 * @param uri The Uri to check.
 * @return Whether the Uri authority is MediaProvider.
 */
public static boolean isMediaDocument(Uri uri) {
    return "com.android.providers.media.documents".equals(uri.getAuthority());
}

/**
 * @param uri The Uri to check.
 * @return Whether the Uri authority is Google Photos.
 */
public static boolean isGooglePhotosUri(Uri uri) {
    return "com.google.android.apps.photos.content".equals(uri.getAuthority());
}

This is the best solution I had to browse files.

Hope it'll help.

Another Way

2) Another solution I found is

Add dependancy in build.gradle of Module: app

compile 'in.gauriinfotech:commons:1.0.8'

Then in your code use

String fullPath = Commons.getPath(uri, context);

Make sure you have added below permission in Manifest.xml

<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
ELITE
  • 5,815
  • 3
  • 19
  • 29
  • Thank you ill take a look at it! the code i marked right fits so it only works with download but i have yet to try this code! – Lazar Kukolj Mar 20 '16 at 07:44
  • 2
    in both solutions getting this exception **Method threw 'java.lang.NumberFormatException' exception.** – Asadullah Mumtaz Jul 14 '20 at 09:00
  • Both the solution giving same error ,'java.lang.IllegalArgumentException: Unknown URI: content://downloads/public_downloads/2250' – Annie May 05 '21 at 10:07
  • Anyone found solution for this?? in some mobile it works but in some this error comes, – Annie May 05 '21 at 10:07
2

I am late here but it could help someone, I have faced same issue in android 10 and 11. let me walk you through step by step to get path of pdf.

1)Open files to select pdf

fun openPdfSelector(){
        val intent = Intent(Intent.ACTION_OPEN_DOCUMENT).apply {
            type = "application/pdf"
            addCategory(Intent.CATEGORY_OPENABLE)
        }
        startActivityForResult(intent, 101)
    }   

2)In Override onActivityResult() method of activity use below code

 data?.data?.also { documentUri ->
                    contentResolver.takePersistableUriPermission(
                        documentUri,
                        Intent.FLAG_GRANT_READ_URI_PERMISSION
                    )
                    val filePathHelper = FilePathHelper()
                    var uriString: String = ""
                    if (filePathHelper.getPathnew(documentUri, this) != null) {
                        uriString = filePathHelper.getPathnew(documentUri, this).toLowerCase()
                    } else {
                        uriString =
                            filePathHelper.getFilePathFromURI(documentUri, this).toLowerCase()
                    }
                    //uriString-> this is original path 
}  

3)FilePathHelper is class we are using to parse uri to get path

public class FilePathHelper {

public FilePathHelper(){

}

public String getMimeType(String url) {
    String type = null;
    String extension = MimeTypeMap.getFileExtensionFromUrl(url.replace(" ", ""));
    if (extension != null) {
        type = MimeTypeMap.getSingleton().getMimeTypeFromExtension(extension);
    }
    return type;
}

public String getFilePathFromURI(Uri contentUri, Context context) {
    //copy file and send new file path
    String fileName = getFileName(contentUri);
    if (!TextUtils.isEmpty(fileName)) {
        File copyFile = new File(context.getExternalCacheDir() + File.separator + fileName);
        copy(context, contentUri, copyFile);
        return copyFile.getAbsolutePath();
    }
    return null;
}

public void copy(Context context, Uri srcUri, File dstFile) {
    try {
        InputStream inputStream = context.getContentResolver().openInputStream(srcUri);
        if (inputStream == null) return;
        OutputStream outputStream = new FileOutputStream(dstFile);
        inputStream.close();
        outputStream.close();
    } catch (IOException e) {
        e.printStackTrace();
    }
}

public String getPath(Uri uri, Context context) {
    String filePath = null;
    final boolean isKitKat = Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT;
    if (isKitKat) {
        filePath = generateFromKitkat(uri, context);
    }

    if (filePath != null) {
        return filePath;
    }

    Cursor cursor = context.getContentResolver().query(uri, new String[]{MediaStore.MediaColumns.DATA}, null, null, null);

    if (cursor != null) {
        if (cursor.moveToFirst()) {
            int columnIndex = cursor.getColumnIndexOrThrow(MediaStore.MediaColumns.DATA);
            filePath = cursor.getString(columnIndex);
        }
        cursor.close();
    }
    return filePath == null ? uri.getPath() : filePath;
}

@TargetApi(19)
private String generateFromKitkat(Uri uri, Context context) {
    String filePath = null;
    if (DocumentsContract.isDocumentUri(context, uri)) {
        String wholeID = DocumentsContract.getDocumentId(uri);

        String id = wholeID.split(":")[1];

        String[] column = {MediaStore.Video.Media.DATA};
        String sel = MediaStore.Video.Media._ID + "=?";

        Cursor cursor = context.getContentResolver().
                query(MediaStore.Video.Media.EXTERNAL_CONTENT_URI,
                        column, sel, new String[]{id}, null);


        int columnIndex = cursor.getColumnIndex(column[0]);

        if (cursor.moveToFirst()) {
            filePath = cursor.getString(columnIndex);
        }

        cursor.close();
    }
    return filePath;
}

public String getFileName(Uri uri) {
    if (uri == null) return null;
    String fileName = null;
    String path = uri.getPath();
    int cut = path.lastIndexOf('/');
    if (cut != -1) {
        fileName = path.substring(cut + 1);
    }
    return fileName;
}

@RequiresApi(api = Build.VERSION_CODES.KITKAT)
public String getPathnew(Uri uri, Context context) {
    final boolean isKitKat = Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT;

    // DocumentProvider
    if (isKitKat && DocumentsContract.isDocumentUri(context, uri)) {
        // ExternalStorageProvider
        if (isExternalStorageDocument(uri)) {
            final String docId = DocumentsContract.getDocumentId(uri);
            final String[] split = docId.split(":");
            final String type = split[0];

            if ("primary".equalsIgnoreCase(type)) {
                return Environment.getExternalStorageDirectory() + "/" + split[1];
            }
            // TODO handle non-primary volumes
        }
        // DownloadsProvider
        else if (isDownloadsDocument(uri)) {
            final String id = DocumentsContract.getDocumentId(uri);
            final Uri contentUri = ContentUris.withAppendedId(Uri.parse("content://downloads/public_downloads"), Long.valueOf(id));
            return getDataColumn(context, contentUri, null, null);
        }
        // MediaProvider
        else if (isMediaDocument(uri)) {
            final String docId = DocumentsContract.getDocumentId(uri);
            final String[] split = docId.split(":");
            final String type = split[0];
            Uri contentUri = null;
            if ("image".equals(type)) {
                contentUri = MediaStore.Images.Media.EXTERNAL_CONTENT_URI;
            } else if ("video".equals(type)) {
                contentUri = MediaStore.Video.Media.EXTERNAL_CONTENT_URI;
            } else if ("audio".equals(type)) {
                contentUri = MediaStore.Audio.Media.EXTERNAL_CONTENT_URI;
            }
            final String selection = "_id=?";
            final String[] selectionArgs = new String[]{split[1]};
            return getDataColumn(context, contentUri, selection, selectionArgs);
        }
    }
    // MediaStore (and general)
    else if ("content".equalsIgnoreCase(uri.getScheme())) {
        // Return the remote address
        if (isGooglePhotosUri(uri))
            return uri.getLastPathSegment();
        return getDataColumn(context, uri, null, null);
    }
    // File
    else if ("file".equalsIgnoreCase(uri.getScheme())) {
        return uri.getPath();
    }
    return null;
}

public String getDataColumn(Context context, Uri uri, String selection, String[] selectionArgs) {
    Cursor cursor = null;
    final String column = "_data";
    final String[] projection = {column};
    try {
        cursor = context.getContentResolver().query(uri, projection, selection, selectionArgs, null);
        if (cursor != null && cursor.moveToFirst()) {
            final int index = cursor.getColumnIndexOrThrow(column);
            return cursor.getString(index);
        }
    } catch (Exception e) {
        e.printStackTrace();
        System.out.println("Something with exception - " + e.toString());
    } finally {
        if (cursor != null)
            cursor.close();
    }
    return null;
}

public boolean isExternalStorageDocument(Uri uri) {
    return "com.android.externalstorage.documents".equals(uri.getAuthority());
}

/**
 * @param uri The Uri to check.
 * @return Whether the Uri authority is DownloadsProvider.
 */
public boolean isDownloadsDocument(Uri uri) {
    return "com.android.providers.downloads.documents".equals(uri.getAuthority());
}

/**
 * @param uri The Uri to check.
 * @return Whether the Uri authority is MediaProvider.
 */
public boolean isMediaDocument(Uri uri) {
    return "com.android.providers.media.documents".equals(uri.getAuthority());
}

/**
 * @param uri The Uri to check.
 * @return Whether the Uri authority is Google Photos.
 */
public boolean isGooglePhotosUri(Uri uri) {
    return "com.google.android.apps.photos.content".equals(uri.getAuthority());
}}

NOTE:- Please provide scope storage permission to you app if you are using android 11
-> For permission you can use below code

 btn_select_file.setOnClickListener {
        if (isScopedStoragePermissionNeeded()) {
            askForExternalStoragePermission()
        } else {
            openPdfSelector()
        }}  



private fun isScopedStoragePermissionNeeded(): Boolean {
        return Build.VERSION.SDK_INT >= Build.VERSION_CODES.R && !Environment.isExternalStorageManager()
    }  

private fun askForExternalStoragePermission() {
        requestPermissions(
            arrayOf(Manifest.permission.MANAGE_EXTERNAL_STORAGE),
            102
        )
}  

-> In onRequestPermissionResultI() method open intent to permission screen

 if (requestCode == 102) {

        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.R) {
            val intent = Intent(Settings.ACTION_MANAGE_APP_ALL_FILES_ACCESS_PERMISSION)
            intent.data = Uri.parse("package:com.example.pdfselector")
            startActivityForResult(intent, 103)
        }
    }  

-> In Manifest file add android:requestLegacyExternalStorage="true" line.

amit semwal
  • 345
  • 3
  • 16
0

Uri uri = intent.getData();

                String uriString = uri.toString();

                File myFile = new File(uriString);

                final String path = myFile.getAbsolutePath();

                String displayName = null;

                if (uriString.startsWith("content://")) {
                    Cursor cursor = null;
                    try {
                        cursor = getActivity().getContentResolver().query(uri, null, null, null, null);
                        if (cursor != null && cursor.moveToFirst()) {
                            displayName = cursor.getString(cursor.getColumnIndex(OpenableColumns.DISPLAY_NAME));
                            tvFile.setVisibility ( View.VISIBLE );
                            tvFile.setText ( displayName );

                            final String finalDisplayName = displayName;
                            tvFile.setOnClickListener ( new View.OnClickListener () {
                                @Override
                                public void onClick(View v) {
                                    File dir = Environment.getExternalStorageDirectory();
                                    File yourFile = new File(dir, path+ finalDisplayName );

                                    Toast.makeText ( getActivity (),"hiiiii"+yourFile,Toast.LENGTH_SHORT ).show ();
                                }
                            } );
                            //Toast.makeText ( getActivity (),"hii"+displayName,Toast.LENGTH_LONG ).show ();
                        }
                    } finally {
                        cursor.close();
                    }
                } else if (uriString.startsWith("file://")) {
                    displayName = myFile.getName();
                   // Toast.makeText ( getActivity (),"hii"+displayName,Toast.LENGTH_LONG ).show ();
                }
0

Please use the below file to get the path from URI

public class FileUtils {
    private static Uri filePathUri = null;


    public static String getPath(final Context context, final Uri uri) {
        filePathUri=uri;
        final boolean isKitKat = Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT;
        final boolean isOreo=Build.VERSION.SDK_INT >= 26;
        // DocumentProvider
        if (isKitKat && DocumentsContract.isDocumentUri(context, uri)) {
            // ExternalStorageProvider
            if (isExternalStorageDocument(uri)) {
                final String docId = getDocumentId(DocumentsContract.getDocumentId(uri));
                final String[] split = docId.split(":");
                final String type = split[0];

                if ("primary".equalsIgnoreCase(type)) {
                    return Environment.getExternalStorageDirectory() + "/" + split[1];
                }
                // TODO handle non-primary volumes
            }
            // DownloadsProvider
            else if (isDownloadsDocument(uri)) {

                final String id = getDocumentId(DocumentsContract.getDocumentId(uri));


                final Uri contentUri = ContentUris.withAppendedId(
                        Uri.parse("content://downloads/public_downloads"), Long.valueOf(id));


                return getDataColumn(context, contentUri, null, null);
            }
            // MediaProvider
            else if (isMediaDocument(uri)) {
                final String docId = getDocumentId(DocumentsContract.getDocumentId(uri));
                final String[] split = docId.split(":");
                final String type = split[0];

                Uri contentUri = null;
                if ("image".equals(type)) {
                    contentUri = MediaStore.Images.Media.EXTERNAL_CONTENT_URI;
                } else if ("video".equals(type)) {
                    contentUri = MediaStore.Video.Media.EXTERNAL_CONTENT_URI;
                } else if ("audio".equals(type)) {
                    contentUri = MediaStore.Audio.Media.EXTERNAL_CONTENT_URI;
                }

                final String selection = "_id=?";
                final String[] selectionArgs = new String[]{
                        split[1]
                };

                return getDataColumn(context, contentUri, selection, selectionArgs);
            }
        }
        // MediaStore (and general)
        else if ("content".equalsIgnoreCase(uri.getScheme())) {
            return getDataColumn(context, uri, null, null);
        }
        // File
        else if ("file".equalsIgnoreCase(uri.getScheme())) {
            return uri.getPath();
        }

        return null;
    }

    /**
     * Get the value of the data column for this Uri. This is useful for
     * MediaStore Uris, and other file-based.
     *
     * @param context       The context.
     * @param uri           The Uri to query.
     * @param selection     (Optional) Filter used in the query.
     * @param selectionArgs (Optional) Selection arguments used in the query.
     * @return The value of the _data column, which is typically a file path.
     */
    public static String getDataColumn(Context context, Uri uri, String selection,
                                       String[] selectionArgs) {

        Cursor cursor = null;**strong text**
        final String column = "_data";
        final String[] projection = {
                column
        };
        FileInputStream input = null;
        FileOutputStream output = null;

        try {
            cursor = context.getContentResolver().query(uri, projection, selection, selectionArgs, null);
            if (cursor != null && cursor.moveToFirst()) {
                final int index = cursor.getColumnIndexOrThrow(column);
                return cursor.getString(index);
            }
        } catch (IllegalArgumentException e){
            e.printStackTrace();

            File file = new File(context.getCacheDir(), "tmp");
            String filePath = file.getAbsolutePath();

            try {
                ParcelFileDescriptor pfd = context.getContentResolver().openFileDescriptor(filePathUri, "r");
                if (pfd == null)
                    return null;

                FileDescriptor fd = pfd.getFileDescriptor();
                input = new FileInputStream(fd);
                output = new FileOutputStream(filePath);
                int read;
                byte[] bytes = new byte[4096];
                while ((read = input.read(bytes)) != -1) {
                    output.write(bytes, 0, read);
                }

                input.close();
                output.close();
                return new File(filePath).getAbsolutePath();
            } catch (IOException ignored) {
                ignored.printStackTrace();
            }
        } finally{
            if (cursor != null)
                cursor.close();
        }
        return null;
    }

    /**
     * @param uri The Uri to check.
     * @return Whether the Uri authority is ExternalStorageProvider.
     */
    public static boolean isExternalStorageDocument(Uri uri) {
        return "com.android.externalstorage.documents".equals(uri.getAuthority());
    }

    /**
     * @param uri The Uri to check.
     * @return Whether the Uri authority is DownloadsProvider.
     */
    public static boolean isDownloadsDocument(Uri uri) {
        return "com.android.providers.downloads.documents".equals(uri.getAuthority());
    }

    /**
     * @param uri The Uri to check.
     * @return Whether the Uri authority is MediaProvider.
     */
    public static boolean isMediaDocument(Uri uri) {
        return "com.android.providers.media.documents".equals(uri.getAuthority());
    }


    private static String getDocumentId(String id) {
        if (!TextUtils.isEmpty(id)) {
            if (id.startsWith("raw:")) {
                return id.replaceFirst("raw:", "");
            }

        }
        return id;
    }
}
Suraj Rao
  • 29,388
  • 11
  • 94
  • 103
sumit
  • 11
  • 1
  • 1
    Please use this link for a full explanation and code https://gist.github.com/HBiSoft/15899990b8cd0723c3a894c1636550a8 – Chandela Nov 08 '20 at 13:06
0

Have tried various solutions for this problem but none worked for me, the best approach according to me is to get output stream for the file using the uri and then write content on a local file (with known path).

@Throws(IOException::class)
private fun copyPdfToLocalFile(uri: Uri) {
    val stringBuilder = StringBuilder()
    contentResolver.openInputStream(uri)?.use { inputStream ->
        BufferedReader(InputStreamReader(inputStream)).use { reader ->
            var line: String? = reader.readLine()
            while (line != null) {
                writeDocument(line)
                line = reader.readLine()
            }
        }
    }
}


private fun writeDocument(line: String) {
    val outputFileUri: Uri = /*Uri of the local file */
    try {
        contentResolver.openFileDescriptor(outputFileUri, "wa")?.use {
            FileOutputStream(it.fileDescriptor).use {
                it.write(line.toByteArray())
            }
        }
    } catch (e: FileNotFoundException) {
        e.printStackTrace()
    } catch (e: IOException) {
        e.printStackTrace()
    }
}

The above code will copy the shared file to a local file, for which you know the path. Later once the copied file isn't needed, you can delete the file.

Since the file is duplicated, can't be used in cases where there is memory constraint but for general use cases it works fine.

ritesh4302
  • 336
  • 1
  • 5
  • 11