Android 内部存储和外部存储 - chuwuwang/ReadingNote GitHub Wiki
Internal File Storage 应用内部存储
-
存储永远都是处于可用状态的,通过Context.xxx API访问。
-
这部分数据都是应用私有的,理论上只有App自己才能够访问这些数据。
-
在应用程序被卸载时,内部存储的所有数据会被系统删除。
内部存储有2个重要目录
-
/data/app:所有安装的app的apk文件
-
/data/data:data目录存储私有数据
-
data/data/包名/files 文件信息
-
data/data/包名/cache 缓存信息
-
data/data/包名/databases 数据库信息
-
data/data/包名/shared_prefs SharedPreferences信息
-
默认情况下,保存到内部存储的文件是应用的私有文件,其他应用和用户不能访问这些文件。可以直接在设备的内部存储中保存、创建文件,而不需要任何访问权限。
-
Context.MODE_APPEND:该模式会检查文件是否存在,存在就往文件追加内容,否则就创建新文件。
-
Context.MODE_PRIVATE:默认操作模式,代表该文件是私有数据,只能被应用本身访问。在该模式下,写入的内容会覆盖原文件的内容。
Context.getDir(String name, int mode)
getDir("Joe", Context.MODE_APPEND).mkdirs()
// getDir(): /data/data/com.joe.kotlin/app_Joe
Context.getFilesDir()
// getFilesDir(): /data/data/com.joe.kotlin/files
Context.getCacheDir()
// getCacheDir(): /data/data/com.joe.kotlin/cache
Context.getDataDir() // API等级需要大于24才可以调用
内部存储的文件读写实例
private fun writeDataByInternalStorage(data: ByteArray, name: String, mode: Int) {
openFileOutput(name, mode).use {
it.write(data)
}
}
private fun readDataByInternalStorage(name: String): String {
val bas = ByteArrayOutputStream()
bas.use {
openFileInput(name).use {
val buff = ByteArray(1024)
var len = it.read(buff)
while (len > 0) {
bas.write(buff, 0, len)
len = it.read(buff)
}
return bas.toString()
}
}
}
External File Storage 应用外部存储
应用外部私有存储
-
外部私有存储属于应用独有,一般不会主动向外部提供数据。
-
其他应用可以通过类似绝对路径这样的方式访问该部分数据。
-
系统会在App卸载时移除外部私有存储中相关应用的数据。
在Android 4.4之后,访问应用外部私有存储不需要进行权限的申请。所有数据在/storage/emulated/0/Android/包名/文件下。
Environment的相关常量
- DIRECTORY_ALARMS:系统提醒铃声存放的标准目录
- DIRECTORY_DCIM:相机拍摄照片和视频的标准目录
- DIRECTORY_DOWNLOADS:下载的文件标准目录
- DIRECTORY_MOVIES:电影存放的标准目录
- DIRECTORY_MUSIC:音乐存放的标准目录
- DIRECTORY_NOTIFICATIONS:系统通知铃声存放的标准目录
- DIRECTORY_PICTURES:图片存放的标准目录
- DIRECTORY_PODCASTS:系统广播存放的标准目录
- DIRECTORY_RINGTONES:系统铃声存放的标准目录
Context.getExternalFilesDir(null)
// getExternalFilesDir: /storage/emulated/0/Android/data/com.joe.kotlin/files
Context.getExternalFilesDirs(null)
// getExternalFilesDirs[0]: /storage/emulated/0/Android/data/com.joe.kotlin/files
// getExternalFilesDirs[1]: null
Context.getExternalFilesDir(Environment.DIRECTORY_MUSIC)
// getExternalFilesDir_DIRECTORY_MUSIC: /storage/emulated/0/Android/data/com.joe.kotlin/files/Music
Context.getExternalFilesDir(Environment.DIRECTORY_MOVIES)
// getExternalFilesDir_DIRECTORY_MOVIES: /storage/emulated/0/Android/data/com.joe.kotlin/files/Movies
Context.getExternalCacheDir()
// getExternalCacheDir: /storage/emulated/0/Android/data/com.joe.kotlin/cache
Context.getExternalCacheDirs()
// getExternalCacheDirs[0]: /storage/emulated/0/Android/data/com.joe.kotlin/cache
// getExternalCacheDirs[1]: null
Context.getExternalMediaDirs()
// getExternalMediaDirs[0]: /storage/emulated/0/Android/media/com.joe.kotlin
// getExternalMediaDirs[1]: null
应用外部共有存储
-
一般指的是/storage/emulated/0下面,也就是/data/media挂载出来的。
-
除去/storage/emulated/0/Android之外的所有路径,比如storage/emulated/0/Pictures这些文件夹。
-
也包括外置sdcard,通过OTG挂载USB出来的存储,一般路径为/storage/xxxx-xxxx。
外部共有存储的路径跟应用本身没有关系,所以一般都是通过Environment类进行获取。而这些存储的数据也不会随着应用的卸载而丢失。
在API 29 getExternalStorageDirectory()、getExternalStoragePublicDirectory()已经被废弃。
相关权限
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
Environment.getRootDirectory() // 该目录下不可创建文件或文件夹
// getRootDirectory: /system
Environment.getDataDirectory() // 该目录下不可创建文件或文件夹
// getDataDirectory: /data
Environment.getDownloadCacheDirectory() // 该目录下不可创建文件或文件夹
// getDownloadCacheDirectory: /cache
Environment.getExternalStorageDirectory() // 可自由创建 需要读写权限
// getExternalStorageDirectory: /storage/emulated/0
Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_MUSIC) // 可自由创建 需要读写权限
// getExternalStoragePublicDirectory_DIRECTORY_MUSIC: /storage/emulated/0/Music
Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_DOCUMENTS) // 可自由创建 需要读写权限
// getExternalStoragePublicDirectory_DIRECTORY_DOCUMENTS: /storage/emulated/0/Documents
检查外部存储的状态
/* Checks if external storage is available for read and write */
fun isExternalStorageWritable(): Boolean {
return Environment.getExternalStorageState() == Environment.MEDIA_MOUNTED
}
/* Checks if external storage is available to at least read */
fun isExternalStorageReadable(): Boolean {
return Environment.getExternalStorageState() in setOf(
Environment.MEDIA_MOUNTED,
Environment.MEDIA_MOUNTED_READ_ONLY
)
}