В моем приложении я получаю разрешение на запись SD-карты, используя следующее намерение. Если пользователь выбирает папку SD-карты из системного файлового проводника, тогда у меня есть доступ на запись SD-карты.
Intent intent = new Intent(Intent.ACTION_OPEN_DOCUMENT_TREE);
intent.putExtra("android.content.extra.SHOW_ADVANCED", true);
startActivityForResult(intent, 42);
После этого я могу изменять файлы на SD-карте с помощью класса DocumentFile. Но у меня проблема с получением DocumentFile для случайного пути к файлу.
Document.fromFile(new File(path));
Document.fromSingleUri(Uri.fromFile(new File(path)));
оба возвращают объект DocumentFile, который возвращает false в .canWrite (). Хотя у меня уже есть разрешение на SD-карту.
Поэтому я написал метод, опубликованный в конце моего вопроса, чтобы получить DocumentFile, который возвращает true в .canWrite (). Но это медленно ... И тоже очень неправильно! Должен быть способ сделать это лучше. Я также написал метод, который возвращает ту же строку, что и
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;
}