Android open external file

External storage

External storage refers to file storage that is not on internal storage and not exclusively accessible to the app that is responsible for the file. The primary purpose of external storage is to provide a place to put files that are meant to be shared between apps or that are too large to fit on the internal storage.

Historically speaking, external storage referred to a disk partition on removable media such as an SD card (was also known as portable storage). This distinction is no longer as relevant as Android devices have evolved and many Android devices no longer support removable storage. Instead some devices will allocate some of their internal non-volatile memory which Android to perform the same function removable media. This is known as emulated storage and is still considered to be external storage. Alternately, some Android devices may have multiple external storage partitions. For example, an Android tablet (in addition to its internal storage) might have emulated storage and one or more slots for an SD card. All of these partitions are treated by Android as external storage.

On devices that have multiple users, each user will have a dedicated directory on the primary external storage partition for their external storage. Apps running as one user will not have access to files from another user on the device. The files for all users are still world-readable and world-writeable; however, Android will sandbox each user profile fromthe others.

Reading and writing to files is almost identical in Xamarin.Android as it is to any other .NET application. The Xamarin.Android app determines the path to the file that will be manipulated, then uses standard .NET idioms for file access. Because the actual paths to internal and external storage may vary from device to device or from Android version to Android version, it is not recommended to hard code the path to the files. Instead, Xamarin.Android exposes the native Android APIs that will help with determining the path to files on internal and external storage.

This guide will discuss the concepts and APIs in Android that are specific to external storage.

Public and private files on external storage

There are two different types of files that an app may keep on external storage:

Private files – Private files are files that are specific to your application (but are still world-readable and world-writable). Android expects that private files are stored in a specific directory on external storage. Even though the files are called «private», they are still visible and accessible by other apps on the device, they are not afforded any special protection by Android.

Public files – These are files that are not considered to be specific to the application and are meant to be freely shared.

The differences between these files is primarily conceptual. Private files are private in the sense that they are considered to be a part of the application, while public files are any other files that exist on external storage. Android provides two different APIs for resolving the paths to private and public files, but otherwise the same .NET APIs are used to read and write to these files. These are the same APIs that are discussed in the section on reading and writing.

Private external files

Private external files are considered to be specific to an application (similar to internal files) but are being kept on external storage for any number of reasons (such as being too large for internal storage). Similar to internal files, these files will be deleted when the app is uninstalled by the user.

The primary location for private external files is found by calling the method Android.Content.Context.GetExternalFilesDir(string type) . This method will return a Java.IO.File object that represents the private external storage directory for the app. Passing null to this method will return the path to the user’s storage directory for the application. As an example, for an application with the package name com.companyname.app , the «root» directory of the private external files would be:

Читайте также:  Android browser с блокировкой рекламы

This document will refer to the storage directory for private files on external storage as PRIVATE_EXTERNAL_STORAGE.

The parameter for GetExternalFilesDir() is a string that specifies an application directory. This is a directory intended to provide a standard location for a logical organization of files. The string values are available through constants on the Android.OS.Environment class:

Android.OS.Environment Directory
DirectoryAlarms PRIVATE_EXTERNAL_STORAGE/Alarms
DirectoryDcim PRIVATE_EXTERNAL_STORAGE/DCIM
DirectoryDownloads PRIVATE_EXTERNAL_STORAGE/Download
DirectoryDocuments PRIVATE_EXTERNAL_STORAGE/Documents
DirectoryMovies PRIVATE_EXTERNAL_STORAGE/Movies
DirectoryMusic PRIVATE_EXTERNAL_STORAGE/Music
DirectoryNotifications PRIVATE_EXTERNAL_STORAGE/Notifications
DirectoryPodcasts PRIVATE_EXTERNAL_STORAGE/Podcasts
DirectoryRingtones PRIVATE_EXTERNAL_STORAGE/Ringtones
DirectoryPictures PRIVATE_EXTERNAL_STORAGE/Pictures

For devices that have multiple external storage partitions, each partition will have a directory that is intended for private files. The method Android.Content.Context.GetExternalFilesDirs(string type) will return an array of Java.IO.Files . Each object will represent a private application-specific directory on all shared/external storage devices where the application can place the files it owns.

The exact path to the private external storage directory can vary from device to device and between versions of Android. Because of this, apps must not hard code the path to this directory, and instead use the Xamarin.Android APIs, such as Android.Content.Context.GetExternalFilesDir() .

Public external files

Public files are files that exist on external storage that are not stored in the directory that Android allocates for private files. Public files will not be deleted when the app is uninstalled. Android apps must be granted permission before they can read or write any public files. It is possible for public files to exist anywhere on external storage, but by convention Android expects public files to exist in the directory identified by the property Android.OS.Environment.ExternalStorageDirectory . This property will return a Java.IO.File object that represents the primary external storage directory. As an example, Android.OS.Environment.ExternalStorageDirectory may refer to the following directory:

This document will refer to the storage directory for public files on external storage as PUBLIC_EXTERNAL_STORAGE.

Android also supports the concept of application directories on PUBLIC_EXTERNAL_STORAGE. These directories are exactly the same as the application directories for PRIVATE_EXTERNAL_STORAGE and are described in the table in the previous section. The method Android.OS.Environment.GetExternalStoragePublicDirectory(string directoryType) will return a Java.IO.File object that correspond to a public application directory. The directoryType parameter is a mandatory parameter and cannot be null .

For example, calling Environment.GetExternalStoragePublicDirectory(Environment.DirectoryDocuments).AbsolutePath will return a string which will resemble:

The exact path to the public external storage directory can vary from device to device and between versions of Android. Because of this, apps must not hard code the path to this directory, and instead use the Xamarin.Android APIs, such as Android.OS.Environment.ExternalStorageDirectory .

Working with external storage

Once a Xamarin.Android app has obtained the full path to a file, it should utilize any of the standard .NET APIs for creating, reading, writing, or deleting files. This maximizes the amount of cross platform compatible code for an app. However, before attempting to access a file a Xamarin.Android app must ensure that is it possible to access that file.

  1. Verify external storage – Depending on the nature of the external storage, it is possible that it might not be mounted and usable by the app. All apps should check the state of the external storage before attempting to use it.
  2. Perform a runtime permission check – An Android app must request permission from the user in order to access external storage. This means that a run time permission request should be performed prior to any file access. The guide Permissions In Xamarin.Android contains more details on Android permissions.

Each of these two tasks will be discussed below.

Verifying that external storage is available

The first step before writing to external storage is to check that it is readable or writeable. The Android.OS.Environment.ExternalStorageState property holds a string that identifies the state of the external storage. This property will return a string that represents the state. This table is a list of the ExternalStorageState values that might be returned by Environment.ExternalStorageState :

ExternalStorageState Description
MediaBadRemoval The media was abruptly removed without being properly unmounted.
MediaChecking The media is present but undergoing a disk check.
MediaEjecting Media is in the process of being unmounted and ejected.
MediaMounted Media is mounted and can be read or written to.
MediaMountedReadOnly Media is mounted but can only be read from.
MediaNofs Media is present but does not contain a filesystem suitable for Android.
MediaRemoved There is no media present.
MediaShared Media is present, but is not mounted. It is being shared via USB with another device.
MediaUnknown The state of the media is unrecognized by Android.
MediaUnmountable The media is present but cannot be mounted by Android.
MediaUnmounted The media is present but is not mounted.

Most Android apps will only need to check if external storage is mounted. The following code snippet shows how to verify that external storage is mounted for read-only access or read-write access:

External storage permissions

Android considers accessing external storage to be a dangerous permission, which typically requires the user to grant their permission to access the resource. The user may revoke this permission at any time. This means that a run time permission request should be performed prior to any file access. Apps are automatically granted permissions to read and write their own private files. It is possible for apps to read and write the private files that belong to other apps after being granted permission by the user.

All Android apps must declare one of the two permissions for external storage in the AndroidManifest.xml . To identify the permissions, one of the following two uses-permission elements must be add to AndroidManifest.xml:

If the user grants WRITE_EXTERNAL_STORAGE , then READ_EXTERNAL_STORAGE is also implicitly granted. It is not necessary to request both permissions in AndroidManifest.xml.

The permissions may also be added using the Android Manifest tab of the solution properties:

The permissions may also be added using the Android Manifest tab of the solution properties pad:

Generally speaking, all dangerous permissions must be approved by the user. The permissions for external storage are an anomaly in that there are exceptions to this rule, depending on the version of Android that the app is running:

Источник

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.

Источник

Читайте также:  Технические характеристики андроид студио
Оцените статью