Implications of Scoped Storage on Android 11 for Enterprise Applications

Storage types on Android  - Background

On Android OS, an application has access to two types of physical storage locations: a working area named "Internal Storage" to privately save his own files, and a wide and varied file system area, named "External Storage".

Internal Storage
This is an App-specific area not accessible by any other apps, file managers, ADB, or the user. 
The typical use of the directories within internal storage is for saving sensitive information that other apps shouldn't access.

The base directory for the application's Internal Storage directory is /data/user/0/<com.your_package>/files/

External Storage
Traditionally this was an SD card, but today in most devices it is also implemented as an additional built-in memory, can be mounted as a filesystem on a computer. 

To access the External Storage the READ/WRITE_EXTERNAL_STORAGE permission is required.

External Storage contains different folders designed for different uses: for common files, downloads, documents or other shared media (Images, Audio, Video, PodCast... ) but there is also the External Storage directory for each individual application installed on the system, which is basically supposed to be reserved for individual applications as an alternative to Internal Storage. Because it is located in the External Storage area, it is in fact also accessible by other applications that have READ/WRITE_EXTERNAL_STORAGE permissions.

Also, removable volumes such as an SD card, generally appear in the file system as part of external storage. 

The base directory for the External Storage is /storage/emulated/0/ or /sdcard/ or /mnt/sdcard/ 

 

 

Storage data access from Android 4.4 until Andorid 9 - Permissions

From Android 4.4 through 9.0 Google defined a stable set of rules for permissions to access storage. While Internal and External app-specific storage was always accessible and do not require any permission, the access to all other external resources  was protected by a couple of permissions that you must provide in the application manifest:

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

With these permissions any application could have full access to any content in the External Storage.
Since those permissions were considered dangerous, was needed to request them both in the manifest and at runtime. By manually installing an app that request one of those permissions, the user was be prompted by the system manual permission approval.
In enterprise environment applications, with large device fleets, this could have been very burdensome if it had to be done manually by an operator on each device. 
Fortunately, most EMMs and Datalogic tools such as Scan2Deploy or Datalogic's Android SDKs can automate this process by silently granting those permissions directly during application installation.

However this Storage access permission model was prone to other issues:

  1. Privacy and data protection issues
    Most programs do not require access to the whole storage system. They often work on a single file or a small collection of files. This posed a risk to user privacy and to a loss of control on the number of files created by each single app.
    With this shared storage access if apps use the external storage for sensitive files, they may be creating security issues, because other apps with the READ_EXTERNAL_STORAGE or WRITE_EXTERNAL_STORAGE permissions are able to access the app-specific files on external storage.

  2. File proliferation and lack of application binding
    While the Internal Storage folders are tightened one-to-one with each application, the files created into the External Storage are completely free. This makes it particularly difficult to locate, copy, inspect, or delete all data associated with applications.
    Furthermore, upon removal of the app, while the data in the Internal Storage will be removed with the app, the data stored by the app in the External Storage will almost always be left on the device.

Introducing Scoped Storage – Android 10

On Android 10, Google introduced Scoped Storage to improve data security, by limiting the ability for applications to freely read and write data to the entire external storage. The original idea was to divide the total External Storage space into several parts, to:

  • give access to the External app-specific folders (Android/data/<package/file>) only to the owner app.
  • associate each file to the app that created it, regardless of where is located, in a private or in a public folder.

On Android 10, by default, an app have no filesystem-level access to External Storage by Context methods, but only through the filtering of the Storage Access Framework and Media Access Framework. Everything else is locked down by default.

However, to enable a smoother transition, Android 10 did not make the new approach as mandatory and introduced also a new requestLegacyExternalStorage=true attribute for application’s manifest (see https://developer.android.com/reference/android/R.attr#requestLegacyExternalStorage), to allow the default Android 9.0-style behavior to be restored on apps targeting for Android 10 and running:

  • Android 10
  • Android 11, with targetSdkVersion <= 29

Legacy applications that target Android 9 or earlier can access external storage without restrictions.

Due to the relevant impact of the Scoped Storage on apps architecture, for many enterprise applications a common choice for Android 10 has been to adopt requestLegacyExternalStorage=true to continue working as before, and to defer refactoring investments to future versions.

 

Strengthening Scoped Storage – Android 11

On Android 11 (API level 30) the enforcement of Scoped Storage access has been made much more effective, providing greater security for app and user data, but on other hand, it has been made mandatory for all the apps in almost all cases.

On Android 11 the directives for accessing the entire external storage are deprecated and ignored by the system. All the applications will be subject to Scoped Storage, forcing the companies to refactor the application that need to access Shared Storage Data or App-Private Data on External Storage.
Most use-cases, are well addressed by a list of Google best practices described in Android official documentation.

However, some applications require broad access to files on a device but can't access them efficiently using the best practices above.
For those kind of applications Android provided a special app access to the Shared Storage called all-files access. However, unlike the previous READ_EXTERNAL_STORAGE or WRITE_EXTERNAL_STORAGE permissions, the new "all-files access" permission allows access only to the shared archive (Download, Media...) and not to the entire external archive.

External app directories like Android/data/<com.another.package>/files are now always private, in the same way as Internal app directories.

Obtain access to Shared Storage on External Storage for special apps

A special application that wants to require the user the "all-files access" must apply these two actions:

  • Declare the android.permission.MANAGE_EXTERNAL_STORAGE permission in his manifest.

    Note:
    since MANAGE_EXTERNAL_STORAGE is a special permission only allowed for few apps like Antivirus, file manager, etc. according to Google's policy, when publishing the application on the PlayStore you will have to show that your app falls within permitted use-cases and justify why you need MANAGE_EXTERNAL_STORAGE.

  • Use the ACTION_MANAGE_ALL_FILES_ACCESS_PERMISSION intent action to direct users to a system settings page where they can enable the “Allow access to manage all files” option for the app itself:

This means that, differently from the previous “dangerous permission” like the READ_EXTERNAL_STORAGE or WRITE_EXTERNAL_STORAGE that was possible to grant trough EMMs, Scan2Deploy or Datalogic SDKs, to obtain the all-files access, an app requires an explicit user’s intervention to approve the access.

Avoid the user intervention to grant all-files access permission on Androin 11

To overcome this limitation in enterprise environment, starting from the new FW releases supporting SDK 1.34.4 (see Datalogic Android SDK FWs compatibility table), Datalogic gives the option to grant this permission via a Scan2Deploy script.

This is a script sample to grant MANAGE_EXTERNAL_STORAGE appops permission to a package using Datalogic Scan2Deploy Studio:

SHELL appops set --uid <PACKAGE_NAME> MANAGE_EXTERNAL_STORAGE allow




For more detail see also the News: Runtime permissions and Appops through SDK and Scan2Deploy.
A the following link you can find the Scan2Deploy studio official documentation on how to use Scan2Deploy Studio to install applications and run scripts

See Also:
Android 11 Storage Overview | Android 11 privacy changes
Storage updates in Android 11  |Android 11 storage changes
Storage Use Cases and Best Practices
 | Apps Migration
Android Storage Overview | The architecture of data and file storage in Android
Storage access with Android 11 | Video

---
update: October 23th, 2023
created on: May 8th, 2023