一 引入分区存储
原因;为了让用户更好地管理自己的文件并减少混乱
内部存储:
获取方式:context.getCacheDir(); 存储路径data/user/0/package/cache ,容量较小,当系统内部存储空间较小时,有被系统删除风险
外部存储:
1.外部私有存储 获取方式Context.getExternalFilesDir()路径:/storage/sdcrad0/Android/data/package/files下
2.外部公共路径存储 通过MediaStore进行增删改查,默认插入路径/storage/sdcrad0/Pictures,可通过指定相对路径指定到Environment.DIRECTORY_DCIM ,Environment.DIRECTORY_MOVIES,等路径;
二 访问权限变更
使用分区存储的应用对自己创建的文件始终拥有读/写权限,无论文件是否位于应用的专有目录内。因此,如果您的应用仅保存和访问自己创建的文件,则无需请求获得READ_EXTERNAL_STORAGE或WRITE_EXTERNAL_STORAGE权限。不过,若要访问其他应用创建的文件,则必须满足以下两个条件: 您的应用已获得 READ_EXTERNAL_STORAGE 权限。
这些文件位于以下其中一个明确定义的媒体集合中:
照片:存储在MediaStore.Images中。
视频:存储在MediaStore.Video中。
音频文件:存储在MediaStore.Audio中。
那如何访问MediaStore.Download,等路径呢?必须使用存储访问框架 问题,如果想访问其他应用的外部存储得私有目录呢?
三 文件存储方式
1.外部文件公开目录,判断sdcard可否存储:
fun isExternalStorageWritable(): Boolean {
return Environment.getExternalStorageState() == Environment.MEDIA_MOUNTED
}
fun isExternalStorageReadable(): Boolean {
return Environment.getExternalStorageState() in
setOf(Environment.MEDIA_MOUNTED, Environment.MEDIA_MOUNTED_READ_ONLY)
}
2.保存照片、音频文件或视频剪辑到外部文件公开目录
MedieStore.Image.Media.insertImage:会生成缩略图,全局查询可以查到两张图 contentResover.insert(uri,contentvalues):适用于图片和视频和音频 ACTION_CREATE_DOCUMENTintent:适用于pdf,等其他格式文件,存储访问框架得一部分
3.外部私有目录:getexternalfiledir获取到路径 val file = File(content.getexernalFiledir(null),Enviorment.DIRECTORY_DCIM)
4.文件读写方式:Android q以前使用流,q是使用文件描述符:
常用读写:
fun write(file: File, any: Any, context: Context) {
val descriptor = getDescriptor(file, context) ?: return
ObjectOutputStream(FileOutputStream(descriptor.fileDescriptor)).safeUse {
it.writeObject(any)
}
descriptor.safeClose()
}
fun readString(file: File, context: Context): String? {
val descriptor = getDescriptor(file, context) ?: return null
FileInputStream(descriptor.fileDescriptor).safeUse { return it.readString() }
descriptor.safeClose()
return null
}
private fun getDescriptor(path: File, context: Context): AssetFileDescriptor? {
val uri = Uri.parse(file.absolutePath)
return context.contentResolver.openAssetFileDescriptor(uri, "r")
}