我有一个应用程序,可以将视频录制到共享的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
删除文件,因为应用程序已被重新安装,并且存在异常,我们可以捕获并打开下一个令人烦恼的对话框,要求用户确认删除(每个文件删除都应该是不同的对话框,多个删除-不可能)。
然后我在这个运行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
}
ContentResolver#checkUriPermission(Uri, int, int)
存在,但我在ContentResolver
中找不到这个方法... https://developer.android.com/reference/android/provider/MediaStore#createDeleteRequest(android.content.ContentResolver,%20java.util.Collection%3Candroid.net.Uri%3E) - user25Context
上有一个checkUriPermission()
方法。 - CommonsWare