android 6.0无法写入外部SD卡
无法在Android v6.0.1中将文件写入外部SDCard。 测试上的设备:红米手机注3android 6.0无法写入外部SD卡
我使用已经有写权限:
@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);
}
这里是我下面的复制方法,它运行正常,但我没有发现目标字典目标文件。谁遇到过这个问题?帮助我PLZ。
@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;
}
find()
方法是错误的。在我做split
操作之前,我应该删除外部SD卡路径。或者它会两次添加外部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;
}
看一看getExternalFilesDirs()
。它会告诉你两个你可以写文件的路径。第二个是可移动的微型SD卡。
应用程序只能写入卡上应用程序特定的目录。
谷歌允许它。但是现在你必须看看你的制造商是否实现了它。
这种限制的有趣之处在于,您不需要这些目录的通常写入和读取权限。
但我需要写入文件2外部sdcard,我已经测试过'file.mkdir'不能在外部路径上通过'getExternalFilesDirs()'成功创建字典。 –
那么你现在知道制造商正在限制这一点。你确定你用过... FilesDirs()?而不是... FilesDir()?你有两条路吗?你只谈论一条路径。 – greenapps
是的,但这是我的PM的请求:-)我必须这样做,所以我发现'DocumentFile'并使用这种方式可以确实写入。 (如果我是boss = =,我会切断这个功能。) –
如果你的'find'方法是不工作的,你应该在你的问题中包含该方法。 – ianhanniballake
@ianhanniballake也许你没有看到它的兄弟,向下滚动代码区域,你会看到'find()'方法发布:-) –
检查你的应用程序信息 - > Permission for double sure if you have it or not。 –