一、AndroidManifest.xml 添加权限
<!-- 往SDCard写入数据权限 -->
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
<!--在sdcard中创建/删除文件的权限 -->
<uses-permission android:name="android.permission.MOUNT_UNMOUNT_FILESYSTEMS"
tools:ignore="ProtectedPermissions" />
二、AndroidManifest.xml 在application标签里添加
android:requestLegacyExternalStorage="true"
Android Q文件存储机制修改成了沙盒模式,有点模仿苹果的意思。APP只能访问自己目录下的文件和公共媒体文件。对于AndroidQ以下,还是使用老的文件存储方式。Android Q仍然使用READ_EXTERNAL_STORAGE和WRITE_EXTERNAL_STORAGE作为存储相关运行时权限,但现在即使获取了这些权限,访问外部存储也受到了限制。
android:requestLegacyExternalStorage=“true” 的意思就是使用旧的存储策略,不使用androidQ的新策略。但这个不是长久之计,很快将会强制都使用新策略。
三、代码
/*
* 从Apk本地Assets复制文件到指定文件夹
*
*/
private boolean copyFileFromAssets() {
boolean result = false;
//手机更目录创建MP3Test文件夹
String filepath=Environment.getExternalStorageDirectory().getAbsolutePath() + "/MP3Test/";
//这是放在私有文件夹里
//String filepath = this.getApplicationContext().getFilesDir().getAbsolutePath() + "/oneLing.mp3";
Log.i("filepath", "copyFileFromAssets: " + filepath);
String fileName = "oneLing.mp3";//文件名称
File dir = new File(filepath);
Log.i("path", "copyData: " + filepath);
File file = new File(dir, fileName);
if (!dir.exists() || !dir.isDirectory()) {
dir.mkdirs();
}
InputStream inputStream = null;
OutputStream outputStream = null;
if (!file.exists()) {
try {
file.createNewFile();
inputStream = this.getAssets().open(fileName);
outputStream = new FileOutputStream(file);
byte[] buffer = new byte[1024];
int len;
while ((len = inputStream.read(buffer)) != -1) {
outputStream.write(buffer, 0, len);
}
outputStream.flush();
outputStream.close();
inputStream.close();
result = true;
} catch (IOException e) {
e.printStackTrace();
}
} else {
try {
file.delete();
file.createNewFile();
inputStream = this.getAssets().open(fileName);
outputStream = new FileOutputStream(file);
byte[] buffer = new byte[1024];
int len;
while ((len = inputStream.read(buffer)) != -1) {
outputStream.write(buffer, 0, len);
}
outputStream.flush();
outputStream.close();
inputStream.close();
result = true;
} catch (IOException e) {
e.printStackTrace();
}
}
return result;
}