如何在没有系统确认对话框的情况下在Android 11API 30上删除文件?

问题描述

我有一个将视频录制到共享MOVIES文件夹的应用。

我可以在录制的视频活动中使用contentResolver.delete(uri,null,null)方法在Android 11(API 30)上删除这些文件。

但是,如果我重新安装该应用程序,则会失去对这些文件的权限...(如此),在这种情况下,我需要执行以下操作:

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

因此它无法使用ContentResolver删除文件,因为重新安装了应用程序,并且有一个例外,我们可以捕获并打开下一个烦人的对话框,以供用户确认删除(对于每个文件删除,应该一个不同的对话框,多次删除-没办法)

enter image description here

然后,我在此Android 11设备(模拟器)上从Google Play安装了Explorer应用程序,当我打开它时,该应用程序仅询问存储写权限(我的应用程序也有此权限),并且该Explorer应用程序可以轻松删除任何文件(包括我录制的视频文件)而没有任何确认对话框。

那么他们怎么做呢?这是黑客还是什么?

链接到应用https://play.google.com/store/apps/details?id=com.speedsoftware.explorer

更新

VLC for 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

解决方法

ssh只会询问一次我认为的用户。

在这里看看:

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

,

Android 11 (API 30) 没有系统确认对话框,您可以执行此操作,但您需要 manage_external_storage 权限。该权限被允许用于某些特定类别的应用程序。

  • 文件管理器
  • 备份和恢复应用
  • 防病毒应用
  • 文档管理应用
  • 设备上的文件搜索
  • 磁盘和文件加密
  • 设备到设备的数据迁移

Manage all files on a storage device

如果您的应用不符合上述类别,则不允许使用 manage_external_storage 权限发布。

如果您的应用是图库、视频和音频播放器,那么您不需要 manage_external_storage 权限,您可以直接使用系统确认对话框将其删除。
Here you can get the example to delete media file

在 android 11 之前,您可以直接使用 file.delete() 方法并删除您的文件。

在 android 11 中,file.delete() 方法仅在您创建自己的内容时才有效。例如,您的应用程序下载一张图片,并且在此案例file.delete() 方法中的位置是外部存储。

如果您想删除相机或屏幕截图等媒体文件,那么 file.delete() 方法在 android 11 中不起作用,因为您没有创建媒体内容。这种情况会出现系统确认对话框。

,

这里有一个很好的 Android Q 和 R 解决方案, 您可以在 Android R 中重命名、复制或删除文件。 检查这个类:https://gist.github.com/fiftyonemoon/433b563f652039e32c07d1d629f913fb

相关问答

错误1:Request method ‘DELETE‘ not supported 错误还原:...
错误1:启动docker镜像时报错:Error response from daemon:...
错误1:private field ‘xxx‘ is never assigned 按Alt...
报错如下,通过源不能下载,最后警告pip需升级版本 Requirem...