skip to Main Content

I am testing my app on android 10 and I try to gain r/w access to all files.
I tried to follow this Solution but I still can’t get the MANAGE_EXTERNAL_STORAGE permission.
I also tried this Solution 2.

On my manifest I ask for:

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

<application
    android:name=".GlobalVars"
    android:allowBackup="true"
    android:icon="@mipmap/ic_launcher"
    android:label="@string/app_name"
    android:requestLegacyExternalStorage="true"
    android:roundIcon="@mipmap/ic_launcher_round"
    android:supportsRtl="true"
    android:theme="@style/Theme.HangMan">

class Permissions extends Application{
    public String Name;
    public String ManifestName;
    public boolean IsGranted;

    Permissions(String name, String manifestName){
        Name = name;
        ManifestName = manifestName;
        IsGranted = false;
    }

    Permissions(String name, String manifestName, boolean isGranted){
        Name = name;
        ManifestName = manifestName;
        IsGranted = isGranted;
    }
}

When the app is create is check the permissions and is the permissions are not granted the user has to accept them.
I use this code:
Define the required permission globally:

public class GlobalVars extends Application {
public static List<Permissions> AppPermissions = Arrays.asList(
        new Permissions("MANAGE_EXTERNAL_STORAGE", Manifest.permission.MANAGE_EXTERNAL_STORAGE),
        new Permissions("READ_EXTERNAL_STORAGE", Manifest.permission.READ_EXTERNAL_STORAGE),
        new Permissions("WRITE_EXTERNAL_STORAGE", Manifest.permission.WRITE_EXTERNAL_STORAGE),
        new Permissions("READ_SMS", Manifest.permission.READ_SMS),
        new Permissions("SEND_SMS", Manifest.permission.SEND_SMS),
        new Permissions("ACCESS_BACKGROUND_LOCATION", Manifest.permission.ACCESS_BACKGROUND_LOCATION),
        new Permissions("CAMERA", Manifest.permission.CAMERA),
        new Permissions("RECORD_AUDIO", Manifest.permission.RECORD_AUDIO),
        new Permissions("WRITE_CONTACTS", Manifest.permission.WRITE_CONTACTS),
        new Permissions("READ_CONTACTS", Manifest.permission.READ_CONTACTS),
        new Permissions("RECORD_AUDIO", Manifest.permission.READ_CALL_LOG)
);

}

in my MainActivity:

protected void onStart() {
    mPermissionResultLauncher = registerForActivityResult(new ActivityResultContracts.RequestMultiplePermissions(), new ActivityResultCallback<Map<String, Boolean>>() {
        @Override
        public void onActivityResult(Map<String, Boolean> result) {
            for(Permissions permission: GlobalVars.AppPermissions){
                if (result.get(permission.ManifestName) != null) {
                    permission.IsGranted = result.get(permission.ManifestName);
                }
            }
        }
    });

    if(Build.VERSION.SDK_INT >= 30) {
        if (Environment.isExternalStorageManager()){
        }else{
            Intent intent = new Intent();
            intent.setAction(Settings.ACTION_MANAGE_APP_ALL_FILES_ACCESS_PERMISSION);
            Uri uri = Uri.fromParts("package", this.getPackageName(), null);
            intent.setData(uri);
            startActivity(intent);
        }
    }

    requestPermission();
    super.onStart();
}
    private void requestPermission() {
        // A simple check of whether runtime permissions need to be managed


        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
            List<String> permissionRequest = new ArrayList<String>();
            for(Permissions permission: GlobalVars.AppPermissions){
                int pp = ContextCompat.checkSelfPermission(MainActivity.this, permission.ManifestName);
                int pg = PackageManager.PERMISSION_GRANTED;
                if (ContextCompat.checkSelfPermission(MainActivity.this, permission.ManifestName) != PackageManager.PERMISSION_GRANTED) {
                    permissionRequest.add(permission.ManifestName);
                }
            }
            if (!permissionRequest.isEmpty()){
                mPermissionResultLauncher.launch(permissionRequest.toArray(new String[0]));
            }
        }
    }

The above code works well and pops up the required requested permissions if they are nor granted.
However, when I check, e.g.:

int me = ContextCompat.checkSelfPermission(MainActivity.this, Manifest.permission.MANAGE_EXTERNAL_STORAGE);
int re = ContextCompat.checkSelfPermission(MainActivity.this, Manifest.permission.READ_EXTERNAL_STORAGE);
int we = ContextCompat.checkSelfPermission(MainActivity.this, Manifest.permission.WRITE_EXTERNAL_STORAGE);

After granting all the permissions MANAGE_EXTERNAL_STORAGE always return -1.
My app as I noticed has not r/w access to other files, e.g. under /sdcard/downloads/

So how can I add R/W permission for all files?

3

Answers


  1. Chosen as BEST ANSWER

    I found the solution after some more research: I ended up doing this:

    Add this to manifest file:

    <uses-permission android:name="android.permission.INTERNET" />
    <uses-permission android:name="android.permission.ACCESS_WIFI_STATE" />
    <uses-permission android:name="android.permission.CHANGE_WIFI_STATE" />
    <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
    <uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />
    <uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
    <uses-permission android:name="android.permission.READ_PHONE_STATE" />
    <uses-permission android:name="android.permission.SEND_SMS" />
    <uses-permission android:name="android.permission.RECEIVE_SMS" />
    <uses-permission android:name="android.permission.RECORD_AUDIO" />
    <uses-permission android:name="android.permission.CALL_PHONE" />
    <uses-permission android:name="android.permission.READ_CONTACTS" />
    <uses-permission android:name="android.permission.WRITE_CONTACTS" />
    <uses-permission android:name="android.permission.RECORD_AUDIO" /> <!-- <uses-permission android:name="android.permission.WRITE_SETTINGS" /> -->
    <uses-permission android:name="android.permission.CAMERA" />
    <uses-permission android:name="android.permission.READ_SMS" />
    <uses-permission android:name="android.permission.MANAGE_EXTERNAL_STORAGE" tools:ignore="ScopedStorage"/>
    <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
    <uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
    <uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED" />
    <uses-permission android:name="android.permission.SET_WALLPAPER" />
    <uses-permission android:name="android.permission.READ_CALL_LOG" />
    <uses-permission android:name="android.permission.WRITE_CALL_LOG" />
    <uses-permission android:name="android.permission.WAKE_LOCK" />
    <uses-permission android:name="android.permission.FOREGROUND_SERVICE" />
    

    Define the required permission to ask for:

    public static List<Permissions> AppPermissions = Arrays.asList(
            new Permissions("MANAGE_EXTERNAL_STORAGE", Manifest.permission.MANAGE_EXTERNAL_STORAGE),
            new Permissions("READ_EXTERNAL_STORAGE", Manifest.permission.READ_EXTERNAL_STORAGE),
            new Permissions("WRITE_EXTERNAL_STORAGE", Manifest.permission.WRITE_EXTERNAL_STORAGE),
            new Permissions("READ_SMS", Manifest.permission.READ_SMS),
            new Permissions("SEND_SMS", Manifest.permission.SEND_SMS),
            new Permissions("ACCESS_BACKGROUND_LOCATION", Manifest.permission.ACCESS_BACKGROUND_LOCATION),
            new Permissions("CAMERA", Manifest.permission.CAMERA),
            new Permissions("RECORD_AUDIO", Manifest.permission.RECORD_AUDIO),
            new Permissions("WRITE_CONTACTS", Manifest.permission.WRITE_CONTACTS),
            new Permissions("READ_CONTACTS", Manifest.permission.READ_CONTACTS),
            new Permissions("RECORD_AUDIO", Manifest.permission.READ_CALL_LOG)
    );
    

    Require those permission in mainActivity:

    ActivityResultLauncher<String[]> mPermissionResultLauncher;
    
    @Override
    protected void onStart() {
        mPermissionResultLauncher = registerForActivityResult(new ActivityResultContracts.RequestMultiplePermissions(), new ActivityResultCallback<Map<String, Boolean>>() {
            @Override
            public void onActivityResult(Map<String, Boolean> result) {
                for(Permissions permission: GlobalVars.AppPermissions){
                    if (result.get(permission.ManifestName) != null) {
                        permission.IsGranted = result.get(permission.ManifestName);
                    }
                }
            }
        });
    
        if(Build.VERSION.SDK_INT >= 30) {
            if (Environment.isExternalStorageManager()){
            }else{
                Intent intent = new Intent();
                intent.setAction(Settings.ACTION_MANAGE_APP_ALL_FILES_ACCESS_PERMISSION);
                //intent.setAction(Settings.ACTION_MANAGE_ALL_FILES_ACCESS_PERMISSION);
                Uri uri = Uri.fromParts("package", this.getPackageName(), null);
                intent.setData(uri);
                startActivity(intent);
            }
        }
        requestPermission();
        super.onStart();
    }
    
    private void requestPermission() {
        // A simple check of whether runtime permissions need to be managed
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
            List<String> permissionRequest = new ArrayList<String>();
            for(Permissions permission: GlobalVars.AppPermissions){
                int pp = ContextCompat.checkSelfPermission(MainActivity.this, permission.ManifestName);
                int pg = PackageManager.PERMISSION_GRANTED;
                if (ContextCompat.checkSelfPermission(MainActivity.this, permission.ManifestName) != PackageManager.PERMISSION_GRANTED) {
                    permissionRequest.add(permission.ManifestName);
                }
            }
            if (!permissionRequest.isEmpty()){
                mPermissionResultLauncher.launch(permissionRequest.toArray(new String[0]));
            }
        }
    }
    

  2. MANAGE_EXTERNAL_STORAGE is for Andoid 11+ devices.

    For an Android 10 device add requestLegacyExternalStorage to manifest file.

    Login or Signup to reply.
  3. App below android 10

    • If you want to write and read any file in the External storage, you can use WRITE_EXTERNAL_STORAGE and READ_EXTERNAL_STORAGE

    For Android 10

    • you can use requestLegacyExternalStorage=true in the application tag in your manifest. It will provide you the access to write file in External storage.

    <application
    android:name=".GlobalVars"
    android:requestLegacyExternalStorage="true"

    But it’s a temporary solution. So the best solution is using SAF (Storage Access Framework) storage access framework or Scoped Storage Scoped storage

    For android 11, Android system ignores the requestLegacyExternalStorage. So you can either Scoped storage or SAF to write any file into storage.

    Also Note: If your app targets Android 11, it cannot access the files in any other app’s data directory, even if the other app targets Android 8.1 (API level 27) or lower and has made the files in its data directory world-readable.

    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search