#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 есть ошибки, что, к сожалению, часто случается. Затем перезагрузите устройство.