Android 11 not fetching path for file

Viewed 1728

I have been working to fetch file path from storage till now, For example file path is /storage/emulated/0/Download/NTL_ANDRODI_DOGMA_SYSTEMS_SRL_A_SOCIO_UNICO_TEST NEW.afgclic

After android 11 its unable to fetch FilePath. After giving permission

uses-permission android:name="android.permission.MANAGE_EXTERNAL_STORAGE"

Its allowing for Android 11 also, but app is getting rejected by Play store. Since the permission cannot be used without a specific reason and its allowed only for filemanager or antivirus app. Now the point is how other app manages to work on Android 11 for fetching files.

I have been using READ and WRITE storage permission to access file from external storage. Files are required to verify license from other library information

Waiting to get the issue resolved. Thanks for the help.

5 Answers

In Android 11 you have to use Scoped Storage if you want full access of storage.

If you want to access public directories like Documents, Download etc.You can use legacyStorage.


In Your Manifest

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

<application
      android:requestLegacyExternalStorage="true" 

/>

If you want to access full storage you can use Scoped Storage

Add Permissions In Your Manifest

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

<uses-permission
    android:name="android.permission.MANAGE_EXTERNAL_STORAGE"
    tools:ignore="ScopedStorage" />

Now just ask for Permission in your code

    if (SDK_INT >= Build.VERSION_CODES.R) {
        ActivityCompat.requestPermissions(this,
                new String[]{Manifest.permission.READ_EXTERNAL_STORAGE,
                        Manifest.permission.MANAGE_EXTERNAL_STORAGE}, 1);

        if (Environment.isExternalStorageManager()) {

        } else {
            Intent intent = new Intent();
            intent.setAction(Settings.ACTION_MANAGE_APP_ALL_FILES_ACCESS_PERMISSION);
            Uri uri = Uri.fromParts("package", getPackageName(), null);
            intent.setData(uri);
            startActivity(intent);
        }

        return true;

    } else {

        if (Build.VERSION.SDK_INT >= 23) {
            if (checkSelfPermission(android.Manifest.permission.WRITE_EXTERNAL_STORAGE)
                    == PackageManager.PERMISSION_GRANTED) {
                Log.v("Permission", "Storage Permission is granted");
                return true;
            } else {
                Log.v("Permission", "Storage Permission is revoked");
                ActivityCompat.requestPermissions(this, new String[]{Manifest.permission.WRITE_EXTERNAL_STORAGE}, 1);
                return false;
            }
        } else { //permission is automatically granted on sdk<23 upon installation
            Log.v("Permission", "Storage Permission is granted");
            return true;
        }
    }

I have fixed it by fetching path from Google drive

private static String getDriveFilePath(Uri uri, Context context) {
Uri returnUri = uri;
Cursor returnCursor = context.getContentResolver().query(returnUri, null, null, null, null);
/*
 * Get the column indexes of the data in the Cursor,
 *     * move to the first row in the Cursor, get the data,
 *     * and display it.
 * */
int nameIndex = returnCursor.getColumnIndex(OpenableColumns.DISPLAY_NAME);
int sizeIndex = returnCursor.getColumnIndex(OpenableColumns.SIZE);
returnCursor.moveToFirst();

String name = (returnCursor.getString(nameIndex));
String size = (Long.toString(returnCursor.getLong(sizeIndex)));
File file = new File(context.getCacheDir(), name);
try {
    InputStream inputStream = context.getContentResolver().openInputStream(uri);
    FileOutputStream outputStream = new FileOutputStream(file);
    int read = 0;
    int maxBufferSize = 1 * 1024 * 1024;
    int bytesAvailable = inputStream.available();

    //int bufferSize = 1024;
    int bufferSize = Math.min(bytesAvailable, maxBufferSize);

    final byte[] buffers = new byte[bufferSize];
    while ((read = inputStream.read(buffers)) != -1) {
        outputStream.write(buffers, 0, read);
    }
    Log.e("File Size", "Size " + file.length());
    inputStream.close();
    outputStream.close();
    Log.e("File Path", "Path " + file.getPath());
} catch (Exception e) {
    Log.e("Exception", e.getMessage());
}
    return file.getPath();
}     
}

Its very difficult to answer your question.We need some information like what you do with files in your app.What is the usecase of filepath in your application.

  • If you really need file to be accessed via file path then you can copy the file to your apps private directory(not reasonable for working with large video or other files).

  • You can use contentResolver to open fileDescriptor to access the file.

  • You can open e folderSelector intent to let user select a folder where you can get full access to this folder using DocumentFile class.

Best way would be to replace your filepath dependency with uri(if possible).

learn more about scoped storage at Here

Related