Chris A
Chris A

Reputation: 1090

How do you request MANAGE_EXTERNAL_STORAGE permission in Android?

From Android Docs, https://developer.android.com/training/data-storage/manage-all-files#all-files-access

"An app can request All files access from the user by doing the following:

Declare the MANAGE_EXTERNAL_STORAGE permission in the manifest.

Use the ACTION_MANAGE_ALL_FILES_ACCESS_PERMISSION intent action to direct users to a system settings page where they can enable the following option for your app: Allow access to manage all files."

What I've tried

The only way I know how to request permissions is with ActivityCompat. I've tried:

ActivityCompat.requestPermissions(this, new String[]{Settings.ACTION_MANAGE_ALL_FILES_ACCESS_PERMISSION},1);

and

ActivityCompat.requestPermissions(this, new String[]{Manifest.permission.MANAGE_EXTERNAL_STORAGE},1);

Neither of which do anything.

The Android docs are extensive but not exactly the most welcoming for newcomers. I understand intents, and know they can be used to switch between activities, but I don't know what an "intent action" is and how it can be used to request permissions

Upvotes: 32

Views: 66479

Answers (6)

CommonsWare
CommonsWare

Reputation: 1006539

In Kotlin:

    val uri = Uri.parse("package:${BuildConfig.APPLICATION_ID}")

    startActivity(
      Intent(
        Settings.ACTION_MANAGE_APP_ALL_FILES_ACCESS_PERMISSION,
        uri
      )
    )

(from this sample project)

You are probably used to an implicit Intent. The docs are asking you to use an explicit Intent, one with an action string and, in this case, a Uri. The Uri will have the package scheme and identify your app by its application ID.

That code snippet will start a system-supplied activity that, in theory, will let the user opt into granting your app the MANAGE_EXTERNAL_STORAGE permission.

This API is available for Android R and higher. It will throw ActivityNotFoundException for Android Q and below.

Upvotes: 33

Aamir Ali Khan
Aamir Ali Khan

Reputation: 11

Intent Environment = new 
Intent().setAction(Settings.ACTION_MANAGE_APP_ALL_FILES_ACCESS_PERMISSION)
    .setData(Uri.parse("package:" + getPackageName()));

if (Environment.resolveActivity(getPackageManager())!=null) {
    startActivity(Environment);
}

Upvotes: 1

galian
galian

Reputation: 890

if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.R) {
    if (!Environment.isExternalStorageManager()) {
        try {
            var intent = Intent(Settings.ACTION_MANAGE_APP_ALL_FILES_ACCESS_PERMISSION,
                    Uri.parse("package:" + packageName))
            startActivityForResult(intent, REQUEST_PERMISSION)
        } catch (e: Exception) {
            Logger.d(TAG, e.message)
            var intent = Intent(Settings.ACTION_MANAGE_ALL_FILES_ACCESS_PERMISSION)
            startActivityForResult(intent, REQUEST_PERMISSION)
        }
    }
}

Note: ACTION_MANAGE_APP_ALL_FILES_ACCESS_PERMISSION and ACTION_MANAGE_ALL_FILES_ACCESS_PERMISSION are different.
Both of them can direct user to system settings page. The difference is:

ACTION_MANAGE_APP_ALL_FILES_ACCESS_PERMISSION, with this action, direct user to the package ("package:<package-name>") setting page.

ACTION_MANAGE_ALL_FILES_ACCESS_PERMISSION, this action direct user to app list. All apps which want to manage all files will show in that list.

Upvotes: 4

shubhamgarg1
shubhamgarg1

Reputation: 1995

You can create an intent like this :

Intent intent = new Intent(ACTION_MANAGE_APP_ALL_FILES_ACCESS_PERMISSION, Uri.parse("package:" + BuildConfig.APPLICATION_ID));

Now, you can launch this intent with startActivityForResult.

final static int APP_STORAGE_ACCESS_REQUEST_CODE = 501; // Any value
startActivityForResult(intent, APP_STORAGE_ACCESS_REQUEST_CODE);    

In your onActivityResult method, you can check whether the user granted you the permission or not.

@Override
public void onActivityResult(int requestCode, int resultCode, Intent data)
{
    super.onActivityResult(requestCode, resultCode, data);
    if(requestCode == APP_STORAGE_ACCESS_REQUEST_CODE && Environment.isExternalStorageManager())
        // Permission granted. Now resume your workflow.
    }
}

You can also do this with the new ActivityResultAPI by launching the activity with :

// Initialize the variable in before activity creation is complete.
val storagePermissionResultLauncher = registerForActivityResult(StartActivityForResult(),
            ActivityResultCallback<ActivityResult?> {
                if (Environment.isExternalStorageManager())
                {
                    // Permission granted. Now resume your workflow.
                }
            })
// launch the above intent.
storagePermissionResultLauncher.launch(intent)

Also, make sure that you add this permission entry in your AndroidManifest.xml.

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

Upvotes: 27

Kahraman Avut
Kahraman Avut

Reputation: 201

If Uri will be used in Intent, Settings.ACTION_MANAGE_APP_ALL_FILES_ACCESS_PERMISSION can be used instead of Settings.ACTION_MANAGE_ALL_FILES_ACCESS_PERMISSION.

if(SDK_INT >= 30){
if(!Environment.isExternalStorageManager()){
    Snackbar.make(findViewById(android.R.id.content), "Permission needed!", Snackbar.LENGTH_INDEFINITE)
            .setAction("Settings", new View.OnClickListener() {
                @Override
                public void onClick(View v) {

                    try {
                        Uri uri = Uri.parse("package:" + BuildConfig.APPLICATION_ID);
                        Intent intent = new Intent(Settings.ACTION_MANAGE_APP_ALL_FILES_ACCESS_PERMISSION, uri);
                        startActivity(intent);
                    } catch (Exception ex){
                        Intent intent = new Intent();
                        intent.setAction(Settings.ACTION_MANAGE_ALL_FILES_ACCESS_PERMISSION);
                        startActivity(intent);
                    }
                }
            })
            .show();
}

}

Upvotes: 19

Matrix
Matrix

Reputation: 581

1 Did you add uses-permission in the AndroidManifest.xml? like :

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

2 You can refer this github library: https://github.com/getActivity/XXPermissions
It wraped the api of google sdk, and provide a simple way to apply the permissions.

Upvotes: 1

Related Questions