Android 11 Scoped storage permissions
Solution 1
Android 11
If you are targeting Android 11 (targetSdkVersion 30
) then you require the following permissions in AndroidManifest.xml for modifying and document access.
<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" />
For Android 10 you place the following line in your AndroidManifest.xml tag
android:requestLegacyExternalStorage="true"
the method below checks if the permission is allowed or denied
private boolean checkPermission() {
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;
}
}
The below method can be used for requesting a permission in android 11 or below
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);
}
}
Handling permission callback for Android 11 or above versions
@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();
}
}
}
}
Handling permission callback for OS versions below 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;
}
}
NOTE: MANAGE_EXTERNAL_STORAGE
is a special permission only allowed for few apps like Antivirus, file manager, etc. You have to justify the reason while publishing the app to PlayStore.
Solution 2
Android 11 doesn't allow to access directly files from storage you must have to select file from storage and copy that file into your app package chache com.android.myapp. Below is the method to copy file from storage to app package cache
private String copyFileToInternalStorage(Uri uri, String newDirName) {
Uri returnUri = uri;
Cursor returnCursor = mContext.getContentResolver().query(returnUri, new String[]{
OpenableColumns.DISPLAY_NAME, OpenableColumns.SIZE
}, 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 output;
if (!newDirName.equals("")) {
File dir = new File(mContext.getFilesDir() + "/" + newDirName);
if (!dir.exists()) {
dir.mkdir();
}
output = new File(mContext.getFilesDir() + "/" + newDirName + "/" + name);
} else {
output = new File(mContext.getFilesDir() + "/" + name);
}
try {
InputStream inputStream = mContext.getContentResolver().openInputStream(uri);
FileOutputStream outputStream = new FileOutputStream(output);
int read = 0;
int bufferSize = 1024;
final byte[] buffers = new byte[bufferSize];
while ((read = inputStream.read(buffers)) != -1) {
outputStream.write(buffers, 0, read);
}
inputStream.close();
outputStream.close();
} catch (Exception e) {
Log.e("Exception", e.getMessage());
}
return output.getPath();
}
Solution 3
Review Android 11 Scoped Storage Updates here
Quick Solution is here :
For Quick Solution if you put your android target and compile sdk version is 29 then your app will run on android 11 with the same implementation as u did on android ten here
In mainfest file
When you updating your android Device from api 10(29) to android 11(30) Api , its not working to retrieve data from your device storage or mobile directory i have checked today on play store thousand of the apps having millions download live on play store they are not working on android 11 , because android 11 introduced new scoped storages update where you have to implement new methods to get media file using MediaStore Object,
some useful information that i wants to share with you after reading the android documentation are listed here:
in android 11 , you can access the cache only for their own specific apps.
apps cannot create their own app-specific directory on external storage. To access the directory that the system provides for your app, call getExternalFilesDirs()
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
On Android 11, apps can no longer access files in any other app's dedicated, app-specific directory within external storage.
Apps that run on Android 11 but target Android 10 (API level 29) can still request the requestLegacyExternalStorage attribute. This flag allows apps to temporarily opt out of the changes associated with scoped storage, such as granting access to different directories and different types of media files. After you update your app to target Android 11, the system ignores the requestLegacyExternalStorage flag.
before this on android 10 we were using
android:requestLegacyExternalStorage="true"
tools:targetApi="q"
in manifest under application attribute now this method is not working in android 11.
so migrate to the new updates now thanks
Review Here Scoped Storage Updates
follow the tutorial guidelines here Follow the Scoped Storage tutorial at GitHub
Solution 4
According to the Android developers documentation they recently introduced the MANAGE_EXTERNAL_STORAGE permission, but I didn't understand if adding this permission I'm able to continue to access file by Environment or not.
Yes, you will. However, bear in mind that if you intend to distribute your app on the Play Store (and perhaps elsewhere), you will need to justify the reason for requesting that permission. So, unless you have a very good reason to use MANAGE_EXTERNAL_STORAGE
, please use something else.
Solution 5
I found this way for Android 11 (SDK R - 30):
1- In Manifest must add this permission: (just for R)
<uses-permission android:name="android.permission.MANAGE_EXTERNAL_STORAGE"
tools:ignore="ScopedStorage" />
2- Request the OS dialogue to ask for permission:
ActivityCompat.requestPermissions(this,
new String[]{Manifest.permission.READ_EXTERNAL_STORAGE,
Manifest.permission.MANAGE_EXTERNAL_STORAGE}, 1);
3- Check your app can access to the storage :
if (!Environment.isExternalStorageManager())
4- Use Intent to open the "All Files Access " for your app
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);
Rob B
Updated on July 08, 2022Comments
-
Rob B almost 2 years
I'm trying to better understand what I will be able to do once the Android 11 version will be released.
My App use the file paths of images provided by
Environment.getExternalStorageDirectory()
to create albums of photos, but with Android 11 I won't be able to access directly files.According to the Android developers documentation they recently introduced the
MANAGE_EXTERNAL_STORAGE
permission, but I didn't understand if adding this permission I'm able to continue to access file byEnvironment
or not.Has anyone an idea???
Thanks
UPDATE JANUARY 2021
I tried my application on an Android 11 Virtual device and it seems to work perfectly even without requesting the
MANAGE_EXTERNAL_STORAGE
permission!Reading the documentation on Android Developers, it seems that the applications that uses the
FILE
API for accessing Photos and Medias only locations can continue to work, but I'am not sure.Is there anyone who better understood the Android Documentation???
-
blackapps almost 4 yearsIt looks that for the now actual 30 version this does not come true. Adding to the manifest does nothing. In the settings for the app nothing can be done. Has something to be done at runtime? To my surpise there is, by default, read access for external storage which was not the case on 29. Using Pixel emulator api 30.
-
CommonsWare almost 4 years@blackapps: "Adding to the manifest does nothing" -- adding what? If you mean
MANAGE_EXTERNAL_STORAGE
, it worked for me on a Pixel 2 the last time I tried it. "In the settings for the app nothing can be done" -- there was for me, when launchingSettings.ACTION_MANAGE_APP_ALL_FILES_ACCESS_PERMISSION
. See gitlab.com/commonsguy/cw-android-r/-/tree/v0.3/RawPaths. "To my surpise there is, by default, read access for external storage which was not the case on 29" -- that is "raw paths". Most of external storage is covered, though not all. -
blackapps almost 4 yearsIndeed that all files access action is needed and works. Even the whole sd card is suddenly writable. Thanks. I meant adding <uses-permission android:name="android.permission.MANAGE_EXTERNAL_STORAGE" /> to manifest.
-
Numan Karaaslan over 3 years@CommonsWare i have a question. I want to trite a document reader program that must be able to read any document anywhere, like an antivirus software, user might have a document inside whatsapp directory and might want to read it inside my app. Does this justify / require all files access permisson?
-
CommonsWare over 3 years@NumanKaraaslan: I cannot answer that, as I am not a Google employee responsible for such decisions. That being said, while you may think that it "must be able to read any document anywhere", Google may well disagree. But, Google's rules only apply to the Play Store, so you could perhaps distribute your app by other means (e.g., F-Droid, if it is open source).
-
Noor Hossain over 3 yearsnot require MANAGE_ALL_FILES permission from playstore ?
-
Nensi Kasundra over 3 yearsThank you!!! It's Working for Android 11 and below os.
-
Ahamadullah Saikat over 3 yearsThis works fine. But what is the equivalent of Environment.getExternalStorageDirectory()? It is deprecated.
-
Ramanjeet about 3 yearsWorked for android 11 but not for Android API 29...
-
Thoriya Prahalad about 3 yearsIf you use api 29 don't need this permission. This permission is for API 30 or above.
-
KoalaKoalified about 3 yearsI tested this on Android Level 30 and it works without the request legacy storage but without the request legacy storage android 29 breaks still...
-
JackHuynh about 3 years@ThoriyaPrahalad Excuse me, I update from targetsdk 29 to 30 and remove android:requestLegacyExternalStorage flag in manifest. But my function not work in android 10. Can I apply your solution?.
-
JackHuynh about 3 yearsIf update from sdk 29 to 30?. and requestLegacyExternalStorage is ignored. So can i reslove it?
-
DragonFire about 3 yearsWhen I submit to playstore I get : Your APK or Android App Bundle requests the 'android.permission.MANAGE_EXTERNAL_STORAGE' permission, which Google Play doesn't support yet.
-
DragonFire about 3 yearsWhen I submit to playstore I get : Your APK or Android App Bundle requests the 'android.permission.MANAGE_EXTERNAL_STORAGE' permission, which Google Play doesn't support yet.
-
DragonFire about 3 yearsWhen I submit to playstore I get : Your APK or Android App Bundle requests the 'android.permission.MANAGE_EXTERNAL_STORAGE' permission, which Google Play doesn't support yet.
-
Tushar Monirul about 3 yearsDo I need to submit any form to google playstore to upload my app with this permission? Just like SMS or Call log permission. Or just simply use these code and everything will be fine?
-
Mori about 3 years@DragonFire ,Yes you are right. This permission will be available after 5th May as google mentioned it.
-
Vishal kumar singhvi about 3 years@DragonFire I am getting the same error, Have you found something answer or help from anywhere.
-
DragonFire about 3 years@Vishalkumarsinghvi downgrade target to 29 from 30.. that works and remove the code for 30... and wait for google to allow.
-
Vishal kumar singhvi about 3 yearsRight now I have target SDK 29 but I got a warning We've detected that your app contains the requestLegacyExternalStorage flag in the manifest file of 1 or more of your app bundles or APKs. So I am worried about It they will remove our app or not? @DragonFire
-
DragonFire about 3 years@Vishalkumarsinghvi I have the same flag but no warning better get in touch with google..
-
Tariq Mahmood about 3 yearsHaving same issue, playstore is not accepting it.
-
Vishal kumar singhvi about 3 years@DragonFire Have you use READ and WRITE_EXTERNAL_STORAGE permission in your app?
-
Максим Петлюк about 3 yearsCan we still use READ and WRITE_EXTERNAL_STORAGE permissions, if our app target is 29? As I understand those permissions should be replaced with MANAGE_EXTERNAL_STORAGE only for apps targeted 30? so untill google allows to push apps with target 29, we can still use them?
-
KoalaKoalified about 3 yearsWhen Google Allows the new API level 30 (Which is coming up May 5th), then this code will fully upgrade your app. Until then go to API level 29 with the request legacy flag.
-
DragonFire about 3 years@Vishalkumarsinghvi yes those permissions I have in manifest and those are the ones I request programatically also
-
Vishal kumar singhvi about 3 yearsRight now I have target SDK 29 but I am using requestLegacyExternalStorage flag and READ & WRITE_EXTERNAL_STORAGE both permission in the manifest file So I am worried about It they will remove our app or not?
-
Vishal kumar singhvi about 3 yearsI am thinking in my app i only need pick an image for device that's it so I will use default picker using intent is this correct for me ? @DragonFire.
-
DragonFire about 3 years@Vishalkumarsinghvi build it test it, if you have further questions please open up a new question.. it is out of scope of this one... thanks have a great time coding...
-
Sonu Kumar about 3 yearschange android:maxSdkVersion 28 to 29 in user-permission
-
Najaf Ali about 3 yearsthere are two solutions if you will target your app for api 30 then you can not used requestlegacyExternalstorage permission but you can use this only for android 29 and your app will run on 30 api too .. second solution use media store api and manage request permission and remove requestlegacyexternal permission.
-
Arnab Kundu about 3 yearsBest answer so far
-
Usama Saeed US about 3 years@AhamadullahSaikat use MediaStore.Files.getContentUri("external") to access all files
-
Phantom Lord about 3 yearsOK, all this code works perfectly, but when I have gained access to all files, in which way can I read/write/delete with these files?
-
ekashking about 3 yearscan you at least explain what in the world is 2296 ???????
-
Thoriya Prahalad about 3 yearsit's request code for requesting permission
-
Uriel Frankel about 3 years@ekashking it is a random number for request code and response. you ask for permission with this code and check if that is the response. you can put other number in all places.
-
Anand Savjani about 3 years@Mori is google play store support this permission from now onwards?
-
Mori about 3 years@AnandSavjani, Yes, but maybe Google asks some other requirements.
-
Yogesh Nikam Patil almost 3 yearsGoogle rejected my app after Implementing this solution.
-
MohanRaj S almost 3 yearsApp is rejected by playstore,Action Required: Your app is not compliant with Google Play Policies
-
Md Mohsin almost 3 yearsWhat is the value of Uri in copyFileToInternalStorage method?
-
vijaya zararia almost 3 years@Yogesh Nikam Patil , I am implementing the same solution for my app. Is there any chance of removing app from play store. What will happen if app is removed?
-
Yogesh Nikam Patil almost 3 years@vijayazararia my app is still on play store and working fine.but play console not accepting my new apk version.I cannot update my apk version.
-
vijaya zararia almost 3 years@YogeshNikamPatil Thanks for the answer. I thought like, it will be completely removed.
-
vijaya zararia almost 3 years@YogeshNikamPatil Then what's an alternative you used to publish your app with android.permission.MANAGE_EXTERNAL_STORAGE .
-
Yogesh Nikam Patil almost 3 yearsI didn't get ay solution yet for my app.
-
Glimpse almost 3 years@YogeshNikamPatil just use context.getExternalFilesDir(null) or context.getExternalFilesDir(Environment.DIRECTORY_PICTURES) if targeting SDK 30, there is no need for write_external_storage or MANAGE_EXTERNAL_STORAGE at all. This "getExternalFilesDir" is returning path of app-specific folder on external storage which does not require any permission. Those permissions are only needed if you want to modify public shared external storage, and app-specific folder isn't that
-
Yogesh Nikam Patil almost 3 yearsThanks @Glimpse, I will try it and let you know its working or not.
-
Al Ro over 2 yearsThis answer is no help for most of us because it requires android.permission.MANAGE_EXTERNAL_STORAGE, which is a no-go for most of us. Google won't accept your app to the play store if you use it.
-
Vivek over 2 yearsis it possible to access whatsapp statuses by using this // ??
-
Akito over 2 yearsSo... It's November 2021, now. Does Google support it? Couldn't find information about it.
-
ahmetvefa53 over 2 yearsİs read external storage permission enough To access al files? (Just read not write)
-
Dave over 2 yearsExcellent, thanks.
-
sidetrail over 2 yearsThis is currently working for me, however Environment.getExternalStoragePublicDirectory is deprecated in API level 29.
-
Al Ro over 2 yearsbut if you want to get accepted by the play store there's going to be some issues when you submit this app, so this is at best half a fix. See support.google.com/googleplay/android-developer/answer/…
-
Al Ro over 2 yearsThis is at best half a solution if you want to be on the play store: support.google.com/googleplay/android-developer/answer/…
-
Al Ro over 2 yearsGoogle strongly restricts use of this permission so if you want to be on the play store this is likely going to get your app flagged: support.google.com/googleplay/android-developer/answer/…
-
mirh over 2 years
-
famfamfam over 2 yearsbad answer when app will be reject by google store
-
famfamfam over 2 yearsi got error Attempt to invoke interface method 'int android.database.Cursor.getColumnIndex(java.lang.String)' on a null object reference
-
Mori over 2 years@Akito please see this page: developer.android.com/training/data-storage/…
-
Er.Nancy Thakkar over 2 yearsSame issue is I am facing google rejected my application after adding 'android.permission.MANAGE_EXTERNAL_STORAGE' permission. Let me know if any one found any solution
-
Pawan Jain over 2 yearsIn android 10 and above we can't use MANAGE_EXTERNAL_STORAGE for play store app submission unless the app is a file manager or antivirus. Google will reject your app.
-
Thoriya Prahalad over 2 yearsthis is risky permission because google allow this permission for some apps only like file manager, antivirus apps and etc. read policy program carefully
-
Kamleshwer Purohit over 2 yearsPlease provide the same for java. is your app is accepted on play store?
-
C_compnay over 2 yearsTx alot it saved my day , Your solution worked.
-
Kamleshwer Purohit over 2 yearsperfect one. should be accept as answer
-
famfamfam over 2 yearsthat not be accepted answer because api 29 were not allowed to publish to stre
-
J. M. over 2 yearsWhere do you put the actuale file information, like if i were to make a .txt file with createfile?
-
Saurabh Dhage over 2 years@J. M. You have to override onActivityResult(). In this method you can write content of the file.
-
J. M. over 2 yearsCan you find all files in folder?
-
Anggrayudi H over 2 yearsYup, I can list files under the granted folder. @J.M.
-
J. M. over 2 yearsCan you post an example please, this is all i need to update my app for writing to android 11. Just cant figure out if folder uri is empty and read list of files.
-
J. M. over 2 yearsHeres my question stackoverflow.com/questions/70979344/…
-
Billyjoker over 2 yearsDo you know if this workaround is need to apply with SQLite ?
-
Haris Abdullah over 2 yearsNot a valid answer,all apps will be reject except for some specific
-
Richard Hammond over 2 yearsWhat a complete and utter mess Android is -
-
bikram over 2 yearsShouldn't it be android:maxSdkVersion="29" in manifest instead of android:maxSdkVersion="28"? We still need write permission to work on SDK 29 if we use manage storage permission for SDK 30+.
-
Raii about 2 yearswill user with new mobile see the APP in play store if we set max SDK to 29?
-
M DEV about 2 years@CommonsWare
File createFile = new File(getApplicationContext().getExternalFilesDir(null)+File.separator+"My App");
Is app specific Storage (Private storage) required WRITE_EXTERNAL_STORAGE Permission? -
CommonsWare about 2 years@MDev: No, you do not need permissions to use the directories available from methods on
Context
, such asgetExternalFilesDir()
.