Android app accessing files

Manage all files on a storage device

The majority of apps that require shared storage access can follow the best practices for sharing media files and sharing non-media files. However, some apps have a core use case that requires broad access of files on a device, but cannot do so efficiently using the privacy-friendly storage best practices. Android provides a special app access called All files access for these situations.

For example, an anti-virus app’s primary use case might require regular scanning of many files across different directories. If this scanning requires repeated user interactions to select directories using the system file picker, it may provide a poor user experience. Other use cases—such as file manager apps, backup and restore apps, and document management apps—may require similar considerations.

Request All files access

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

  1. Declare the MANAGE_EXTERNAL_STORAGE permission in the manifest.
  2. 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.

To determine whether your app has been granted the MANAGE_EXTERNAL_STORAGE permission, call Environment.isExternalStorageManager() .

Operations that MANAGE_EXTERNAL_STORAGE allows

The MANAGE_EXTERNAL_STORAGE permission grants the following:

Read and write access to all files within shared storage.

Access to the contents of the MediaStore.Files table.

Access to the root directory of both the USB on-the-go (OTG) drive and the SD card.

Write access to all internal storage directories⁠, except for /Android/data/ , /sdcard/Android , and most subdirectories of /sdcard/Android . This write access includes direct file path access.

Apps that are granted this permission still cannot access the app-specific directories that belong to other apps because these directories appear as subdirectories of Android/data/ on a storage volume.

When an app has the MANAGE_EXTERNAL_STORAGE permission, it can access these additional files and directories using either the MediaStore API or direct file paths. When you use the Storage Access Framework, however, you can only access a file or directory if you could do so without having the MANAGE_EXTERNAL_STORAGE permission.

Invoke another app’s storage management activity

On Android 12 (API level 31) and higher, apps that have both the MANAGE_EXTERNAL_STORAGE permission and the QUERY_ALL_PACKAGES permission—such as file management apps—can use the getManageSpaceActivityIntent() to send users to another app’s custom space management activity.

The getManageSpaceActivityIntent() method takes in a package name and a request code, and it returns one of the following:

  • A PendingIntent , if the app with the specified package name has defined a custom «manage space» activity. The file management app that called the getManageSpaceActivityIntent() method can then invoke the returned intent to send users to the custom activity.
  • null , if the app with the specified package name doesn’t define a «manage space» activity.

Enable MANAGE_EXTERNAL_STORAGE for testing

To explore how the MANAGE_EXTERNAL_STORAGE permission affects your app, you can enable the permission for testing purposes. To do so, run the following command on the machine that’s connected to your test device:

Google Play notice

This section provides a notice for developers who publish apps on Google Play.

To limit broad access to shared storage, the Google Play store has updated its policy to evaluate apps that target Android 11 (API level 30) or higher and request «All files access» through the MANAGE_EXTERNAL_STORAGE permission. This policy takes effect in May 2021.

When your app targets Android 11 or higher, and it declares the MANAGE_EXTERNAL_STORAGE permission, Android Studio shows the lint warning that appears in figure 1. This warning reminds you that «the Google Play store has a policy that limits usage of» the permission.

Figure 1. Lint warning in Android Studio that reminds you about the Google Play policy regarding the MANAGE_EXTERNAL_STORAGE permission.

You should request the MANAGE_EXTERNAL_STORAGE permission only when your app cannot effectively make use of the more privacy-friendly APIs, such as Storage Access Framework or the Media Store API. Additionally, the app’s usage of the permission must fall within permitted uses, and must be directly tied to the core functionality of the app. If your app includes a use case that’s similar to the following examples, it’s likely to be allowed to request the MANAGE_EXTERNAL_STORAGE permission:

  • File managers
  • Backup and restore apps
  • Anti-virus apps
  • Document management apps
  • On-device file search
  • Disk and file encryption
  • Device-to-device data migration
Читайте также:  Не приходят оповещения ватсап андроид

Content and code samples on this page are subject to the licenses described in the Content License. Java is a registered trademark of Oracle and/or its affiliates.

Источник

Open files using storage access framework

Android 4.4 (API level 19) introduces the Storage Access Framework (SAF). The SAF makes it simple for users to browse and open documents, images, and other files across all of their preferred document storage providers. A standard, easy-to-use UI lets users browse files and access recents in a consistent way across apps and providers.

Cloud or local storage services can participate in this ecosystem by implementing a DocumentsProvider that encapsulates their services. Client apps that need access to a provider’s documents can integrate with the SAF with just a few lines of code.

The SAF includes the following:

  • Document provider—A content provider that allows a storage service (such as Google Drive) to reveal the files it manages. A document provider is implemented as a subclass of the DocumentsProvider class. The document-provider schema is based on a traditional file hierarchy, though how your document provider physically stores data is up to you. The Android platform includes several built-in document providers, such as Downloads, Images, and Videos.
  • Client app—A custom app that invokes the ACTION_CREATE_DOCUMENT , ACTION_OPEN_DOCUMENT , and ACTION_OPEN_DOCUMENT_TREE intent actions and receives the files returned by document providers.
  • Picker—A system UI that lets users access documents from all document providers that satisfy the client app’s search criteria.

Some of the features offered by the SAF are as follows:

  • Lets users browse content from all document providers, not just a single app.
  • Makes it possible for your app to have long term, persistent access to documents owned by a document provider. Through this access users can add, edit, save, and delete files on the provider.
  • Supports multiple user accounts and transient roots such as USB storage providers, which only appear if the drive is plugged in.

Overview

The SAF centers around a content provider that is a subclass of the DocumentsProvider class. Within a document provider, data is structured as a traditional file hierarchy:

Figure 1. Document provider data model. A Root points to a single Document, which then starts the fan-out of the entire tree.

Note the following:

  • Each document provider reports one or more ‘roots’, which are starting points into exploring a tree of documents. Each root has a unique COLUMN_ROOT_ID , and it points to a document (a directory) representing the contents under that root. Roots are dynamic by design to support use cases like multiple accounts, transient USB storage devices, or user login/logout.
  • Under each root is a single document. That document points to 1 to N documents, each of which in turn can point to 1 to N documents.
  • Each storage backend surfaces individual files and directories by referencing them with a unique COLUMN_DOCUMENT_ID . Document IDs must be unique and not change once issued, since they are used for persistent URI grants across device reboots.
  • Documents can be either an openable file (with a specific MIME type), or a directory containing additional documents (with the MIME_TYPE_DIR MIME type).
  • Each document can have different capabilities, as described by COLUMN_FLAGS . For example, FLAG_SUPPORTS_WRITE , FLAG_SUPPORTS_DELETE , and FLAG_SUPPORTS_THUMBNAIL . The same COLUMN_DOCUMENT_ID can be included in multiple directories.

Control flow

As stated above, the document provider data model is based on a traditional file hierarchy. However, you can physically store your data however you like, as long as you can access it by using DocumentsProvider API. For example, you could use tag-based cloud storage for your data.

Figure 2 shows how a photo app might use the SAF to access stored data:

Figure 2. Storage Access Framework Flow

Note the following:

  • In the SAF, providers and clients don’t interact directly. A client requests permission to interact with files (that is, to read, edit, create, or delete files).
  • The interaction starts when an application (in this example, a photo app) fires the intent ACTION_OPEN_DOCUMENT or ACTION_CREATE_DOCUMENT . The intent can include filters to further refine the criteria—for example, «give me all openable files that have the ‘image’ MIME type.»
  • Once the intent fires, the system picker goes to each registered provider and shows the user the matching content roots.
  • The picker gives users a standard interface for accessing documents, even though the underlying document providers may be very different. For example, figure 2 shows a Google Drive provider, a USB provider, and a cloud provider.
Читайте также:  Входящие вызовы андроид блокирует уведомления этой категории как включить huawei

Figure 3 shows a picker in which a user searching for images has selected the Downloads folder. It also shows all of the roots available to the client app.

Figure 3. Picker

After the user selects the Downloads folder, the images are displayed. Figure 4 shows the result of this process. The user can now interact with these images in the ways that the provider and client app support.

Figure 4. Images stored in the Downloads folder, as viewed in the system picker

Writing a client app

On Android 4.3 and lower, if you want your app to retrieve a file from another app, it must invoke an intent such as ACTION_PICK or ACTION_GET_CONTENT . The user must then select a single app from which to pick a file and the selected app must provide a user interface for the user to browse and pick from the available files.

On Android 4.4 (API level 19) and higher, you have the additional option of using the ACTION_OPEN_DOCUMENT intent, which displays a system-controlled picker UI controlled that allows the user to browse all files that other apps have made available. From this single UI, the user can pick a file from any of the supported apps.

On Android 5.0 (API level 21) and higher, you can also use the ACTION_OPEN_DOCUMENT_TREE intent, which allows the user to choose a directory for a client app to access.

Note: ACTION_OPEN_DOCUMENT is not intended to be a replacement for ACTION_GET_CONTENT . The one you should use depends on the needs of your app:

  • Use ACTION_GET_CONTENT if you want your app to simply read or import data. With this approach, the app imports a copy of the data, such as an image file.
  • Use ACTION_OPEN_DOCUMENT if you want your app to have long term, persistent access to documents owned by a document provider. An example would be a photo-editing app that lets users edit images stored in a document provider.

For more information on how to support browsing for files and directories using the system picker UI, see the guide on how to access documents and other files.

Additional resources

For more information about document providers, take advantage of the following resources:

Источник

Data and file storage overview

Android uses a file system that’s similar to disk-based file systems on other platforms. The system provides several options for you to save your app data:

  • App-specific storage: Store files that are meant for your app’s use only, either in dedicated directories within an internal storage volume or different dedicated directories within external storage. Use the directories within internal storage to save sensitive information that other apps shouldn’t access.
  • Shared storage: Store files that your app intends to share with other apps, including media, documents, and other files.
  • Preferences: Store private, primitive data in key-value pairs.
  • Databases: Store structured data in a private database using the Room persistence library.

The characteristics of these options are summarized in the following table:

Type of content Access method Permissions needed Can other apps access? Files removed on app uninstall?
App-specific files Files meant for your app’s use only From internal storage, getFilesDir() or getCacheDir()

From external storage, getExternalFilesDir() or getExternalCacheDir()

Never needed for internal storage

Not needed for external storage when your app is used on devices that run Android 4.4 (API level 19) or higher

No Yes
Media Shareable media files (images, audio files, videos) MediaStore API READ_EXTERNAL_STORAGE when accessing other apps’ files on Android 11 (API level 30) or higher

READ_EXTERNAL_STORAGE or WRITE_EXTERNAL_STORAGE when accessing other apps’ files on Android 10 (API level 29)

Permissions are required for all files on Android 9 (API level 28) or lower

Yes, though the other app needs the READ_EXTERNAL_STORAGE permission No
Documents and other files Other types of shareable content, including downloaded files Storage Access Framework None Yes, through the system file picker No
App preferences Key-value pairs Jetpack Preferences library None No Yes
Database Structured data Room persistence library None No Yes

The solution you choose depends on your specific needs:

How much space does your data require? Internal storage has limited space for app-specific data. Use other types of storage if you need to save a substantial amount of data. How reliable does data access need to be? If your app’s basic functionality requires certain data, such as when your app is starting up, place the data within internal storage directory or a database. App-specific files that are stored in external storage aren’t always accessible because some devices allow users to remove a physical device that corresponds to external storage. What kind of data do you need to store? If you have data that’s only meaningful for your app, use app-specific storage. For shareable media content, use shared storage so that other apps can access the content. For structured data, use either preferences (for key-value data) or a database (for data that contains more than 2 columns). Should the data be private to your app? When storing sensitive data—data that shouldn’t be accessible from any other app—use internal storage, preferences, or a database. Internal storage has the added benefit of the data being hidden from users.

Categories of storage locations

Android provides two types of physical storage locations: internal storage and external storage. On most devices, internal storage is smaller than external storage. However, internal storage is always available on all devices, making it a more reliable place to put data on which your app depends.

Removable volumes, such as an SD card, appear in the file system as part of external storage. Android represents these devices using a path, such as /sdcard .

Apps themselves are stored within internal storage by default. If your APK size is very large, however, you can indicate a preference within your app’s manifest file to install your app on external storage instead:

Permissions and access to external storage

On earlier versions of Android, apps needed to declare the READ_EXTERNAL_STORAGE permission to access any file outside the app-specific directories on external storage. Also, apps needed to declare the WRITE_EXTERNAL_STORAGE permission to write to any file outside the app-specific directory.

More recent versions of Android rely more on a file’s purpose than its location for determining an app’s ability to access, and write to, a given file. In particular, if your app targets Android 11 (API level 30) or higher, the WRITE_EXTERNAL_STORAGE permission doesn’t have any effect on your app’s access to storage. This purpose-based storage model improves user privacy because apps are given access only to the areas of the device’s file system that they actually use.

Android 11 introduces the MANAGE_EXTERNAL_STORAGE permission, which provides write access to files outside the app-specific directory and MediaStore . To learn more about this permission, and why most apps don’t need to declare it to fulfill their use cases, see the guide on how to manage all files on a storage device.

Scoped storage

To give users more control over their files and to limit file clutter, apps that target Android 10 (API level 29) and higher are given scoped access into external storage, or scoped storage, by default. Such apps have access only to the app-specific directory on external storage, as well as specific types of media that the app has created.

Use scoped storage unless your app needs access to a file that’s stored outside of an app-specific directory and outside of a directory that the MediaStore APIs can access. If you store app-specific files on external storage, you can make it easier to adopt scoped storage by placing these files in an app-specific directory on external storage. That way, your app maintains access to these files when scoped storage is enabled.

To prepare your app for scoped storage, view the storage use cases and best practices guide. If your app has another use case that isn’t covered by scoped storage, file a feature request. You can temporarily opt-out of using scoped storage.

View files on a device

To view the files stored on a device, use Android Studio’s Device File Explorer.

Additional resources

For more information about data storage, consult the following resources.

Videos

Content and code samples on this page are subject to the licenses described in the Content License. Java is a registered trademark of Oracle and/or its affiliates.

Источник

Читайте также:  Компилятор не может создавать код для этого профиля qt android
Оцените статью