Merge pull request #1385 from KryptKode/feat/manage_media
handle manage media permission
This commit is contained in:
commit
ed2ed80400
4 changed files with 276 additions and 227 deletions
|
@ -56,12 +56,14 @@ abstract class BaseSimpleActivity : AppCompatActivity() {
|
|||
private val DELETE_FILE_SDK_30_HANDLER = 300
|
||||
private val RECOVERABLE_SECURITY_HANDLER = 301
|
||||
private val UPDATE_FILE_SDK_30_HANDLER = 302
|
||||
private val MANAGE_MEDIA_RC = 303
|
||||
|
||||
companion object {
|
||||
var funAfterSAFPermission: ((success: Boolean) -> Unit)? = null
|
||||
var funAfterSdk30Action: ((success: Boolean) -> Unit)? = null
|
||||
var funAfterUpdate30File: ((success: Boolean) -> Unit)? = null
|
||||
var funRecoverableSecurity: ((success: Boolean) -> Unit)? = null
|
||||
var funAfterManageMediaPermission: (() -> Unit)? = null
|
||||
}
|
||||
|
||||
abstract fun getAppIconIDs(): ArrayList<Int>
|
||||
|
@ -393,6 +395,8 @@ abstract class BaseSimpleActivity : AppCompatActivity() {
|
|||
funRecoverableSecurity = null
|
||||
} else if (requestCode == UPDATE_FILE_SDK_30_HANDLER) {
|
||||
funAfterUpdate30File?.invoke(resultCode == Activity.RESULT_OK)
|
||||
} else if (requestCode == MANAGE_MEDIA_RC) {
|
||||
funAfterManageMediaPermission?.invoke()
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -608,6 +612,15 @@ abstract class BaseSimpleActivity : AppCompatActivity() {
|
|||
}
|
||||
}
|
||||
|
||||
@RequiresApi(Build.VERSION_CODES.S)
|
||||
fun launchMediaManagementIntent(callback: () -> Unit) {
|
||||
Intent(Settings.ACTION_REQUEST_MANAGE_MEDIA).apply {
|
||||
data = Uri.parse("package:$packageName")
|
||||
startActivityForResult(this, MANAGE_MEDIA_RC)
|
||||
}
|
||||
funAfterManageMediaPermission = callback
|
||||
}
|
||||
|
||||
fun copyMoveFilesTo(
|
||||
fileDirItems: ArrayList<FileDirItem>, source: String, destination: String, isCopyOperation: Boolean, copyPhotoVideoOnly: Boolean,
|
||||
copyHidden: Boolean, callback: (destinationPath: String) -> Unit
|
||||
|
|
|
@ -894,22 +894,26 @@ fun BaseSimpleActivity.renameFile(
|
|||
}
|
||||
}
|
||||
} else if (isAccessibleWithSAFSdk30(oldPath)) {
|
||||
handleSAFDialogSdk30(oldPath) {
|
||||
if (!it) {
|
||||
return@handleSAFDialogSdk30
|
||||
}
|
||||
|
||||
try {
|
||||
ensureBackgroundThread {
|
||||
val success = renameDocumentSdk30(oldPath, newPath)
|
||||
runOnUiThread {
|
||||
callback?.invoke(success, Android30RenameFormat.NONE)
|
||||
}
|
||||
if (canManageMedia()) {
|
||||
renameCasually(oldPath, newPath, isRenamingMultipleFiles, callback)
|
||||
} else {
|
||||
handleSAFDialogSdk30(oldPath) {
|
||||
if (!it) {
|
||||
return@handleSAFDialogSdk30
|
||||
}
|
||||
} catch (e: Exception) {
|
||||
showErrorToast(e)
|
||||
runOnUiThread {
|
||||
callback?.invoke(false, Android30RenameFormat.NONE)
|
||||
|
||||
try {
|
||||
ensureBackgroundThread {
|
||||
val success = renameDocumentSdk30(oldPath, newPath)
|
||||
runOnUiThread {
|
||||
callback?.invoke(success, Android30RenameFormat.NONE)
|
||||
}
|
||||
}
|
||||
} catch (e: Exception) {
|
||||
showErrorToast(e)
|
||||
runOnUiThread {
|
||||
callback?.invoke(false, Android30RenameFormat.NONE)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -957,147 +961,154 @@ fun BaseSimpleActivity.renameFile(
|
|||
}
|
||||
}
|
||||
}
|
||||
} else {
|
||||
val oldFile = File(oldPath)
|
||||
val newFile = File(newPath)
|
||||
val tempFile = try {
|
||||
createTempFile(oldFile) ?: return
|
||||
} catch (exception: Exception) {
|
||||
if (isRPlus() && exception is java.nio.file.FileSystemException) {
|
||||
// if we are renaming multiple files at once, we should give the Android 30+ permission dialog all uris together, not one by one
|
||||
if (isRenamingMultipleFiles) {
|
||||
callback?.invoke(false, Android30RenameFormat.CONTENT_RESOLVER)
|
||||
} else {
|
||||
val fileUris = getFileUrisFromFileDirItems(arrayListOf(File(oldPath).toFileDirItem(this))).second
|
||||
updateSDK30Uris(fileUris) { success ->
|
||||
if (success) {
|
||||
val values = ContentValues().apply {
|
||||
put(MediaStore.Images.Media.DISPLAY_NAME, newPath.getFilenameFromPath())
|
||||
}
|
||||
} else renameCasually(oldPath, newPath, isRenamingMultipleFiles, callback)
|
||||
}
|
||||
|
||||
try {
|
||||
contentResolver.update(fileUris.first(), values, null, null)
|
||||
callback?.invoke(true, Android30RenameFormat.NONE)
|
||||
} catch (e: Exception) {
|
||||
showErrorToast(e)
|
||||
callback?.invoke(false, Android30RenameFormat.NONE)
|
||||
}
|
||||
} else {
|
||||
callback?.invoke(false, Android30RenameFormat.NONE)
|
||||
}
|
||||
}
|
||||
}
|
||||
private fun BaseSimpleActivity.renameCasually(
|
||||
oldPath: String,
|
||||
newPath: String,
|
||||
isRenamingMultipleFiles: Boolean,
|
||||
callback: ((success: Boolean, android30RenameFormat: Android30RenameFormat) -> Unit)?
|
||||
) {
|
||||
val oldFile = File(oldPath)
|
||||
val newFile = File(newPath)
|
||||
val tempFile = try {
|
||||
createTempFile(oldFile) ?: return
|
||||
} catch (exception: Exception) {
|
||||
if (isRPlus() && exception is FileSystemException) {
|
||||
// if we are renaming multiple files at once, we should give the Android 30+ permission dialog all uris together, not one by one
|
||||
if (isRenamingMultipleFiles) {
|
||||
callback?.invoke(false, Android30RenameFormat.CONTENT_RESOLVER)
|
||||
} else {
|
||||
showErrorToast(exception)
|
||||
callback?.invoke(false, Android30RenameFormat.NONE)
|
||||
}
|
||||
return
|
||||
}
|
||||
val fileUris = getFileUrisFromFileDirItems(arrayListOf(File(oldPath).toFileDirItem(this))).second
|
||||
updateSDK30Uris(fileUris) { success ->
|
||||
if (success) {
|
||||
val values = ContentValues().apply {
|
||||
put(MediaStore.Images.Media.DISPLAY_NAME, newPath.getFilenameFromPath())
|
||||
}
|
||||
|
||||
val oldToTempSucceeds = oldFile.renameTo(tempFile)
|
||||
val tempToNewSucceeds = tempFile.renameTo(newFile)
|
||||
if (oldToTempSucceeds && tempToNewSucceeds) {
|
||||
if (newFile.isDirectory) {
|
||||
updateInMediaStore(oldPath, newPath)
|
||||
rescanPath(newPath) {
|
||||
runOnUiThread {
|
||||
callback?.invoke(true, Android30RenameFormat.NONE)
|
||||
}
|
||||
if (!oldPath.equals(newPath, true)) {
|
||||
deleteFromMediaStore(oldPath)
|
||||
}
|
||||
scanPathRecursively(newPath)
|
||||
}
|
||||
} else {
|
||||
if (!baseConfig.keepLastModified) {
|
||||
newFile.setLastModified(System.currentTimeMillis())
|
||||
}
|
||||
updateInMediaStore(oldPath, newPath)
|
||||
scanPathsRecursively(arrayListOf(newPath)) {
|
||||
if (!oldPath.equals(newPath, true)) {
|
||||
deleteFromMediaStore(oldPath)
|
||||
}
|
||||
runOnUiThread {
|
||||
callback?.invoke(true, Android30RenameFormat.NONE)
|
||||
}
|
||||
}
|
||||
}
|
||||
} else {
|
||||
tempFile.delete()
|
||||
newFile.delete()
|
||||
if (isRPlus()) {
|
||||
// if we are renaming multiple files at once, we should give the Android 30+ permission dialog all uris together, not one by one
|
||||
if (isRenamingMultipleFiles) {
|
||||
callback?.invoke(false, Android30RenameFormat.SAF)
|
||||
} else {
|
||||
val fileUris = getFileUrisFromFileDirItems(arrayListOf(File(oldPath).toFileDirItem(this))).second
|
||||
updateSDK30Uris(fileUris) { success ->
|
||||
if (!success) {
|
||||
return@updateSDK30Uris
|
||||
}
|
||||
try {
|
||||
val sourceUri = fileUris.first()
|
||||
val sourceFile = File(oldPath).toFileDirItem(this)
|
||||
|
||||
if (oldPath.equals(newPath, true)) {
|
||||
val tempDestination = try {
|
||||
createTempFile(File(sourceFile.path)) ?: return@updateSDK30Uris
|
||||
} catch (exception: Exception) {
|
||||
callback?.invoke(false, Android30RenameFormat.NONE)
|
||||
return@updateSDK30Uris
|
||||
}
|
||||
|
||||
val copyTempSuccess = copySingleFileSdk30(sourceFile, tempDestination.toFileDirItem(this))
|
||||
if (copyTempSuccess) {
|
||||
contentResolver.delete(sourceUri, null)
|
||||
tempDestination.renameTo(File(newPath))
|
||||
if (!baseConfig.keepLastModified) {
|
||||
newFile.setLastModified(System.currentTimeMillis())
|
||||
}
|
||||
updateInMediaStore(oldPath, newPath)
|
||||
scanPathsRecursively(arrayListOf(newPath)) {
|
||||
runOnUiThread {
|
||||
callback?.invoke(true, Android30RenameFormat.NONE)
|
||||
}
|
||||
}
|
||||
} else {
|
||||
callback?.invoke(false, Android30RenameFormat.NONE)
|
||||
}
|
||||
} else {
|
||||
val destinationFile = FileDirItem(
|
||||
newPath,
|
||||
newPath.getFilenameFromPath(),
|
||||
sourceFile.isDirectory,
|
||||
sourceFile.children,
|
||||
sourceFile.size,
|
||||
sourceFile.modified
|
||||
)
|
||||
val copySuccessful = copySingleFileSdk30(sourceFile, destinationFile)
|
||||
if (copySuccessful) {
|
||||
if (!baseConfig.keepLastModified) {
|
||||
newFile.setLastModified(System.currentTimeMillis())
|
||||
}
|
||||
contentResolver.delete(sourceUri, null)
|
||||
updateInMediaStore(oldPath, newPath)
|
||||
scanPathsRecursively(arrayListOf(newPath)) {
|
||||
runOnUiThread {
|
||||
callback?.invoke(true, Android30RenameFormat.NONE)
|
||||
}
|
||||
}
|
||||
} else {
|
||||
callback?.invoke(false, Android30RenameFormat.NONE)
|
||||
}
|
||||
}
|
||||
|
||||
contentResolver.update(fileUris.first(), values, null, null)
|
||||
callback?.invoke(true, Android30RenameFormat.NONE)
|
||||
} catch (e: Exception) {
|
||||
showErrorToast(e)
|
||||
callback?.invoke(false, Android30RenameFormat.NONE)
|
||||
}
|
||||
} else {
|
||||
callback?.invoke(false, Android30RenameFormat.NONE)
|
||||
}
|
||||
}
|
||||
} else {
|
||||
callback?.invoke(false, Android30RenameFormat.NONE)
|
||||
}
|
||||
} else {
|
||||
showErrorToast(exception)
|
||||
callback?.invoke(false, Android30RenameFormat.NONE)
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
val oldToTempSucceeds = oldFile.renameTo(tempFile)
|
||||
val tempToNewSucceeds = tempFile.renameTo(newFile)
|
||||
if (oldToTempSucceeds && tempToNewSucceeds) {
|
||||
if (newFile.isDirectory) {
|
||||
updateInMediaStore(oldPath, newPath)
|
||||
rescanPath(newPath) {
|
||||
runOnUiThread {
|
||||
callback?.invoke(true, Android30RenameFormat.NONE)
|
||||
}
|
||||
if (!oldPath.equals(newPath, true)) {
|
||||
deleteFromMediaStore(oldPath)
|
||||
}
|
||||
scanPathRecursively(newPath)
|
||||
}
|
||||
} else {
|
||||
if (!baseConfig.keepLastModified) {
|
||||
newFile.setLastModified(System.currentTimeMillis())
|
||||
}
|
||||
updateInMediaStore(oldPath, newPath)
|
||||
scanPathsRecursively(arrayListOf(newPath)) {
|
||||
if (!oldPath.equals(newPath, true)) {
|
||||
deleteFromMediaStore(oldPath)
|
||||
}
|
||||
runOnUiThread {
|
||||
callback?.invoke(true, Android30RenameFormat.NONE)
|
||||
}
|
||||
}
|
||||
}
|
||||
} else {
|
||||
tempFile.delete()
|
||||
newFile.delete()
|
||||
if (isRPlus()) {
|
||||
// if we are renaming multiple files at once, we should give the Android 30+ permission dialog all uris together, not one by one
|
||||
if (isRenamingMultipleFiles) {
|
||||
callback?.invoke(false, Android30RenameFormat.SAF)
|
||||
} else {
|
||||
val fileUris = getFileUrisFromFileDirItems(arrayListOf(File(oldPath).toFileDirItem(this))).second
|
||||
updateSDK30Uris(fileUris) { success ->
|
||||
if (!success) {
|
||||
return@updateSDK30Uris
|
||||
}
|
||||
try {
|
||||
val sourceUri = fileUris.first()
|
||||
val sourceFile = File(oldPath).toFileDirItem(this)
|
||||
|
||||
if (oldPath.equals(newPath, true)) {
|
||||
val tempDestination = try {
|
||||
createTempFile(File(sourceFile.path)) ?: return@updateSDK30Uris
|
||||
} catch (exception: Exception) {
|
||||
callback?.invoke(false, Android30RenameFormat.NONE)
|
||||
return@updateSDK30Uris
|
||||
}
|
||||
|
||||
val copyTempSuccess = copySingleFileSdk30(sourceFile, tempDestination.toFileDirItem(this))
|
||||
if (copyTempSuccess) {
|
||||
contentResolver.delete(sourceUri, null)
|
||||
tempDestination.renameTo(File(newPath))
|
||||
if (!baseConfig.keepLastModified) {
|
||||
newFile.setLastModified(System.currentTimeMillis())
|
||||
}
|
||||
updateInMediaStore(oldPath, newPath)
|
||||
scanPathsRecursively(arrayListOf(newPath)) {
|
||||
runOnUiThread {
|
||||
callback?.invoke(true, Android30RenameFormat.NONE)
|
||||
}
|
||||
}
|
||||
} else {
|
||||
callback?.invoke(false, Android30RenameFormat.NONE)
|
||||
}
|
||||
} else {
|
||||
val destinationFile = FileDirItem(
|
||||
newPath,
|
||||
newPath.getFilenameFromPath(),
|
||||
sourceFile.isDirectory,
|
||||
sourceFile.children,
|
||||
sourceFile.size,
|
||||
sourceFile.modified
|
||||
)
|
||||
val copySuccessful = copySingleFileSdk30(sourceFile, destinationFile)
|
||||
if (copySuccessful) {
|
||||
if (!baseConfig.keepLastModified) {
|
||||
newFile.setLastModified(System.currentTimeMillis())
|
||||
}
|
||||
contentResolver.delete(sourceUri, null)
|
||||
updateInMediaStore(oldPath, newPath)
|
||||
scanPathsRecursively(arrayListOf(newPath)) {
|
||||
runOnUiThread {
|
||||
callback?.invoke(true, Android30RenameFormat.NONE)
|
||||
}
|
||||
}
|
||||
} else {
|
||||
callback?.invoke(false, Android30RenameFormat.NONE)
|
||||
}
|
||||
}
|
||||
|
||||
} catch (e: Exception) {
|
||||
showErrorToast(e)
|
||||
callback?.invoke(false, Android30RenameFormat.NONE)
|
||||
}
|
||||
}
|
||||
}
|
||||
} else {
|
||||
callback?.invoke(false, Android30RenameFormat.NONE)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -65,47 +65,59 @@ class RenamePatternTab(context: Context, attrs: AttributeSet) : RelativeLayout(c
|
|||
return@handleSAFDialog
|
||||
}
|
||||
|
||||
activity?.handleSAFDialogSdk30(firstPath) {
|
||||
if (!it) {
|
||||
return@handleSAFDialogSdk30
|
||||
}
|
||||
|
||||
ignoreClicks = true
|
||||
var pathsCnt = validPaths.size
|
||||
numbersCnt = pathsCnt.toString().length
|
||||
for (path in validPaths) {
|
||||
if (stopLooping) {
|
||||
if (activity?.canManageMedia() == true) {
|
||||
renameFiles(validPaths, useMediaFileExtension, callback)
|
||||
} else {
|
||||
activity?.handleSAFDialogSdk30(firstPath) { granted ->
|
||||
if (!granted) {
|
||||
return@handleSAFDialogSdk30
|
||||
}
|
||||
|
||||
try {
|
||||
val newPath = getNewPath(path, useMediaFileExtension) ?: continue
|
||||
activity?.renameFile(path, newPath, true) { success, android30Format ->
|
||||
if (success) {
|
||||
pathsCnt--
|
||||
if (pathsCnt == 0) {
|
||||
callback(true)
|
||||
}
|
||||
} else {
|
||||
ignoreClicks = false
|
||||
if (android30Format != Android30RenameFormat.NONE) {
|
||||
currentIncrementalNumber = 1
|
||||
stopLooping = true
|
||||
renameAllFiles(validPaths, useMediaFileExtension, android30Format, callback)
|
||||
} else {
|
||||
activity?.toast(R.string.unknown_error_occurred)
|
||||
}
|
||||
}
|
||||
}
|
||||
} catch (e: Exception) {
|
||||
activity?.showErrorToast(e)
|
||||
}
|
||||
renameFiles(validPaths, useMediaFileExtension, callback)
|
||||
}
|
||||
stopLooping = false
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private fun renameFiles(
|
||||
validPaths: List<String>,
|
||||
useMediaFileExtension: Boolean,
|
||||
callback: (success: Boolean) -> Unit
|
||||
) {
|
||||
ignoreClicks = true
|
||||
var pathsCnt = validPaths.size
|
||||
numbersCnt = pathsCnt.toString().length
|
||||
for (path in validPaths) {
|
||||
if (stopLooping) {
|
||||
return
|
||||
}
|
||||
|
||||
try {
|
||||
val newPath = getNewPath(path, useMediaFileExtension) ?: continue
|
||||
activity?.renameFile(path, newPath, true) { success, android30Format ->
|
||||
if (success) {
|
||||
pathsCnt--
|
||||
if (pathsCnt == 0) {
|
||||
callback(true)
|
||||
}
|
||||
} else {
|
||||
ignoreClicks = false
|
||||
if (android30Format != Android30RenameFormat.NONE) {
|
||||
currentIncrementalNumber = 1
|
||||
stopLooping = true
|
||||
renameAllFiles(validPaths, useMediaFileExtension, android30Format, callback)
|
||||
} else {
|
||||
activity?.toast(R.string.unknown_error_occurred)
|
||||
}
|
||||
}
|
||||
}
|
||||
} catch (e: Exception) {
|
||||
activity?.showErrorToast(e)
|
||||
}
|
||||
}
|
||||
stopLooping = false
|
||||
}
|
||||
|
||||
private fun getNewPath(path: String, useMediaFileExtension: Boolean): String? {
|
||||
try {
|
||||
val exif = ExifInterface(path)
|
||||
|
|
|
@ -58,67 +58,80 @@ class RenameSimpleTab(context: Context, attrs: AttributeSet) : RelativeLayout(co
|
|||
return@handleSAFDialog
|
||||
}
|
||||
|
||||
activity?.handleSAFDialogSdk30(firstPath) {
|
||||
if (!it) {
|
||||
return@handleSAFDialogSdk30
|
||||
}
|
||||
|
||||
ignoreClicks = true
|
||||
var pathsCnt = validPaths.size
|
||||
for (path in validPaths) {
|
||||
if (stopLooping) {
|
||||
if (activity?.canManageMedia() == true) {
|
||||
renameFiles(validPaths, append, valueToAdd, callback)
|
||||
} else {
|
||||
activity?.handleSAFDialogSdk30(firstPath) { granted ->
|
||||
if (!granted) {
|
||||
return@handleSAFDialogSdk30
|
||||
}
|
||||
|
||||
val fullName = path.getFilenameFromPath()
|
||||
var dotAt = fullName.lastIndexOf(".")
|
||||
if (dotAt == -1) {
|
||||
dotAt = fullName.length
|
||||
}
|
||||
|
||||
val name = fullName.substring(0, dotAt)
|
||||
val extension = if (fullName.contains(".")) ".${fullName.getFilenameExtension()}" else ""
|
||||
|
||||
val newName = if (append) {
|
||||
"$name$valueToAdd$extension"
|
||||
} else {
|
||||
"$valueToAdd$fullName"
|
||||
}
|
||||
|
||||
val newPath = "${path.getParentPath()}/$newName"
|
||||
|
||||
if (activity?.getDoesFilePathExist(newPath) == true) {
|
||||
continue
|
||||
}
|
||||
|
||||
activity?.renameFile(path, newPath, true) { success, android30Format ->
|
||||
if (success) {
|
||||
pathsCnt--
|
||||
if (pathsCnt == 0) {
|
||||
callback(true)
|
||||
}
|
||||
} else {
|
||||
ignoreClicks = false
|
||||
if (android30Format != Android30RenameFormat.NONE) {
|
||||
stopLooping = true
|
||||
renameAllFiles(validPaths, append, valueToAdd, android30Format, callback)
|
||||
} else {
|
||||
activity?.toast(R.string.unknown_error_occurred)
|
||||
}
|
||||
}
|
||||
}
|
||||
renameFiles(validPaths, append, valueToAdd, callback)
|
||||
}
|
||||
stopLooping = false
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private fun renameAllFiles(
|
||||
private fun renameFiles(
|
||||
validPaths: List<String>,
|
||||
append: Boolean,
|
||||
valueToAdd: String,
|
||||
callback: (success: Boolean) -> Unit
|
||||
) {
|
||||
ignoreClicks = true
|
||||
var pathsCnt = validPaths.size
|
||||
for (path in validPaths) {
|
||||
if (stopLooping) {
|
||||
return
|
||||
}
|
||||
|
||||
val fullName = path.getFilenameFromPath()
|
||||
var dotAt = fullName.lastIndexOf(".")
|
||||
if (dotAt == -1) {
|
||||
dotAt = fullName.length
|
||||
}
|
||||
|
||||
val name = fullName.substring(0, dotAt)
|
||||
val extension = if (fullName.contains(".")) ".${fullName.getFilenameExtension()}" else ""
|
||||
|
||||
val newName = if (append) {
|
||||
"$name$valueToAdd$extension"
|
||||
} else {
|
||||
"$valueToAdd$fullName"
|
||||
}
|
||||
|
||||
val newPath = "${path.getParentPath()}/$newName"
|
||||
|
||||
if (activity?.getDoesFilePathExist(newPath) == true) {
|
||||
continue
|
||||
}
|
||||
|
||||
activity?.renameFile(path, newPath, true) { success, android30Format ->
|
||||
if (success) {
|
||||
pathsCnt--
|
||||
if (pathsCnt == 0) {
|
||||
callback(true)
|
||||
}
|
||||
} else {
|
||||
ignoreClicks = false
|
||||
if (android30Format != Android30RenameFormat.NONE) {
|
||||
stopLooping = true
|
||||
renameAllFilesSdk30(validPaths, append, valueToAdd, android30Format, callback)
|
||||
} else {
|
||||
activity?.toast(R.string.unknown_error_occurred)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
stopLooping = false
|
||||
}
|
||||
|
||||
private fun renameAllFilesSdk30(
|
||||
paths: List<String>,
|
||||
appendString: Boolean,
|
||||
stringToAdd: String,
|
||||
android30Format: Android30RenameFormat,
|
||||
callback: (success: Boolean) -> Unit
|
||||
callback: (success: Boolean) -> Unit,
|
||||
) {
|
||||
val fileDirItems = paths.map { File(it).toFileDirItem(context) }
|
||||
val uriPairs = context.getFileUrisFromFileDirItems(fileDirItems)
|
||||
|
|
Loading…
Reference in a new issue