1

In my Android app, I need to load a text file from the storage using a file chooser dialog. Some time ago, I followed the instructions in this Android file chooser topic (original answer).

On the phone with Android 4.2.2 (API 17) everything works fine. This code (actually as the uri.getPath() itself) returns the real path of the file:

public static String getPath(Context context, Uri uri) throws URISyntaxException {
    if ("content".equalsIgnoreCase(uri.getScheme())) {
        String[] projection = { "_data" };
        Cursor cursor = null;
        try {
            cursor = context.getContentResolver().query(uri, projection, null, null, null);
            int column_index = cursor.getColumnIndexOrThrow("_data");
            if (cursor.moveToFirst()) {
                return cursor.getString(column_index);
            }
        } catch (Exception e) {
            ...
        }
        ...
    }
    ...
}

It returns something like this: /storage/sdcard1/Directory/myFile.txt

..and I can further work with the file.

However, on the phones with Android 7 and 8 (API 24-26), the cursor.getString(column_index) always returns null, and the uri.getPath() return paths like:

  • /document/254 - Android 8 (external storage)
  • /document/primary:myFile.txt - Android 8 (internal storage)
  • /document/C5F9-13FC:myFile.txt - Android 7

... and when I want to work with the file created by new File(path) and read its content with BufferedReader, I get the FileNotFoundException.

I do not think this is a permission problem because when I read the file with hardcoded path using the following code, everything works fine:

File storage = Environment.getExternalStorageDirectory();
File file = new File(storage, fileName);

My question is:

Is there any way to get the real file path from the file chooser or should I adress this problem on devices with newer Android API in a completely different way like using an external library?

Phantômaxx
  • 37,901
  • 21
  • 84
  • 115
gabi197
  • 103
  • 5
  • you need to add permission for external read write access in android manifest file and you need to request permission at runtime for upper 5.0 android devices – PushpikaWan Oct 27 '18 at 09:07

2 Answers2

0

add this to manifest file

  <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
    <uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE"/>

Then request permission at run time like below

// Check whether this app has write external storage permission or not.
int writeExternalStoragePermission = ContextCompat.checkSelfPermission(ExternalStorageActivity.this, Manifest.permission.WRITE_EXTERNAL_STORAGE);
// If do not grant write external storage permission.
if(writeExternalStoragePermission!= PackageManager.PERMISSION_GRANTED)
{
    // Request user to grant write external storage permission.
    ActivityCompat.requestPermissions(ExternalStorageActivity.this, new String[]{Manifest.permission.WRITE_EXTERNAL_STORAGE}, REQUEST_CODE_WRITE_EXTERNAL_STORAGE_PERMISSION);
}

You need to execute these code before interact with any external read, write process.

PushpikaWan
  • 2,437
  • 3
  • 14
  • 23
  • Thanks, but this is not a permission issue. From the file chooser, I just keep getting a URI, from which I am not able to get the file, like: '/document/0000-0000:Documents /Dictionaries/MyFile.txt' instead of '/storage/emulated/0/Dictionaries/MyFile.txt' which is the real path to the file. – gabi197 Oct 31 '18 at 19:12
0

I found a solution here.

The problem was that I wanted to read the file using the following code:

File file = new File(intent.getData().getPath());
BufferedReader br = new BufferedReader(new FileReader(file));

Instead, I should be using this:

InputStream is = getContentResolver().openInputStream(intent.getData());
BufferedReader br = new BufferedReader(new InputStreamReader(is));
gabi197
  • 103
  • 5