首页 文章

Android - 获取DocumentFile,对sd卡上的任何文件路径具有写访问权限(已获得sd卡权限)

提问于
浏览
5

在我的应用程序中,我使用以下意图获得SD卡写入权限 . 如果用户从系统文件资源管理器中选择sd卡文件夹,那么我有SD卡写访问权限 .

Intent intent = new Intent(Intent.ACTION_OPEN_DOCUMENT_TREE);
intent.putExtra("android.content.extra.SHOW_ADVANCED", true);
startActivityForResult(intent, 42);

之后,我可以使用DocumentFile类修改SD卡中的文件 . 但我在获取随机文件路径的DocumentFile时遇到问题 .

Document.fromFile(new File(path));
Document.fromSingleUri(Uri.fromFile(new File(path)));

两者都返回一个DocumentFile对象,该对象在.canWrite()上返回false . 即使我已经获得SD卡许可 .

所以我编写了在我的问题末尾发布的方法,以获得一个在.canWrite()上返回true的DocumentFile . 但这很慢......而且感觉非常错误!必须有更好的方法来做到这一点 . 我还写了一个返回相同字符串的方法

String docFileUriString = docFile.getUri().toString();

对于任何文件,其中docFile是由下面的方法返回的DocumentFile . 但

DocumentFile.fromTreeUri(Uri.parse(docFileUriString ));

返回一个DocumentFile,它指向sd卡的根,而不是DocumentFile路径 . 这很奇怪 . 有人可以提出更优雅的解决方案吗?

public static DocumentFile getDocumentFileIfAllowedToWrite(File file, Context con){ 

    List<UriPermission> permissionUris = con.getContentResolver().getPersistedUriPermissions();

    for(UriPermission permissionUri:permissionUris){

        Uri treeUri = permissionUri.getUri();
        DocumentFile rootDocFile = DocumentFile.fromTreeUri(con, treeUri);
        String rootDocFilePath = FileUtil.getFullPathFromTreeUri(treeUri, con);

        if(file.getAbsolutePath().startsWith(rootDocFilePath)){

            ArrayList<String> pathInRootDocParts = new ArrayList<String>();
            while(!rootDocFilePath.equals(file.getAbsolutePath())){
                pathInRootDocParts.add(file.getName());
                file = file.getParentFile();
            } 

            DocumentFile docFile = null;  

            if(pathInRootDocParts.size()==0){ 
                docFile = DocumentFile.fromTreeUri(con, rootDocFile.getUri()); 
            }
            else{
                for(int i=pathInRootDocParts.size()-1;i>=0;i--){
                    if(docFile==null){docFile = rootDocFile.findFile(pathInRootDocParts.get(i));}
                    else{docFile = docFile.findFile(pathInRootDocParts.get(i)); }  
                }
            }
            if(docFile!=null && docFile.canWrite()){ 
                return docFile; 
            }else{
                return null;
            }

        }
    }
    return null; 
}

1 回答

  • 0

    回应@AndiMar(3月21日),我只是检查它是否存在于内部存储器上,如果它不需要担心 .

    try {
            if (sourcefile.toString().contains(Environment.getExternalStorageDirectory().toString())) {
                if (sourcefile.exists()) {
                    sourcefile.delete();
                }
            } else {
                FileUtilities fio = new FileUtilities();
                DocumentFile filetodelete = fio.getDocumentFileIfAllowedToWrite(sourcefile, context);
                if (filetodelete.exists()) {
                    filetodelete.delete();
                }
            }
    
        } catch (Exception e) {
            e.printStackTrace();
    
        }
    

相关问题