从android 11的范围存储中删除图像
Posted
技术标签:
【中文标题】从android 11的范围存储中删除图像【英文标题】:delete images from scoped storage in android 11 【发布时间】:2021-12-27 13:26:42 【问题描述】:我想从作用域存储中删除一个图像文件 从其他目录显示的图像。 我已成功显示图像,但现在我无法在 android 11 中删除这些图像,删除图像的代码适用于 android 10 或更低版本。
private void delSysMedia(ImageModel mi)
ContentResolver cr = context.getContentResolver();
cr.delete(Images.Media.EXTERNAL_CONTENT_URI, Images.Media._ID + "=?", new String[]String.valueOf(mi.getId()));
cr.delete(Images.Thumbnails.EXTERNAL_CONTENT_URI, Images.Thumbnails.IMAGE_ID + "=?", new String[]String.valueOf(mi.getId()));
这是我在图像服务类中使用的代码
【问题讨论】:
new String[]String.valueOf(mi.getId()))
我们不知道你在做什么。我们不知道那会是什么 id。我们也不知道您是如何获得该 ID 的。我们也不知道哪个目录中的哪个文件。在有人可以帮助您之前,您应该写一篇更好的帖子。 .delete() 返回什么?你会用吗?
want to delete an image file from scoped storage
我们不知道该图像将驻留在何处。请提及完整路径。同时展示您是如何创建该图像的。
the images that are showing from the other directories.
其他目录?哪个?你的帖子很不清楚。
另外,您应该首先获取文件的 uri。并为文件 uri 调用 .delete() 十个。
【参考方案1】:
要在 Android 11 及更高版本上删除文件,您需要 MediaStore.createDeleteRequest 并传递要删除的 Uri 列表,它将向用户显示系统默认选择器,要求允许或拒绝删除文件。
您可以使用以下代码删除图像文件。
val uris = arrayListOf<Uri?>()
val uriOfCurrentFile= getImgUri(fileObject.absolutePath)
if (uriOfCurrentFile!= null)
uris.add(uriOfCurrentFile)
val intentSenderLauncher =
registerForActivityResult(ActivityResultContracts.StartIntentSenderForResult())
if (it.resultCode == RESULT_OK)
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.R)
Toast.makeText(context, "Deleted Successfully", Toast.LENGTH_SHORT).show()
//This function gets Uri of file for deletion
fun getImgUri(
path: String,
): Uri?
try
val checkFile = File(path)
Timber.e("checkDelete- $checkFile")
if (checkFile.exists())
var id: Long = 0
val cr: ContentResolver = activity?.contentResolver!!
val selection = MediaStore.Images.Media.DATA
val selectionArgs = arrayOf<String>(checkFile.absolutePath)
val projection = arrayOf(MediaStore.Images.Media._ID, MediaStore.Images.Media.DATA)
val sortOrder = MediaStore.Images.Media.TITLE + " ASC"
val cursor = cr.query(
MediaStore.Images.Media.EXTERNAL_CONTENT_URI, projection,
"$selection=?", selectionArgs, null
)
if (cursor != null)
while (cursor.moveToNext())
val idIndex = cursor.getColumnIndex(MediaStore.Images.Media._ID)
id = cursor.getString(idIndex).toLong()
Timber.e("checkFileID- $id")
try
val photoUri: Uri = ContentUris.withAppendedId(
MediaStore.Images.Media.EXTERNAL_CONTENT_URI,
id
)
return photoUri
catch (securityException: SecurityException)
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q)
val recoverableSecurityException =
securityException as? RecoverableSecurityException
?: throw securityException
recoverableSecurityException.userAction.actionIntent.intentSender
else
throw securityException
catch (ex: Exception)
ex.printStackTrace()
return null
//now you have list of Uri you want to delete
if (uris != null && uris.size > 0)
var intentSender = when
Build.VERSION.SDK_INT >= Build.VERSION_CODES.R ->
MediaStore.createDeleteRequest(
activity!!.contentResolver,
uris
).intentSender
else -> null
intentSender?.let sender ->
intentSenderLauncher.launch(
IntentSenderRequest.Builder(sender).build()
)
请注意,如果不是图像文件,则必须替换
MediaStore.Images
与 MediaStore.Video
、MediaStore.Audio
、MediaStore.Files
等。
【讨论】:
以上是关于从android 11的范围存储中删除图像的主要内容,如果未能解决你的问题,请参考以下文章
如何将 expo-image-picker 与 android 11 范围存储一起使用?