Как удалить файл на Android 11 (API 30) без диалогового окна подтверждения системы?

У меня есть приложение, которое записывает видео в общую папку MOVIES.

Я могу удалить эти файлы на Android 11 (API 30) с помощью метода contentResolver.delete(uri, null, null) в моей записи видео.

Но если я переустановлю приложение, оно потеряет права доступа к этим файлам ... (так что жаль), и в этом случае мне нужно сделать что-то вроде этого:

try {
    context.contentResolver.delete(uri, null, null)
} catch (exception: Exception) {
    if (exception is RecoverableSecurityException) {
        val intentSender = exception.userAction.actionIntent.intentSender
        intentSender?.let {
            callback?.startIntentSenderForResult(
                intentSender,
                requestCode
            )
        }
    }
}

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

введите описание изображения здесь

Затем я установил приложение Explorer из Google Play на это устройство Android 11 (эмулятор), когда я его открыл, приложение запрашивало только разрешение на запись в хранилище (мое приложение также делает это), и это приложение Explorer могло легко удалить любой файл (включая мои записи видео файлы) без какого-либо диалогового окна подтверждения.

Так как они это делают? Это взлом или что это?

Ссылка на приложение https://play.google.com/store/apps/details?id=com.speedsoftware.explorer.

Обновить

VLC для Android также может удалить любой медиафайл https://play.google.com/store/apps/details?id=org.videolan.vlc.

Они также используют контент-провайдера, поэтому он такой же, но возвращает true, в отличие от моего приложения, почему?

fun deleteFile(file: File): Boolean {
    var deleted: Boolean
    //Delete from Android Medialib, for consistency with device MTP storing and other apps listing content:// media
    if (file.isDirectory) {
        deleted = true
        for (child in file.listFiles()) deleted = deleted and deleteFile(child)
        if (deleted) deleted = deleted and file.delete()
    } else {
        val cr = AppContextProvider.appContext.contentResolver
        try {
            deleted = cr.delete(MediaStore.Files.getContentUri("external"),
                    MediaStore.Files.FileColumns.DATA + "=?", arrayOf(file.path)) > 0
        } catch (ignored: IllegalArgumentException) {
            deleted = false
        } catch (ignored: SecurityException) {
            deleted = false
        }
        // Can happen on some devices...
        if (file.exists()) deleted = deleted or file.delete()
    }
    return deleted
}

https://github.com/videolan/vlc-android/blob/master/application/vlc-android/src/org/videolan/vlc/util/FileUtils.kt#L240


person user25    schedule 28.10.2020    source источник
comment
Приложения, запрашивающие доступ ко всем файлам, как это делают файловые менеджеры, могут удалять все файлы с помощью стандартного класса File. Нет необходимости использовать преобразователи контента или хранилище мультимедиа. Не нужно спрашивать пользователя.   -  person blackapps    schedule 29.10.2020
comment
@blackapps, как они запрашивают такой доступ? VLC для Android также может легко удалять файлы (это не файловый менеджер)   -  person user924    schedule 29.10.2020
comment
stackoverflow.com/questions/63842070 /   -  person blackapps    schedule 29.10.2020
comment
Придет пакетное удаление для Android 11. Разве его там нет?   -  person blackapps    schedule 29.10.2020
comment
и для каждого удаления файла должен быть отдельный диалог, многократное удаление - ни в коем случае - Android 11 поддерживает пакетный запрос на доступ.   -  person CommonsWare    schedule 29.10.2020
comment
@CommonsWare в порядке, но я все равно хотел бы удалить видеофайлы без какого-либо диалога, например Мне нужно реализовать функцию записи цикла, например, в видеорегистраторе. все видео не должны занимать на устройстве более 15 ГБ, поэтому, когда приложение записывает новые видео, оно должно автоматически удалять самое старое, если все видео занимают более 15 ГБ. Я мог бы использовать Context.getExternalMediaDirs, но видео удаляются, если приложение удаляется, и возникают другие проблемы, когда разные приложения (например, видеоплееры) не могут получить доступ к этим видео (не будут сканировать). Но я вижу, что VLC может легко удалить файл на Android 11, как они это делают?   -  person user25    schedule 29.10.2020
comment
@CommonsWare они по-прежнему используют 29 SDK, поэтому он работает для них .. Интересно, если я хочу, чтобы в моем приложении для видеомагнитофона была функция циклической записи (которая требует удаления старых видеофайлов во время записи, как в устройствах Dashcam), можно ли будет использовать MANAGE_EXTERNAL_STORAGE разрешение и публикация обновления в Google Play?   -  person user25    schedule 29.10.2020
comment
можно ли использовать разрешение MANAGE_EXTERNAL_STORAGE и опубликовать обновление в Google Play? - Я не могу ответить на это. но я все равно хотел бы удалить видеофайлы без какого-либо диалога - вы уже это делаете. Ваша проблема в том, что в случае, когда пользователь удаляет ваше приложение, а затем переустанавливает его, вы не можете удалить какие-либо старые записи из своего приложения. ИМХО, вы слишком задумываетесь о необычном происшествии. Просто скажите пользователю, что вы удалили и переустановили, поэтому нам нужна ваша помощь, чтобы очистить старые записи, а затем использовать Storage Access Framework.   -  person CommonsWare    schedule 29.10.2020
comment
@CommonsWare хорошо, согласен, спасибо :)   -  person user25    schedule 29.10.2020
comment
@CommonsWare сказано, что есть ContentResolver#checkUriPermission(Uri, int, int), но я не могу найти этот метод в _2 _... developer.android.com/reference/android/provider/   -  person user25    schedule 21.11.2020
comment
@ user25: Похоже, это ошибка в документации. На Context есть checkUriPermission().   -  person CommonsWare    schedule 21.11.2020


Ответы (3)


Есть ContentResolver.applyBatch(), который, я думаю, спросит пользователя только один раз.

Взгляните сюда:

https://developer.android.com/guide/topics/providers/content-provider-basics.html#Batch

person blackapps    schedule 29.10.2020
comment
это developer.android.com/reference/android/provider/ - person user25; 21.11.2020

Android 11 (API 30) без диалогового окна подтверждения системы вы можете сделать, но вам нужно manage_external_storage разрешение. Разрешение разрешено для приложения определенной категории.

  • Файловые менеджеры
  • Резервное копирование и восстановление приложений
  • Антивирусные приложения
  • Приложения для управления документами
  • Поиск файлов на устройстве
  • Шифрование дисков и файлов
  • Перенос данных с устройства на устройство

Управление всеми файлами на устройстве хранения

Если ваше приложение не соответствует указанной выше категории, вы не разрешаете публикацию с разрешением manage_external_storage.

Если ваше приложение представляет собой галерею, видео и аудиоплеер, вам не нужно manage_external_storage разрешение, и вы можете удалить его непосредственно в диалоговом окне подтверждения системы.
Здесь вы можете получить пример удаления медиафайла

До Android 11 вы можете использовать используемый метод file.delete () и удалить свой файл.

В android 11 метод file.delete() работает только в том случае, если вы создаете собственный контент. Например, ваше приложение загружает одно изображение, и в этом file.delete() методе используется внешнее хранилище.

если вы хотите удалить мультимедийные файлы, такие как камера или снимок экрана, в этот раз метод file.delete() не работает в android 11, потому что мультимедийный контент вы не создали. Эта ситуация следует с диалоговым окном подтверждения системы.

person Jatin Borsaniya    schedule 22.06.2021

Вот хорошее решение для Android Q и R. Вы можете переименовать, дублировать или удалить файл в Android R. Проверьте этот класс: https://gist.github.com/fiftyonemoon/433b563f652039e32c07d1d629f913fb

person hardkgosai    schedule 12.07.2021