Problems that you may encounter
The Android system itself has its own storage, and the SD card can be used to expand the storage space. The former is like the hard disk in PC, the latter is good to move hard. The former space is small, the latter space is large, but the latter is not necessarily available. These issues may be encountered when developing applications that handle local data access:
- Need to determine whether the SD card is available: Occupy too much internal storage of the fuselage, easy to incur user antipathy, priority to store data in the SD card;
Application data storage path, should be consistent with other apps, erase data when the app unloads:
- Unconventional in the SD card root directory to create a directory, causing users to resent
- Users are disgusted with residual directories or data on the user's machine after uninstalling the application
Data security, the application data is not willing to be read and written by other applications;
Image cache, etc., should not be scanned into the user album and other Media library.
Basic operations
To use external storage, the required permissions are in AndoridManifest.xml
:
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" /><uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
Starting with API 19/andorid 4.4/kitkat, you no longer need to explicitly declare these two permissions unless you want to read and write application data from other apps ( $appDataDir
)
To determine the SD card available:
/** * Check if the primary "external" storage device is available. * * @return */public static boolean hasSDCardMounted() { String state = Environment.getExternalStorageState(); if (state != null && state.equals(Environment.MEDIA_MOUNTED)) { return true; } else { return false; }}
Usage of storage
Depending on the system user, the amount of storage space that can be occupied varies
At API Level 9 and above, File
the object's getFreeSpace()
method obtains the system root user free space;
getUsableSpace()
Take non-root user free space
Get disk usage When multiple stores are available, and choose the right storage based on current system conditions.
According to the system storage usage, reasonably set the size of the space used by the app, and can also do dynamic adjustment when running.
In the API level 9 and above the system, you can directly invoke File
the relevant methods of the object, the following self-calculation:
@TargetApi(VERSION_CODES.GINGERBREAD)public static long getUsableSpace(File path) { if (path == null) { return -1; } if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.GINGERBREAD) { return path.getUsableSpace(); } else { if (!path.exists()) { return 0; } else { final StatFs stats = new StatFs(path.getPath()); return (long) stats.getBlockSize() * (long) stats.getAvailableBlocks(); } }}
The law of the path
Generally, the Context
path to Environment
file access is obtained through and related methods.
With these two classes, you get a variety of paths,
($rootDir) +-/data-environment.getdatadirectory () | || | ($appDataDir) | +-data/com.srain.cube.sample| || | ($filesDir) | +-Files, Context.getfilesdir ()/Context.getfilestreampath ("") | | || | +-File1-Context.getfilestreampath ("File1") | | ($cacheDir) | +-Cache-Context.getcachedir () | || +-App_$name (Context.getdir (String name, int mode) | | ($rootDir) +-/storage/sdcard0-environment.getexternalstoragedirectory () | /Environment.getexternalstoragepublicdirectory ("") | +-Dir1-environment.getexternalstoragepublicdirectory ("Dir1") | | ($appDataDir) +-Andorid/data/com.srain.cube.sample | | ($filesDir) +-Context.getexternalfilesdir ("") | | | +-File1-Context.getexternalfilesdir ("File1") | +-Music--Context.getexternalfilesdir (Environment.music); | +-picture--... Environment.picture | +- ... | | ($cacheDir) +-Context.getexternalcachedir ()-cache | +- ???
Characteristics of each path
The following describes the characteristics of these paths and the details to be aware of in use:
root directory ( $rootDir
):
- Internal storage path:
/data
, by Environment.getDataDirectory()
getting
External storage path: /storage/sdcard0
(also similar to/mnt/), by Environment.getExternalStorageDirectory()
obtaining
Example:
Environment.getDataDirectory(): /dataEnvironment.getExternalStorageDirectory(): /storage/sdcard0
Application Data Catalog ( $appDataDir
)
- Internal storage:
$appDataDir = $rootDir/data/$packageName
,
- External storage:
$appDataDir = $rootDir/Andorid/data/$packageName
The data in these directories, after the app is uninstalled, will be deleted by the system, we should put the app's data in both directories.
The data directory that is exposed in external storage. These directories will not be deleted by the system as the app is deleted, please use:
Environment.getExternalStorageDirectory(): /storage/sdcard0// 同 $rootDirEnvironment.getExternalStoragePublicDirectory(""): /storage/sdcard0Environment.getExternalStoragePublicDirectory("folder1"): /storage/sdcard0/folder1
Directory under the Application Data directory
In general, under $appdatadir, there will be two directories:
Data cache: $cacheDir = $appDataDir/cache
:
- Internal storage:
Context.getCacheDir()
When the body is out of memory, the file is deleted
External storage:Context.getExternalCacheDir()
External storage without real-time monitoring, when the space is low, the file will not be deleted in real time, may return an empty object
Example:
Context.getCacheDir(): /data/data/com.srain.cube.sample/cacheContext.getExternalCacheDir(): /storage/sdcard0/Android/data/com.srain.cube.sample/cache
File directory $filesDir = $appDataDir/files
:
Internal storage: by Context.getFilesDir()
getting
Context.getFileStreamPath(String name)
Returns the name
file object as a filename, which is name
empty, and returns $filesDir
itself
Example:
Context.getFilesDir(): /data/data/com.srain.cube.sample/filesContext.getFileStreamPath(""): /data/data/com.srain.cube.sample/filesContext.getFileStreamPath("file1"): /data/data/com.srain.cube.sample/files/file1
External storage: Passed Context.getExternalFilesDir(String type)
as type
an empty string when fetched.
type
The system specifies several types:
Environment.DIRECTORY_MUSICEnvironment.DIRECTORY_PICTURES...
Example:
Context.getExternalFilesDir(""): /storage/sdcard0/Android/data/com.srain.cube.sample/filesContext.getExternalFilesDir(Environment.DIRECTORY_MUSIC) /storage/sdcard0/Android/data/com.srain.cube.sample/files/Music
$cacheDir / $filesDir
Security
In internal storage, the $cacheDir
app $filesDir
is secure, and other apps can't read the app's data, while the external storage is not.
In external storage, these two folders are also accessible to other applications.
In external storage, $filesDir
media files are not scanned as media and added to the Media Library.
$cacheDir / $filesDir
Sibling directory
In internal storage: through Context.getDir(String name, int mode)
the available and $filesDir
/or $cacheDir
sibling directories
The directory is named app_ + name
by the mode to control whether the directory is for app private or other apps to read and write.
Example:
Context.getDir("dir1", MODE_PRIVATE): Context.getDir: /data/data/com.srain.cube.sample/app_dir1
In particular, for external storage, get $cacheDir
or $filesDir
and the path below
Under API Level 8, or if there is not enough space, the associated method will need to be constructed when the path is empty.
@TargetApi(VERSION_CODES.FROYO)public static File getExternalCacheDir(Context context) { if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.FROYO)) { File path = context.getExternalCacheDir(); // In some case, even the sd card is mounted, // getExternalCacheDir will return null // may be it is nearly full. if (path != null) { return path; } } // Before Froyo or the path is null, // we need to construct the external cache folder ourselves final String cacheDir = "/Android/data/" + context.getPackageName() + "/cache/"; return new File(Environment.getExternalStorageDirectory().getPath() + cacheDir);}
Related code:Https://github.com/liaohuqiu/cube-sdk/blob/master/core/src/in/srain/cube/diskcache/FileUtils.java
Android file storage use reference