Keywords: Android 11 | Scoped Storage | MANAGE_EXTERNAL_STORAGE | Storage Permissions | File Access
Abstract: This article provides an in-depth examination of Android 11 scoped storage permissions, detailing the usage scenarios and restrictions of MANAGE_EXTERNAL_STORAGE permission, offering complete permission checking and requesting implementations, and comparing traditional file APIs with modern storage access frameworks to assist developers in adapting to Android 11 storage policy changes.
Evolution of Android 11 Storage Permission Architecture
With the release of Android 11, Google has further strengthened the storage permission management system by introducing more stringent scoped storage mechanisms. This transformation aims to enhance user privacy protection by limiting applications' excessive access to device storage. Traditionally, developers have used the Environment.getExternalStorageDirectory() method to directly access external storage paths, but in the Android 11 environment, this direct file path access approach has been significantly restricted.
Permission Configuration Strategy Analysis
For applications targeting Android 11 (API level 30), precise permission declaration configuration is required in the AndroidManifest.xml file. Core permissions include:
<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" />
It is important to note that the WRITE_EXTERNAL_STORAGE permission no longer provides extensive write capabilities in Android 10 and above, hence the android:maxSdkVersion="28" attribute restricts its effectiveness to older system versions only.
Permission Status Detection Mechanism
Implementing robust permission management requires establishing comprehensive detection mechanisms. The following code demonstrates a cross-version compatible permission checking solution:
private boolean checkPermission() {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.R) {
return Environment.isExternalStorageManager();
} else {
int readResult = ContextCompat.checkSelfPermission(context, Manifest.permission.READ_EXTERNAL_STORAGE);
int writeResult = ContextCompat.checkSelfPermission(context, Manifest.permission.WRITE_EXTERNAL_STORAGE);
return readResult == PackageManager.PERMISSION_GRANTED && writeResult == PackageManager.PERMISSION_GRANTED;
}
}
This implementation intelligently selects detection strategies based on system version: using Environment.isExternalStorageManager() for Android 11 and above, while checking read and write permission status separately for older versions.
Permission Request Flow Implementation
The permission request process requires differentiated strategies for different Android versions:
private void requestPermission() {
if (Build.VERSION.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", context.getPackageName())));
startActivityForResult(intent, REQUEST_CODE);
} catch (Exception e) {
Intent intent = new Intent(Settings.ACTION_MANAGE_ALL_FILES_ACCESS_PERMISSION);
startActivityForResult(intent, REQUEST_CODE);
}
} else {
ActivityCompat.requestPermissions(activity,
new String[]{Manifest.permission.WRITE_EXTERNAL_STORAGE}, REQUEST_CODE);
}
}
In the Android 11 environment, permission requests are completed through system settings interfaces, requiring applications to guide users to specialized permission management pages.
Permission Callback Handling
Proper handling of permission request results is crucial:
@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
if (requestCode == REQUEST_CODE) {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.R) {
if (Environment.isExternalStorageManager()) {
// Business logic after successful permission grant
} else {
// Handle permission denial scenario
}
}
}
}
Alternative Storage Access Solutions
For most application scenarios, adopting scoped storage access patterns is recommended. Media files can be safely accessed through ContentResolver and Storage Access Framework (SAF):
private String copyFileToAppStorage(Uri sourceUri, String destinationDirectory) {
Cursor cursor = context.getContentResolver().query(sourceUri,
new String[]{OpenableColumns.DISPLAY_NAME, OpenableColumns.SIZE}, null, null, null);
if (cursor != null && cursor.moveToFirst()) {
String fileName = cursor.getString(cursor.getColumnIndex(OpenableColumns.DISPLAY_NAME));
File outputFile = new File(context.getFilesDir(), destinationDirectory + "/" + fileName);
try (InputStream input = context.getContentResolver().openInputStream(sourceUri);
OutputStream output = new FileOutputStream(outputFile)) {
byte[] buffer = new byte[1024];
int bytesRead;
while ((bytesRead = input.read(buffer)) != -1) {
output.write(buffer, 0, bytesRead);
}
return outputFile.getAbsolutePath();
} catch (IOException e) {
Log.e("Storage", "File copy failed", e);
} finally {
cursor.close();
}
}
return null;
}
Permission Usage Considerations
MANAGE_EXTERNAL_STORAGE belongs to a special permission category with strict usage limitations. Google Play Store only grants this permission to specific types of applications such as file managers and antivirus software. During app store review processes, developers must provide adequate justification for its use. For regular applications, priority should be given to using scoped storage APIs, which aligns with platform design principles and ensures smooth app store approval.
Version Compatibility Considerations
In Android 10 systems, traditional storage access behavior can be temporarily maintained by adding the android:requestLegacyExternalStorage="true" attribute to the <application> tag. However, this is only a transitional solution, and developers should complete the migration to scoped storage as soon as possible.
Conclusion and Recommendations
Android 11's scoped storage mechanism represents a significant advancement in mobile platform privacy protection. Developers should: deeply understand permission model changes, adopt modern storage access APIs, implement refined permission management, and ensure balance between application functionality and user privacy protection. By following best practices, applications can not only meet platform requirements but also provide users with safer and more reliable experiences.