android 6.0无法编写外部sdcard

时间:2016-08-20 02:59:22

标签: android android-6.0-marshmallow android-sdcard

无法在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;
}

2 个答案:

答案 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卡。

应用只能写入卡上特定于应用的目录。

谷歌允许它。但现在你必须看看你的制造商是否实现了它。

这个限制的有趣之处在于你不需要这些目录的通常写入和读取权限。