Android 11 - 在外部存储上创建特定于应用程序的目录
Android 11 - Creating app-specific directory on external storage
最近,我正在尝试将我的应用程序从 SDK-29 迁移到 SDK-30。
我最关心的一件事是分区存储。
我在 official document 上看到说“在 Android 11(API 级别 30)及更高版本上,应用无法在外部存储上创建自己的应用特定目录。”。 =13=]
所以我尝试在外部存储中创建自己的目录并向其中写入一个新文件。代码如下所示:
// creating new directory under external storage
val appDir = File(applicationContext.getExternalFilesDir(null), "play")
appDir.mkdir()
// writing new file under my own directory
val newFile = File(appDir.absolutePath, "test.jpg")
val outputStream = FileOutputStream(newFile)
val inputStream = resources.openRawResource(R.drawable.ic_launcher_foreground)
val data = byteArrayOf()
inputStream.read(data)
outputStream.write(data)
inputStream.close()
outputStream.close()
我预计这段代码会崩溃,但它有效。我在给定路径找到文件。所以,我有点搞不懂那张纸条的意思。
Google“无法在外部存储上创建自己的应用特定目录”是什么意思?
他们指的是从外部存储根创建任意目录(例如,Environment.getExternalStorageDirectory()
。
getExternalFilesDir()
和 Context
上的类似方法是替代使用的好解决方案!
在外部存储上创建特定于应用程序的目录,但不在根目录下。
private fun createDir(directoryName: String): File? {
val file = File(applicationContext.getExternalFilesDir("/"),directoryName)
if (!file?.mkdirs())
print("Volume : " + "Directory not created")
return file
}
注意:不需要任何存储权限。
在 root 的外部存储上创建特定于应用程序的目录。
Note: This is only work for Android 11.
请求用户访问所有文件:
- 在清单中声明 MANAGE_EXTERNAL_STORAGE 权限。
- 使用 ACTION_MANAGE_ALL_FILES_ACCESS_PERMISSION 意图操作来
将用户定向到系统设置页面,他们可以在其中启用
您的应用的以下选项:允许访问以管理所有文件。
- 确定您的应用是否已被授予
MANAGE_EXTERNAL_STORAGE权限,调用
Environment.isExternalStorageManager().
Write code on OnCreate Method:
if (!isExternalStorageReadable()) return
if (!Environment.isExternalStorageManager()) {
val intent = Intent(Settings.ACTION_MANAGE_APP_ALL_FILES_ACCESS_PERMISSION)
intent.addCategory("android.intent.category.DEFAULT")
intent.data = Uri.parse(String.format("package:%s", applicationContext.packageName))
startActivityForResult(intent, 20)
} else {
createDir("ddddd")
}
Declare two functions outside from OnCreate:
private fun isExternalStorageReadable(): Boolean {
return Environment.getExternalStorageState() in
setOf(Environment.MEDIA_MOUNTED, Environment.MEDIA_MOUNTED_READ_ONLY)
}
private fun createDir(directoryName: String): File? {
val file = File(Environment.getExternalStoragePublicDirectory("/"),directoryName)
if (!file?.mkdirs())
print("Volume : " + "Directory not created")
return file
}
最近,我正在尝试将我的应用程序从 SDK-29 迁移到 SDK-30。 我最关心的一件事是分区存储。
我在 official document 上看到说“在 Android 11(API 级别 30)及更高版本上,应用无法在外部存储上创建自己的应用特定目录。”。 =13=]
所以我尝试在外部存储中创建自己的目录并向其中写入一个新文件。代码如下所示:
// creating new directory under external storage
val appDir = File(applicationContext.getExternalFilesDir(null), "play")
appDir.mkdir()
// writing new file under my own directory
val newFile = File(appDir.absolutePath, "test.jpg")
val outputStream = FileOutputStream(newFile)
val inputStream = resources.openRawResource(R.drawable.ic_launcher_foreground)
val data = byteArrayOf()
inputStream.read(data)
outputStream.write(data)
inputStream.close()
outputStream.close()
我预计这段代码会崩溃,但它有效。我在给定路径找到文件。所以,我有点搞不懂那张纸条的意思。
Google“无法在外部存储上创建自己的应用特定目录”是什么意思?
他们指的是从外部存储根创建任意目录(例如,Environment.getExternalStorageDirectory()
。
getExternalFilesDir()
和 Context
上的类似方法是替代使用的好解决方案!
在外部存储上创建特定于应用程序的目录,但不在根目录下。
private fun createDir(directoryName: String): File? {
val file = File(applicationContext.getExternalFilesDir("/"),directoryName)
if (!file?.mkdirs())
print("Volume : " + "Directory not created")
return file
}
注意:不需要任何存储权限。
在 root 的外部存储上创建特定于应用程序的目录。
Note: This is only work for Android 11.
请求用户访问所有文件:
- 在清单中声明 MANAGE_EXTERNAL_STORAGE 权限。
- 使用 ACTION_MANAGE_ALL_FILES_ACCESS_PERMISSION 意图操作来 将用户定向到系统设置页面,他们可以在其中启用 您的应用的以下选项:允许访问以管理所有文件。
- 确定您的应用是否已被授予 MANAGE_EXTERNAL_STORAGE权限,调用 Environment.isExternalStorageManager().
Write code on OnCreate Method:
if (!isExternalStorageReadable()) return
if (!Environment.isExternalStorageManager()) {
val intent = Intent(Settings.ACTION_MANAGE_APP_ALL_FILES_ACCESS_PERMISSION)
intent.addCategory("android.intent.category.DEFAULT")
intent.data = Uri.parse(String.format("package:%s", applicationContext.packageName))
startActivityForResult(intent, 20)
} else {
createDir("ddddd")
}
Declare two functions outside from OnCreate:
private fun isExternalStorageReadable(): Boolean {
return Environment.getExternalStorageState() in
setOf(Environment.MEDIA_MOUNTED, Environment.MEDIA_MOUNTED_READ_ONLY)
}
private fun createDir(directoryName: String): File? {
val file = File(Environment.getExternalStoragePublicDirectory("/"),directoryName)
if (!file?.mkdirs())
print("Volume : " + "Directory not created")
return file
}