从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.ImagesMediaStore.VideoMediaStore.AudioMediaStore.Files 等。

【讨论】:

以上是关于从android 11的范围存储中删除图像的主要内容,如果未能解决你的问题,请参考以下文章

如何将 expo-image-picker 与 android 11 范围存储一起使用?

在 Android Q 中从外部存储访问照片

从服务器下载时,listview 将图像存储在 android 中的位置

如何在某个日期范围内从表存储中删除记录?

如何在android中保存从相机拍摄的图像

如何从 URL 下载图像并缓存 Android (React-Native)