Adaptation Rules for Android10 Partitioned Storage
- 2021-12-12 09:50:37
- OfStack
Directory store permissions
Internal storage external storage adaptation
Storage permissions
Adaptation
Get an external storage folder
Storage permissions
Android Q still uses READ_EXTRNAL_STORAGE and WRITE_EXTRNAL_STORAGE as storage-related runtime permissions but now even if
With these permissions, access to external storage is restricted, and only files in its own directory and files in the public body can be accessed
Internal storage external storage
内部存储 | 外部存储 | 备注 | |
---|---|---|---|
英文名称 | Internal storage | External storage | |
版本变更 | 不变 | 4.4之前,外部存储仅仅代表SD卡之类的移动存储设备,4.4之后包括内置的外部存储和SD卡(部分手机没有提供SD卡的卡槽,就只有内置的外部存储) | |
查看方法 | 用模拟器+adb shell 进入 或者是Android Studio Devices File Explorer | 1般的文档管理App 都能看 | 用 su root 命令给模拟器加权限 |
组成成分 | System/:存放系用数据 data/: 存放应用相关数据 vendor/:用于存放厂商客制化的数据等 | 私有存储区:android/ 文件夹下,是应用的私有存储区域 公共存储区域:Movie、Download、 DCIM、 Picture、Documents、Ringtones、Music、 Alarms | |
存储内容 | db share preference files cache 等 | 开发者自己需要存储的数据 如视频文件、音频文件、或者1些表格 日志文件 | 内部存储小而且宝贵我们基本上不要操作它,需要存储的都存储在外部存储 |
获取路径方法 | Environment.getDataDirectory() Context.getFileDir() | Environment.getExternalStorageDirectory() (traget>=30,已废弃) Context.getExternalFilesDir() | 基本上Context的方法获取的都是应用的私有存储路径 E nvironment的方法获取的都是根目录 |
应用卸载时 | 私有路径下的文件全部删除 即:data/user/0/packageName/ | 私有路径下的文件全部删除 即:android/data/packageName/ 公共存储区域不变动 |
Adaptation
Get an external storage folder
// If there is no fileDirName Folders are created automatically
val file:File = context.getExternalFileDir("fileDirName") // fileDirName Folder name
// /storage/emulated/0/Android/data/packageName/files/fileDirName
Create an external storage file
val appFileDirName = applicationContext.getExternalFilesDir("fileDirName")?.absolutePath
val newFile = File(appFileDirName, "temp.txt")
val fileWriter = FileWriter(newFile)
fileWriter.write("test information")
fileWriter.flush()
fileWriter.close()
Create a file path under the public directory of external storage
/**
* @param fileName File name
* @param relativePath Contains sub-paths under a media
*/
fun insertFileIntroMediaStore(
context: Context,
fileName: String,
relativePath: String
): Uri? {
if (Build.VERSION.SDK_INT < Build.VERSION_CODES.Q) {
return null
}
val contentResolver = context.contentResolver
val values = ContentValues()
values.put(MediaStore.Downloads.DISPLAY_NAME, fileName)
values.put(MediaStore.Downloads.MIME_TYPE, "text/plain")
values.put(MediaStore.Downloads.RELATIVE_PATH, relativePath)
// Verify the availability of storage space
// Because the external storage space is located on a physical volume that the user may be able to remove, the application special is attempted to read from the external storage space
// Verify that the volume is accessible before you write application-specific data to external storage.
// You can do this by calling the Environment.getExternalStorageState() Query the status of the volume. If the returned status is MEDIA_MOUNTED You can read and write application-specific files in external storage. If the returned status is MEDIA_MOUNTED_READ_ONLY You can only read these files.
val externalStorageState = Environment.getExternalStorageState()
return if (externalStorageState.equals(Environment.MEDIA_MOUNTED)) {
contentResolver.insert(MediaStore.Downloads.EXTERNAL_CONTENT_URI, values)
} else {
contentResolver.insert(MediaStore.Downloads.INTERNAL_CONTENT_URI, values)
}
}
/**
* @param context Context
* @param insertUri Storage Uri
* @param inputStream File output stream
*/
fun saveFile(context: Context, insertUri: Uri?, inputStream: InputStream?) {
insertUri ?: return
inputStream ?: return
val resolver = context.contentResolver
val out = resolver.openOutputStream(insertUri)
var read: Int
val buffer = ByteArray(1024)
while (inputStream.read(buffer).also { read = it } != -1) {
out?.write(buffer)
}
inputStream.close()
out?.flush()
out?.close()
}
/**
* @param context Context
* @param insertUri Storage Uri
* @param sourceFile Resource file
*/
fun saveFile(context: Context, insertUri: Uri?, sourceFile: File?) {
insertUri ?: return
sourceFile ?: return
val inputStream = FileInputStream(sourceFile)
val resolver = context.contentResolver
val out = resolver.openOutputStream(insertUri)
var read: Int
val buffer = ByteArray(1024)
while (inputStream.read(buffer).also { read = it } != -1) {
out?.write(buffer)
}
inputStream.close()
out?.flush()
out?.close()
}
Read external storage public directory files
/**
* Get the file output stream by uri
* @param context Context
* @param uri File path
*/
fun getInputStreamByUri(context: Context, uri: Uri?): InputStream? {
uri ?: return null
val openFileDescriptor = context.contentResolver.openFileDescriptor(uri, "r")
return FileInputStream(openFileDescriptor?.fileDescriptor)
}
The above is the Android10 partition storage use summary of the details, more information about the use of Android10 partition storage please pay attention to other related articles on this site!