如何在没有系统确认对话框的情况下删除 Android 11 (API 30) 上的文件? [英] How can I delete file on Android 11 (API 30) without system confirmation dialog?

查看:68
本文介绍了如何在没有系统确认对话框的情况下删除 Android 11 (API 30) 上的文件?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

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

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

尝试{context.contentResolver.delete(uri, null, null)} 捕获(异常:异常){如果(异常是 RecoverableSecurityException){val intentSender = exception.userAction.actionIntent.intentSenderintentSender?.let {回调? .startIntentSenderForResult(意图发送者,请求代码)}}}

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

然后我在这个 Android 11 设备(模拟器)上安装了来自 Google Play 的 Explorer 应用程序,当我打开它时,该应用程序只要求存储写入权限(我的应用程序也这样做)并且这个 Explorer 应用程序可以轻松删除任何文件(包括我录制的视频文件)没有任何确认对话框.

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

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

更新

Android 版 VLC 还可以删除任何媒体文件 https://play.google.com/store/apps/details?id=org.videolan.vlc

他们也使用 content provider,所以它是一样的,但它返回 true 不像我的应用程序,为什么?

fun deleteFile(file: File): Boolean {删除变量:布尔值//从Android Medialib中删除,为了与设备MTP存储和其他列出内容的应用程序保持一致://媒体如果(文件.isDirectory){删除 = 真for (child in file.listFiles()) 删除 = 删除和 deleteFile(child)if (deleted) 删除 = 删除和 file.delete()} 别的 {val cr = AppContextProvider.appContext.contentResolver尝试 {删除 = cr.delete(MediaStore.Files.getContentUri(external"),MediaStore.Files.FileColumns.DATA + "=?", arrayOf(file.path)) >0} catch(忽略:IllegalArgumentException){删除 = 假} catch(忽略:SecurityException){删除 = 假}//可能发生在某些设备上...如果 (file.exists()) 删除 = 删除或 file.delete()}返回已删除}

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

解决方案

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

I have an app which records videos to shared MOVIES folder.

I can delete those files on Android 11 (API 30) with contentResolver.delete(uri, null, null) method in my recorded videos activity.

But if I reinstall the app then it looses permissions to those files... (so afwul) and in such case I need to do something like this:

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
            )
        }
    }
}

So it couldn't delete the file using ContentResolver because app was reinstalled and there is exception which we can catch and open the next annoying dialog for a user to confirm deletion (and for each file deletion it should be a different dialog, multiple deleting - no way)

Then I installed Explorer app from Google Play on this Android 11 device (emulator), when I opened it the app only asked for storage write permission (my app also does it) and this Explorer app could easily delete any file (including my record videos files) without any confirmation dialog.

So how do they do it? Is it a hack or what is that?

Link to the app https://play.google.com/store/apps/details?id=com.speedsoftware.explorer

Update

VLC for Android can also delete any media file https://play.google.com/store/apps/details?id=org.videolan.vlc

They also use content provider, so it's the same but it returns true unlike my app, why?

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

解决方案

Well here is a good solution for Android Q and R, You can rename, duplicate or delete the file in Android R. Check this class: https://gist.github.com/fiftyonemoon/433b563f652039e32c07d1d629f913fb

这篇关于如何在没有系统确认对话框的情况下删除 Android 11 (API 30) 上的文件?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆