在我的应用程序中,我使用以下意图获得 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 ));
返回一个指向 sd 卡根目录的 DocumentFile,而不是 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;
}