Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to get the file path from a URI that points to a PDF document?

Tags:

android

pdf

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);
}
like image 645
Lazar Kukolj Avatar asked Mar 20 '16 02:03

Lazar Kukolj


People also ask

How do I find the path of a PDF?

fileName = fileName. substring(0, fileName. indexOf("."));

How do you find the absolute path of URI?

Uri uri = data. getData(); File file = new File(uri. getPath());//create path from uri final String[] split = file. getPath().

How do I get file path in Android 10?

String path = uri. getPath(); File dir = new File(sdcard. getAbsolutePath()+"/"+path1);


3 Answers

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.

like image 199
Gueorgui Obregon Avatar answered Oct 17 '22 17:10

Gueorgui Obregon


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.

like image 33
CommonsWare Avatar answered Oct 17 '22 17:10

CommonsWare


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" />
like image 2
ELITE Avatar answered Oct 17 '22 19:10

ELITE