@@ -480,30 +480,44 @@ object StorageUtils {
480480 // returns null if directory does not exist and could not be created
481481 fun createDirectoryDocIfAbsent (context : Context , dirPath : String ): DocumentFileCompat ? {
482482 try {
483- val cleanDirPath = ensureTrailingSeparator(dirPath)
484- return if (requireAccessPermission(context, cleanDirPath )) {
485- val grantedDir = getGrantedDirForPath(context, cleanDirPath ) ? : return null
483+ val targetDirPath = ensureTrailingSeparator(dirPath)
484+ return if (requireAccessPermission(context, targetDirPath )) {
485+ val grantedDir = getGrantedDirForPath(context, targetDirPath ) ? : return null
486486 val rootTreeDocumentUri = convertDirPathToTreeDocumentUri(context, grantedDir) ? : return null
487487 var parentFile: DocumentFileCompat ? = DocumentFileCompat .fromTreeUri(context, rootTreeDocumentUri) ? : return null
488- val pathIterator = getPathStepIterator(context, cleanDirPath, grantedDir)
488+ val pathIterator = getPathStepIterator(context, targetDirPath, grantedDir)
489+ var currentDirPath = ensureTrailingSeparator(grantedDir)
489490 while (pathIterator?.hasNext() == true ) {
490491 val dirName = pathIterator.next()
491- var dirFile = findDocumentFileIgnoreCase(parentFile, dirName)
492- if (dirFile == null || ! dirFile.exists()) {
493- dirFile = parentFile?.createDirectory(dirName)
494- if (dirFile == null ) {
492+ var treeDocFile = findDocumentFileIgnoreCase(parentFile, dirName)
493+ currentDirPath = ensureTrailingSeparator(currentDirPath + dirName)
494+
495+ if (treeDocFile == null && File (currentDirPath).exists()) {
496+ // `DocumentsProvider` may be temporarily buggy and fail to list children directories.
497+ // Better to fail fast and revoke directory access, so that the user is aware
498+ // of the issue when trying again with `ACTION_OPEN_DOCUMENT_TREE`.
499+ // Otherwise, we would try to recreate the existing (but unlisted) directory,
500+ // and the document provider will create a new one with a "(1)" suffix.
501+ Log .e(LOG_TAG , " failed to get document file for existing path=$currentDirPath from granted dir=$grantedDir . Revoking granted dir..." )
502+ PermissionManager .revokeDirectoryAccess(context, grantedDir)
503+ throw Exception (" failed to get document file for existing path=$currentDirPath from grantedDir=$grantedDir " )
504+ }
505+
506+ if (treeDocFile == null || ! treeDocFile.exists()) {
507+ treeDocFile = parentFile?.createDirectory(dirName)
508+ if (treeDocFile == null ) {
495509 Log .e(LOG_TAG , " failed to create directory with name=$dirName from parent=$parentFile " )
496510 return null
497511 }
498512 }
499- parentFile = dirFile
513+ parentFile = treeDocFile
500514 }
501515 parentFile
502516 } else {
503- val directory = File (cleanDirPath )
517+ val directory = File (targetDirPath )
504518 directory.mkdirs()
505519 if (! directory.exists()) {
506- Log .e(LOG_TAG , " failed to create directories at path=$cleanDirPath " )
520+ Log .e(LOG_TAG , " failed to create directories at path=$targetDirPath " )
507521 return null
508522 }
509523 DocumentFileCompat .fromFile(directory)
0 commit comments