无法在Android v6.0.1中将文件写入外部SDCard。 在设备上测试:Redmi Note3
我已经使用了以下权限:
@TargetApi(21)
public void requestDocumentPermission() {
Intent intent = new Intent(Intent.ACTION_OPEN_DOCUMENT_TREE);
startActivityForResult(intent, SDCardBrowser.REQUEST_DOCUMENTS);
}
@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
if (requestCode == REQUEST_DOCUMENTS && resultCode == RESULT_OK) { // given permission
Uri uri = data.getData();
takeUriPermission(data.getFlags(), uri);
SharedPreferences.Editor editor = PreferenceManager.getDefaultSharedPreferences(this).edit();
editor.putString(Constants.PREFS_DEFAULT_URI, uri.toString()).apply();
doCopy(selectedNodes, toNode);
}
super.onActivityResult(requestCode, resultCode, data);
}
这是我的复制方法,它运行正常,但我没有在目标字典中找到目标文件。有谁遇到过这个问题?帮帮我。
@TargetApi(23)
public static void copyFileV23(File srcFile, File destFile) {
FileInputStream in = null;
OutputStream out = null;
Context context = XXXApplication.getInstance().getApplicationContext();
ContentResolver resolver = context.getContentResolver();
String strUri = PreferenceManager.getDefaultSharedPreferences(context).getString(Constants.PREFS_DEFAULT_URI, null);
if (null == strUri) {
return;
}
DocumentFile rootDocument = DocumentFile.fromTreeUri(context, Uri.parse(strUri));
try {
in = new FileInputStream(srcFile);
DocumentFile target = find(destFile.getAbsolutePath(), rootDocument, getMimeType(srcFile));
out = resolver.openOutputStream(target.getUri());
if (null != out) {
byte[] buf = new byte[4096];
int len;
while ((len = in.read(buf)) != -1) {
out.write(buf, 0, len);
}
}
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
} finally {
try {
in.close();
out.close();
} catch (IOException ignore) {
}
}
}
private static DocumentFile find(String absolutePath, DocumentFile root, String mime) {
if (null == root || null == absolutePath) {
return null;
}
String[] paths = absolutePath.split("\\/");
for (int i = 0; i < paths.length; i++) {
if (paths[i].equals(""))
continue;
DocumentFile documentFile = root.findFile(paths[i]);
if (null == documentFile) {
if (i < paths.length - 1) {
documentFile = root.createDirectory(paths[i]);
} else {
documentFile = root.createFile(mime, paths[i]);
}
}
root = documentFile;
}
return root;
}
修改-1
找到解决方案,find()
方法不正确。它应该如下所示:
private static DocumentFile findFileInExternal(String absolutePath, DocumentFile root, String mime) {
if (null == root || null == absolutePath) {
return null;
}
String externalPath = ExternalStorage.getStoragePath(true);
if (null == externalPath) {
return null;
}
absolutePath = absolutePath.substring(externalPath.length());
String[] paths = absolutePath.split("\\/");
for (int i = 0; i < paths.length; i++) {
if (paths[i].equals(""))
continue;
DocumentFile documentFile = root.findFile(paths[i]);
if (null == documentFile) {
if (i < paths.length - 1) {
documentFile = root.createDirectory(paths[i]);
} else {
documentFile = root.createFile(mime, paths[i]);
}
}
root = documentFile;
}
return root;
}
答案 0 :(得分:0)
find()
方法错了。我应该在执行split
操作之前删除外部sdcard路径。或者它会两次添加外部SD卡路径。以下是正确的find()
方法:
private static DocumentFile find(String absolutePath, DocumentFile root, String mime) {
if (null == root || null == absolutePath) {
return null;
}
String externalPath = ExternalStorage.getStoragePath(true);
if (null == externalPath) {
return null;
}
absolutePath = absolutePath.substring(externalPath.length());
String[] paths = absolutePath.split("\\/");
for (int i = 0; i < paths.length; i++) {
if (paths[i].equals(""))
continue;
DocumentFile documentFile = root.findFile(paths[i]);
if (null == documentFile) {
if (i < paths.length - 1) {
documentFile = root.createDirectory(paths[i]);
} else {
documentFile = root.createFile(mime, paths[i]);
}
}
root = documentFile;
}
return root;
}
答案 1 :(得分:0)
看看getExternalFilesDirs()
。它会告诉你两个可以写文件的路径。第二个是可移动微型SD卡。
应用只能写入卡上特定于应用的目录。
谷歌允许它。但现在你必须看看你的制造商是否实现了它。这个限制的有趣之处在于你不需要这些目录的通常写入和读取权限。