3

If we run the android app target to version 10 or below, we can set the below flag in the AndroidManifest file to access the root folder of the device.

android:requestLegacyExternalStorage="true"

But Google anymore will not going to support that from Android 11. Check the link: https://developer.android.com/training/data-storage/use-cases#opt-out-scoped-storage

So how can I manage the scoped storage from my application (I am developing a Xamarin forms app that supports Android & iOS)?

James Z
  • 12,209
  • 10
  • 24
  • 44
Jay
  • 65
  • 8

2 Answers2

1

The below documentation links will give you the clear idea about storage related updates and APIs provided in api 30 (Android 11)

https://developer.android.com/about/versions/11/privacy/storage?authuser=1

https://developer.android.com/training/data-storage#scoped-storage

Vivek
  • 11,938
  • 19
  • 92
  • 127
0

add the following permissions in AndroidManifest.xml:

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

and add

android:requestLegacyExternalStorage="true"

android 11 / API 30 = "R", so check permission with following function:

private boolean checkRWPermissions() {
    if (SDK_INT >= Build.VERSION_CODES.R) {
        return Environment.isExternalStorageManager();
    } else {
        int result = ContextCompat.checkSelfPermission(PermissionActivity.this, READ_EXTERNAL_STORAGE);
        int result1 = ContextCompat.checkSelfPermission(PermissionActivity.this, WRITE_EXTERNAL_STORAGE);
        return result == PackageManager.PERMISSION_GRANTED && result1 == PackageManager.PERMISSION_GRANTED;
    }
}

if result of checkRWPermissions() is false, ask permissions this way:

private void requestPermission() {
    if (SDK_INT >= Build.VERSION_CODES.R) {
        try {
            Intent intent = new Intent(Settings.ACTION_MANAGE_APP_ALL_FILES_ACCESS_PERMISSION);
            intent.addCategory("android.intent.category.DEFAULT");
            intent.setData(Uri.parse(String.format("package:%s",getApplicationContext().getPackageName())));
            startActivityForResult(intent, 2296);
        } catch (Exception e) {
            Intent intent = new Intent();
            intent.setAction(Settings.ACTION_MANAGE_ALL_FILES_ACCESS_PERMISSION);
            startActivityForResult(intent, 2296);
        }
    } else {
        //below android 11
        ActivityCompat.requestPermissions(PermissionActivity.this, new String[]{WRITE_EXTERNAL_STORAGE}, PERMISSION_REQUEST_CODE);
    }
}

handle permission callback for android "R"=API 30:

@Override
protected void onActivityResult(int requestCode, int resultCode, @Nullable Intent data) {
    super.onActivityResult(requestCode, resultCode, data);
    if (requestCode == 2296) {
        if (SDK_INT >= Build.VERSION_CODES.R) {
            if (Environment.isExternalStorageManager()) {
                // perform action when allow permission success
            } else {
                Toast.makeText(this, "Allow permission for storage access!", Toast.LENGTH_SHORT).show();
            }
        }
    }
}

handle permission callback below android "R" = android 11:

@Override
public void onRequestPermissionsResult(int requestCode, String[] permissions, int[] grantResults) {
    switch (requestCode) {
        case PERMISSION_REQUEST_CODE:
            if (grantResults.length > 0) {
                boolean READ_EXTERNAL_STORAGE = grantResults[0] == PackageManager.PERMISSION_GRANTED;
                boolean WRITE_EXTERNAL_STORAGE = grantResults[1] == PackageManager.PERMISSION_GRANTED;

                if (READ_EXTERNAL_STORAGE && WRITE_EXTERNAL_STORAGE) {
                    // perform action when allow permission success
                } else {
                    Toast.makeText(this, "Allow permission for storage access!", Toast.LENGTH_SHORT).show();
                }
            }
            break;
    }
}

copied: Thoriya Prahalad

sifr_dot_in
  • 3,153
  • 2
  • 33
  • 42