gpt4 book ai didi

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

转载 作者:塔克拉玛干 更新时间:2023-11-02 21:42:44 30 4
gpt4 key购买 nike

在我的应用程序中,我使用以下 Intent 获得了 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;
}

最佳答案

Document.fromFile(File) 在最近的设备上似乎无法正常用于此目的

这是答案的链接我得到了关于这个问题的最多信息 https://stackoverflow.com/a/26765884/971355

关键步骤是:

  1. 获取对 SD 卡的写入权限并使其在手机重启后持久存在

    public void onActivityResult(int requestCode, int resultCode, Intent resultData) {

    ...

    getContentResolver().takePersistableUriPermission(treeUri, Intent .FLAG_GRANT_READ_URI_PERMISSION |Intent.FLAG_GRANT_WRITE_URI_PERMISSION);

  2. 之后,无论文件和文件夹的嵌套深度如何,您都可以访问它们,但您必须了解必须处理的复杂 URL。

如果您像我一样是 Linux 用户,并且曾经认为一切都是文件,一切都很简单。这次不是。SD 卡上的文件,比如 /storage/13E5-2604/testDir/test.txt其中 13E5-2604 是您的 SD 卡根文件夹:

content://com.android.externalstorage.documents/tree/13E5-2604%3A/document/13E5-2604%3A%2FtestDir%2Ftest.txt

新现实中。为什么他们做得如此复杂 - 是另一个问题...

我不知道有什么 API 方法可以透明且轻松地将普通 linux 路径转换为这个新现实路径。但是在你完成之后(%3A 是 : 而 %2F 是/请参阅 https://www.w3schools.com/tags/ref_urlencode.ASP 以供引用)你可以创建 DocumentFile 轻松:

DocumentFile txtFile = DocumentFile.fromSingleUri(context,
Uri.parse("content://com.android.externalstorage.documents/tree/13E5-2604%3A/document/13E5-2604%3A%2FtestDir%2Ftest.txt"));

并写入它。

关于Android - 获取对 SD 卡上任何文件路径具有写入权限的 DocumentFile(已获得 SD 卡权限),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/36242311/

30 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com