Requestlegacyexternalstorage Is Not Working In Android 11 – Api 30

Requestlegacyexternalstorage Is Not Working In Android 11 - Api 30
To address the issue of requestLegacyExternalStorage not functioning in Android 11 – API 30, it’s crucial to implement Scoped Storage which is a more secure way to give apps access to files.

Feature Android 10 (API 29) Android 11 (API 30)
requestLegacyExternalStorage
Yes No
Scoped storage enforcement No Yes
Access to app-specific files Unrestricted Unrestricted
Access to shared storage Full access with permissions Limited to MediaStore, Downloads and Documents via SAF

Diving deeper into the topic of `requestLegacyExternalStorage` in Android development, we discover that it’s a feature which permits an application to retain broad access to shared storage on Android 10 (API level 29). This attribute made it possible for apps to continue accessing their entire directories outside the traditional sandbox, using paths as they did on earlier versions of Android, by merely asking users for permission.

However, for apps targeting Android 11 (API level 30) and above, this attribute is ignored. The pertaining characteristic of the Android 11 platform enforces scoped storage, which modifies the way applications store and access data on a user’s device. Therefore, the usage of the aforementioned `requestLegacyExternalStorage` attribute, which was introduced specifically for Android 10, ceases to function in Android 11.

As a replacement, developers are advised to modify their applications to use app-specific files and directories. These are directly related to your app and will only be accessible by your app, thus improving the overall security. Furthermore, if access to shared storage is required, developers will have limited access options, primarily through the MediaStore API or Directories like Downloads or Documents but it has to be done via Storage Access Framework(SAF).

To quote renowned computer scientist Edsger Dijkstra: “If debugging is the process of removing software bugs, then programming must be the process of putting them in.” This not only showcases the complexity and intricate nature of software development, but also serves as a reminder to constantly update our practices when coding, especially given the constant updates and changes being implemented in platforms like Android.

For more detailed guidelines, please refer to Android’s official documentation on [data storage updates](https://developer.android.com/about/versions/11/privacy/storage) pertinent to these version changes.

Understanding the Issue: RequestLegacyExternalStorage and Android 11


With the evolution of Android’s data security protocols, changes in the way apps access and manage files have been introduced. Particularly, with Android 11 or API 30, Google made some notable changes regarding external storage access. Among these changes is one that impacts the function of

requestLegacyExternalStorage

, leading to a common issue where it stops working as expected.

The flag

requestLegacyExternalStorage

was initially added in Android 10 (API 29) to allow applications to continue using the legacy file system while they adapt their code to the new Scoped Storage model. The attribute could be included in an app’s manifest file like so:

<manifest ... >
    ...
    <application android:requestLegacyExternalStorage="true" ... >
    ... 
    </application>
</manifest>

When this flag is set to true, it lets apps that target Android 10 (API level 29) continue to have broad access to external storage directories. However, the attribute has been depreciated in Android 11 or API 30.

What this means for developers is that if your application targets Android 11 (API 30), it can no longer use

requestLegacyExternalStorage

to get access to the full external storage. Instead, your app should use other means such as Media Store API, Storage Access Framework (SAF) or manage files within your app specific external storage directory.

<‘code’>
//For Images
Intent intent = new Intent(Intent.ACTION_OPEN_DOCUMENT);
intent.addCategory(Intent.CATEGORY_OPENABLE);
intent.setType(“image/*”);

//For Files
Intent intent = new Intent(Intent.ACTION_OPEN_DOCUMENT);
intent.addCategory(Intent.CATEGORY_OPENABLE);
intent.setType(“*/*”);

This change promotes better user privacy by giving users more control over what files an app can access on external storage. For instance, by utilizing the Storage Access Framework, users can choose which files they want the app to have access to instead of inadvertently granting access to all files in the external storage.

Alan Kay once mentioned, “Technology is anything that wasn’t around when you were born”. So it stands to reason that as technology evolves with time, so should our approach to interacting with it. As such, while transitioning from

requestLegacyExternalStorage

might seem cumbersome, these changes work towards providing an enhanced level of privacy and data security for users.

You may refer to the official Android Developers guide for [Scoped Storage](https://developer.android.com/training/data-storage#scoped-storage) for more detailed information about making this transition.

Navigating Changes to Scoped Storage in API 30


Embedded within the landscape of Android development is the highly critical feature known as Storage Access. Most notably in Android 11 – API level 30, changes to the Scoped Storage model have introduced new developmental complexities to consider. In part, the guidelines that heavily pertain to the practice of accessing files stored outside an app’s isolated storage sandbox underwent a significant transformation.

To cast some light on these transformations, it’s crucial to first understand the `requestLegacyExternalStorage` attribute, which was conceived to enable apps targeting Android 10 (API level 29) maintain their ability to freely access shared storage.

This attribute allowed developers some leeway while adjusting to the introduction of Scoped Storage in Android 10. However, one must be cognizant of the fact that `requestLegacyExternalStorage` does not have any impact when your app is running on Android 11 or higher. As per the Android storage updates documentation, this attribute is ignored by Android 11, thereby rendering it unable to facilitate the unrestricted access of shared storage any longer.

The above statement resonates with the words of technology enthusiast and authoritative figure on programming, John D. Cook, who stated, “Change is inevitable in the technology industry; understanding and adapting to it leads to success”.

Diving further:

1. “All Files Access” Permission: If your app requires broad access, then you may need to use the `MANAGE_EXTERNAL_STORAGE` permission. This grants ability to read and write from all files within shared storage. However, please note that due to its extensive nature, Google Play imposes restrictions on its usage.

    //This is how you would declare the All Files Access permission
    \

2. Biodirectional Access to App-Specific Directories: Apps can store propriety files in an app-specific directory on external storage, created via `getExternalFilesDir()` method, and this location doesn’t necessitate any user permissions.

    //This code shows how to create a new file in an app-specific external directory
    File newFile = new File(getExternalFilesDir(null), "MyFile.txt");

3. MediaStore API: Instead of using traditional file paths, adopt using MediaStore API for accessing Media files (Photos, Videos, Audio). Take particular note that manipulating other app’s media files requires specific user permissions.

    //Snippet showing how to add image via MediaStore
    ContentValues values = new ContentValues();
    values.put(MediaStore.Images.Media.DISPLAY_NAME, "ImageName.jpg");
    values.put(MediaStore.Images.Media.MIME_TYPE, "image/jpeg");
    Uri uri = getContentResolver().insert(MediaStore.Images.Media.EXTERNAL_CONTENT_URI, values);

A pivotal aspect to remember as Android Developers is the importance of evolving alongside the platform. With the deprecation of `requestLegacyExternalStorage`, adaptations must be taken on board to devise better and safer ways to manage accessing data on external storage in spa-like adherence to Android’s new storage rules. It’s paramount to maintain a guitar-like tuning with Android’s updates on privacy and storage mechanisms, to ensure the symphony of app compatibility continues harmoniously across various API levels.

Implementing Solutions for RequestLegacyExternalStorage Issues


RequestLegacyExternalStorage is a flag that allows an app to use a broad access to the system’s external storage, such as reading or writing to it. It has been deprecated since Android 11 (API level 30), therefore it makes sense that the RequestLegacyExternalStorage may not be functioning in Android 11.

The transition to the new file access policy in Android 11 can be twofold:

  1. Updating your `targetSdkVersion` to `30` or above
  2. Migrating data to the optimal storage location depending on what you need

    • If you want to continue using broad file storage access, consider moving your files to MediaStore. To add a new file to `

      MediaStore

      `, you’d utilize this code snippet:

      ContentValues values = new ContentValues();
      values.put(MediaStore.Images.Media.DISPLAY_NAME, "my_image");
      values.put(MediaStore.Images.Media.RELATIVE_PATH, "Pictures/my_app_images");
      values.put(MediaStore.Images.Media.MIME_TYPE, "image/jpeg");
      Uri uri = getContentResolver().insert(MediaStore.Images.Media.EXTERNAL_CONTENT_URI, values);
      

      This will store and give you access to any media files that you need.

    • For more specific uses, such as document editing, you might find Storage Access Framework (SAF) useful. A sample of retrieving a document via SAF could look like:

      Intent intent = new Intent(Intent.ACTION_OPEN_DOCUMENT);
      intent.addCategory(Intent.CATEGORY_OPENABLE);
      intent.setType("application/pdf");
      startActivityForResult(intent, READ_REQUEST_CODE);
      

      Then in `onActivityResult()` method,

      @Override
      public void onActivityResult(int requestCode, int resultCode, Intent resultData) {
          if (requestCode == READ_REQUEST_CODE && resultCode == Activity.RESULT_OK) {
              Uri uri = null;
              if (resultData != null) {
                  uri = resultData.getData();
                  // Perform operations on the document using its URI.
              }
          }
      }
      

      This would allow access to documents without affecting the privacy measures provided by Android 11.

    • Use your app-specific directory for categorized storage.
      File file = new File(context.getExternalFilesDir(null), "MyApp");
      

Reference: [Android Developers – Data Storage](https://developer.android.com/training/data-storage)

As Mat McLoughlin, a software developer at Facebook once said, “Every line of code written comes at a price: maintenance.” This change by Google, although inconvenient, definitely feels like a step forward towards user privacy and security, which means we developers must adjust and write our lines of code accordingly.

Technological Context: The Impact of Android’s Shift Away From RequestLegacyExternalStorage

With the release of Android 11 (API Level 30), there has been a fundamental shift in how apps can interact with a device’s external storage. Prior to this transition, developers used the ‘requestLegacyExternalStorage’ attribute in their app’s manifest file to maintain broad access to the file system on devices running Android 10 (API Level 29). As we delve into the impact of Android’s shift away from ‘requestLegacyExternalStorage’, let’s also consider why ‘requestLegacyExternalStorage’ might not be working on Android 11.

The Shift Away From RequestLegacyExternalStorage

In an effort to improve privacy and security, Google has gradually restricted the scope of storage access for apps starting from API level 29. However, the ‘requestLegacyExternalStorage’ flag gave developers an opportunity to work around these restrictions for a brief period until they updated their apps to comply with the new storage model, known as Scoped Storage.

When testing on an Android 11 device or emulator, remember that the ‘requestLegacyExternalStorage’ attribute is disregarded even if it is mentioned in the manifest file. The reason being, Google has moved towards enforcing Scoped Storage as of API Level 30 and above which in turn implies that ‘requestLegacyExternalStorage’ brings no changes to your app’s behavior.

Understanding Scoped Storage

‘Scoped Storage’ introduces separate sandbox storage spaces for each app. Apps now only have unrestricted write access to their own isolated directory whereas read and write access to shared storage for all other files require explicit user permission. This greatly limits the exposure of sensitive user data.

In his famous words about coding practices, Linus Torvalds, the principal developer of the Linux kernel once said, “Bad programmers worry about the code. Good programmers worry about data structures and their relationships.”

This sentiment feels particularly relevant given the ongoing shift towards more structured, managed approaches to handling data like the Scoped Storage mechanism.

Resolving Issues with RequestLegacyExternalStorage on Android 11+

If ‘requestLegacyExternalStorage’ is not working as expected on Android 11, one should generally move towards adopting Scoped Storage policies. Here’s how:

Update Manifest File:

Remove the ‘requestLegacyExternalStorage’ flag from the app’s manifest file.

MediaStore API:

Use MediaStore API for accessing shared media files.

Storage Access Framework (SAF):

For non-media files, use the Storage Access Framework that allows users to select specific files or directories the app can work with.

This change emphasizes Google’s push for better user information safety protocols, encouraging developers to adhere to the principle of least privilege, accessing only necessary data and permissions.

On the broader perspective of the technological context, this marks an important step towards creating platforms that are inherently secure by design. It reaffirms the philosophy that human-centric factors like privacy and security are indeed driving technical evolutions.

Diving deep into the understanding of `requestLegacyExternalStorage`, it becomes evident that its functionality is significantly different in Android 11 – API 30 as compared to preceding versions. To put into perspective, prior to the implementation of `Android Q`—also known as Android 10—and for apps targeting this version, it was quite simple to read and write to shared storage through a device’s file system using various APIs such as java.io.File, MediaStore, etc.

Permission Functionality Prior to Android 10 Functionality on Android 11 (API 30)
requestLegacyExternalStorage 
Allowing apps unrestricted access to shared storage. Shared storage access is restricted

However, with the introduction of Android 11 – API 30, Google decided to withdraw this broad file access capability to enhance users’ data privacy. This introduced Scoped Storage, limiting an application’s access to external storage or shared storage. Thus, the function of `requestLegacyExternalStorage` changed, causing difficulties for developers due to these newly imposed restrictions.

The practical implication of this change suggests that app developers need to adapt their code accordingly to accommodate these changes when upgrading their apps to target API level 30(Android 11) or higher. Instead of using `requestLegacyExternalStorage`, they are required to use alternative methods available, such as `getExternalFilesDirs()`, `MediaStore API`, or `Storage Access Framework(SAF)` to access files in the shared storage space. Each method may carry specific permission requirements, offering different levels of access, that developers need to consider based on their app’s functional requirements:

  • getExternalFilesDirs()

    : It provides an app-specific directory on external storage where you can place media files for your app. No specific user permissions are needed for using this.

  • MediaStore API

    : It provides generalized access to the external storage system’s media content providing options like adding, deleting, and updating items in the MediaStore databases.

  • Storage Access Framework(SAF)

    : It provides a user interface to navigate and pick documents across all supported document providers in a structured form.

As former US Vice President Al Gore said, “the future will be better tomorrow”, we developers must be ready to adapt our skills to the evolving landscape of technology standards and upgrade our knowledge arsenal. In this context, adapting to the changes in the functioning of `requestLegacyExternalStorage` and applying alternative methodologies presents a valuable learning experience for enhancing app development prowess.

For additional information on managing external storage access, one can refer to the official Android Developers documentation.

Related