Удаление физического файла с помощью поставщика контента Android MediaStore.Files.getContentUri(VOLUME_NAME_EXTERNAL)

#android #android-contentprovider

#Android #android-contentprovider

Вопрос:

Мое текущее приложение для Android хранит файлы PDF на внешнем хранилище с помощью

  val contentUri = MediaStore.Files.getContentUri(VOLUME_NAME_EXTERNAL)
 

Приложение создает подпапку в папке standard Documents.

Мой манифест содержит

 android:requestLegacyExternalStorage = true
 

Для Android 30 я запрашиваю следующее

 val intent = Intent(Settings.ACTION_MANAGE_APP_ALL_FILES_ACCESS_PERMISSION)
                val uri = Uri.fromParts("package", packageName, null)
                intent.data = uri
                startActivity(intent)
 

У меня есть фоновый рабочий, который пытается очистить все загруженные файлы, код, который я использую, выглядит следующим образом:-

 @RequiresApi(Build.VERSION_CODES.Q)
override suspend fun doActualFlowedWork(): Result {
    if (hasSdkHigherThan(Build.VERSION_CODES.P)) {
        clearDownloadFiles()
    } else {
        clearDownloadLegacyFiles()
    }

    return result ?: Result.success()
}

@Suppress("BlockingMethodInNonBlockingContext")
@RequiresApi(Build.VERSION_CODES.Q)
private fun clearDownloadFiles() {
    val resolver = context.contentResolver
    val relativeLocation = "${Environment.DIRECTORY_DOCUMENTS}${MY_SUB_FOLDER}"

    val contentUri = MediaStore.Files.getContentUri(VOLUME_NAME_EXTERNAL)

    resolver.query(
        contentUri,
        arrayOf(MediaStore.MediaColumns._ID, MediaStore.MediaColumns.DISPLAY_NAME, MediaStore.MediaColumns.RELATIVE_PATH),
        "${MediaStore.MediaColumns.RELATIVE_PATH}=?",
        arrayOf(relativeLocation),
        null
    ).use { cursor ->

        cursor?.let {
            while (it.moveToNext()) {

                val idIndex = cursor.getColumnIndex(MediaStore.MediaColumns._ID)
                val displayNameIndex = cursor.getColumnIndex(MediaStore.MediaColumns.DISPLAY_NAME)
                val relativePathNameIndex = cursor.getColumnIndex(MediaStore.MediaColumns.RELATIVE_PATH)

                if (cursor.getString(relativePathNameIndex) == relativeLocation) {

                    val fileContentUri = MediaStore.Files.getContentUri(VOLUME_NAME_EXTERNAL, cursor.getLong(idIndex))
                    val count = context.contentResolver.delete(fileContentUri, null, null)
                    if (count == 0) Timber.e("FAILED to clear downloaded file = ${cursor.getString(displayNameIndex)}")
                    else Timber.i("Cleared downloaded file = ${cursor.getString(displayNameIndex)}")
                }
            }
        }
    }
}

@Suppress("DEPRECATION")
private fun clearDownloadLegacyFiles() {
    val documentsFolder = File(Environment.getExternalStorageDirectory(), Environment.DIRECTORY_DOCUMENTS)
    if (!documentsFolder.exists()) return

    val mendeleyLiteSubFolder = File(Environment.getExternalStorageDirectory(), "${Environment.DIRECTORY_DOCUMENTS}$MY_SUB_FOLDER")
    if (!mendeleyLiteSubFolder.exists()) return

    val downloadFiles = mendeleyLiteSubFolder.listFiles()

    downloadFiles?.forEach { downloadFile ->
        if (downloadFile.exists()) downloadFile.delete()
        Timber.i("Clearing downloaded file = $downloadFile")
    }
}
 

Этот рабочий процесс очистки завершается нормально, и журналы показывают, что файлы были удалены,
однако, когда я использую проводник устройств Android Studio для просмотра вложенной папки с документами, физические файлы PDF все еще присутствуют.

Мои ожидания неверны?

Чего достигает этот код context.contentResolver.delete(fileContentUri, null, null) ?

Как мне удалить физические файлы из моей подпапки?

Комментарии:

1. This clear down worker completes OK Какая функция? У вас есть два.

2. @blackapps Функция, которая использует поставщика контента, например, clearDownloadFiles()

3. В этом случае вы можете вызвать обе функции.

4. Ниже Q удаления из MediaStore недостаточно. Вы также должны удалить файлы самостоятельно обычным способом.

5. В основном это работает здесь для Q . Но не тогда, когда в MediaStore есть ошибки, что, к сожалению, часто случается. Затем перезагрузите устройство.