使用SAF(存储访问框架)的Android SD卡写权限

Ank*_*ria 19 android android-sdcard storage-access-framework android-5.0-lollipop documentfile

关于如何在SD卡(android 5及以上版本)中编写(和重命名)文件的大量调查结果后,我认为android提供的新SAF需要获得用户写入SD卡文件的许可.

我在这个文件管理器应用程序ES文件资源管理器中看到,最初它采用以下方式读取和写入权限,如图片所示.

在此输入图像描述

图2

选择SD卡后,授予写入权限.

因此我尝试使用SAF的方式相同,但重命名文件失败了.我的代码:

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);

    rename = (Button) findViewById(R.id.rename);

    startActivityForResult(new Intent(Intent.ACTION_OPEN_DOCUMENT_TREE), 42);
}

@Override
public void onActivityResult(int requestCode,int resultCode,Intent resultData) {
    if (resultCode != RESULT_OK)
        return;
    Uri treeUri = resultData.getData();
    DocumentFile pickedDir = DocumentFile.fromTreeUri(this, treeUri);
    grantUriPermission(getPackageName(), treeUri, Intent.FLAG_GRANT_READ_URI_PERMISSION | Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
    getContentResolver().takePersistableUriPermission(treeUri, Intent.FLAG_GRANT_READ_URI_PERMISSION | Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
}

public void renameclick(View v) {
    File ff = new File("/storage/sdcard1/try1.jpg");
    try {
        ff.createNewFile();
    } catch (Exception e) {
        Log.d("error", "creating");
        e.printStackTrace();
    }
}
Run Code Online (Sandbox Code Playgroud)

在运行代码之后,我仍然拒绝EAacces权限.

bwt*_*bwt 22

让用户选择"SD卡"甚至"内部存储"SAF根目录,使您的应用程序可以访问相应的存储,但只能通过SAF API,而不能直接通过文件系统.例如,您可以将代码翻译成以下内容:

public void writeFile(DocumentFile pickedDir) {
    try {
        DocumentFile file = pickedDir.createFile("image/jpeg", "try2.jpg");
        OutputStream out = getContentResolver().openOutputStream(file.getUri());
        try {

            // write the image content

        } finally {
            out.close();
        }

    } catch (IOException e) {
        throw new RuntimeException("Something went wrong : " + e.getMessage(), e);
    }
}
Run Code Online (Sandbox Code Playgroud)

在最新版本的Android中,使用应用程序外部的数据java.io.File几乎完全被弃用.

  • 获得树URI后,您可以使用它包含的文件和目录执行任何操作.您不需要每次询问用户1)您使用`takePersistableUriPermission()`和2)您将URI存储在某处,以便您可以在应用程序启动时检索它 (3认同)
  • @Eftekhari,您可以执行以下操作:`DocumentFile pickTree = DocumentFile.fromFile(App.getContext(),uriTree); 对于(DocumentFile文件:pickedTree.listFiles()){如果(file.isDirectory())file.createFile(mimeType,fileName); }` (2认同)