2

I know I am asking the question which is already asked lots of time but I have tried lots of answer from them.

I have developed below code for taking pdf files and I have setup PROVIDER perfectly.

Intent intent = new Intent();
intent.setType("application/pdf");
intent.putExtra(Intent.EXTRA_LOCAL_ONLY, true);
intent.setAction(Intent.ACTION_GET_CONTENT);
startActivityForResult(intent, PICKFILE_REQUEST_CODE);

but once I will get data on onActivityResultthen trying to get file path.

So In a few cases, I am getting file path proper. But in Samsung device, I am getting URI as content://file-content/number. So due to this type of URI, method can't convert that URI to file path.

Here is my method which converts URI to localPath

private static String getRealPath(ContentResolver contentResolver, Uri uri, String whereClause) {
        String localPath = "";

        // Query the URI with the condition.
        Cursor cursor = contentResolver.query(uri, null, whereClause, null, null);

        if (cursor != null) {
            boolean moveToFirst = cursor.moveToFirst();
            if (moveToFirst) {

                // Get column name by URI type.
                String columnName = MediaStore.Images.Media.DATA;

                if (uri == MediaStore.Images.Media.EXTERNAL_CONTENT_URI) {
                    columnName = MediaStore.Images.Media.DATA;
                } else if (uri == MediaStore.Audio.Media.EXTERNAL_CONTENT_URI) {
                    columnName = MediaStore.Audio.Media.DATA;
                } else if (uri == MediaStore.Video.Media.EXTERNAL_CONTENT_URI) {
                    columnName = MediaStore.Video.Media.DATA;
                }

                // Get column index.
                int columnIndex = cursor.getColumnIndex(columnName);

                // Get column value which is the uri related file local path.
                localPath = cursor.getString(columnIndex);
            }
        }

        return localPath;
    }

So I have two question about this problem :

  1. I want to get column name for URI but Not getting which type of URI when user select file from Drive's file.

    i.e: In my method, I can't compare uri == MediaStore.Image.Media.EXTERNAL_CONTENT_URI.

  2. How can convert content://file-content/number uri to file path.

Thanks in advance.

maid450
  • 7,478
  • 3
  • 37
  • 32
Android Dev
  • 109
  • 7

1 Answers1

2

I want to get column name for uri but Not getting which type of URI when user select file from Drive's file.

Use this code to check scheme of an URI:

if (uri.getScheme().equals(ContentResolver.SCHEME_CONTENT)) {
    // Content scheme        
} else if (uri.getScheme().equals(ContentResolver.SCHEME_FILE)){
   // File scheme    
} else {
   // Other
}

How can convert content://file-content/number uri to file path.

Create a temp file:

@Nullable
private File createTempUploadFile(String fileName) {
    File storageDir = new File(getActivity().getExternalFilesDir(null), "Upload");
    if (storageDir.exists()) {
        File[] files = storageDir.listFiles();
        for (File file : files) {
            file.delete();
        }
    } else {
        if (!storageDir.mkdirs()) {
            return null;
        }
    }

    File file = new File(storageDir.getPath() + File.separator + fileName);
    mCurrentFilePath = "file:" + file.getAbsolutePath();
    return file;
}

Write a util method to copy from an input stream to a file

public static boolean copyFileFromInputStream(InputStream inputStream, File dest) {
    OutputStream outputStream = null;
    try {
        outputStream = new FileOutputStream(dest);
        final byte[] buffer = new byte[64 * 1024]; // 64KB
        int bytesRead;
        while ((bytesRead = inputStream.read(buffer)) != -1) {
            outputStream.write(buffer, 0, bytesRead);
        }
        outputStream.flush();
        return true;
    } catch (IOException e) {
        Timber.e(e);
        return false;
    } finally {
        try {
            if (inputStream != null) {
                inputStream.close();
            }

            if (outputStream != null) {
                outputStream.close();
            }
        } catch (IOException e) {
            // Do nothing.
        }
    }
}

Copy content from the URI to the temp file in onActivityResult

try {
    File dest = createTempUploadFile(fileName);
    if (dest != null) {
        InputStream inputStream =
                getActivity().getContentResolver().openInputStream(uri);
        Utils.copyFileFromInputStream(inputStream, dest);
    }
} catch (Exception e) {
    // TODO
}

Now get the file path from the temp file.

Update: If you want to get file name from a URI, use this code inside onActivityResult.

Cursor cursor = null;
try {
    cursor = getActivity().getContentResolver().query(uri,
            null,
            null,
            null,
            null);

    if (cursor != null && cursor.moveToFirst()) {
        int displayNameIndex = cursor.getColumnIndex(OpenableColumns.DISPLAY_NAME);
        String fileName = cursor.getString(displayNameIndex);
    }  
} finally {
    if (cursor != null) {
        cursor.close();
    }
}
Son Truong
  • 13,661
  • 5
  • 32
  • 58
  • Yup thanks you saved my day. but my question is that how can I get filename to pass into `createTempUploadFile` function! – Android Dev Sep 12 '18 at 09:37
  • getContentResolver().openInputStream(uri); is responding no such file or directory found. – Android Dev Sep 12 '18 at 10:08
  • 1
    getContentResolver().openInputStream(uri); is responding me "no such file or directory found". – Android Dev Sep 12 '18 at 12:50
  • Cam you use logcat to see file uri full path. I need to see it to find root cause. – Son Truong Sep 12 '18 at 13:16
  • 1
    I am getting uri = "content://com.google.android.apps.docs.storage.legacy/enc%3DdNqhIYs1Zum600Gx_CbFQcRywYkUEsmKhxXlurrwt5HZh9_c%0A".. Now if I am trying to transfer `getContentResolver().openInputStream(uri)` then logcat shows me is responding me "no such file or directory found" – Android Dev Sep 12 '18 at 13:22
  • Please add this to intent that you want to open file `intent.addCategory(Intent.CATEGORY_OPENABLE);`. And make sure you add read/write external permissions in manifest and grant all. – Son Truong Sep 12 '18 at 14:04
  • @NhấtGiang how much temporary is this file? I try to open it from other activity and I get FileException: no such file or directory found – Carlos López Marí May 28 '19 at 11:10