关于 Android 系统回收站的实现

您的观察非常正确。Android 系统的回收站实现通常是通过以下几种方式:

  • 文件名添加 .Trash 前缀,使文件在文件浏览器中被隐藏

  • 在 MediaStore 中将文件标记为 IS_TRASHED = 1

  • 有些设备会将文件移动到特定的 .Trash 目录

    // 创建文件条目时使用 .Trash 前缀 put(MediaStore.MediaColumns.DISPLAY_NAME, ".Trash-"+System.currentTimeMillis()/1000+"-"+fileName)

    // 然后在所有 URI 上设置 IS_TRASHED 标记 val values = ContentValues().apply { put(MediaStore.MediaColumns.IS_TRASHED, 1) } contentResolver.update(uri, values, null, null)

回收站实现的关键点

  • 文件名前缀:.Trash-[时间戳]-[原文件名] 是一种常见的格式

  • IS_TRASHED 标记:在 Android 11+ 上,这个标记告诉系统该文件已被移到回收站

  • 相对路径:将文件放在应用专属目录下,如 Pictures/应用名称/

  • 保留元数据:保存原始文件名和删除时间,以便将来可以恢复

    /**

    • 从回收站恢复文件 */ @RequiresApi(Build.VERSION_CODES.Q) suspend fun restoreFromTrash(context: Context, uri: Uri) = withContext(Dispatchers.IO) { try { val contentResolver = context.contentResolver

      kotlin 复制代码
       // 1. 获取当前文件名
       var fileName = ""
       contentResolver.query(
           uri,
           arrayOf(MediaStore.MediaColumns.DISPLAY_NAME),
           null,
           null,
           null
       )?.use { cursor ->
           if (cursor.moveToFirst()) {
               fileName = cursor.getString(cursor.getColumnIndexOrThrow(MediaStore.MediaColumns.DISPLAY_NAME))
           }
       }
       
       if (fileName.startsWith(".Trash-")) {
           // 2. 提取原始文件名
           val originalFileName = fileName.substringAfter("-", "").substringAfter("-", "")
           
           // 3. 更新文件属性
           val values = ContentValues().apply {
               put(MediaStore.MediaColumns.DISPLAY_NAME, originalFileName)
               put(MediaStore.MediaColumns.IS_TRASHED, 0)
           }
           
           // 4. 应用更新
           contentResolver.update(uri, values, null, null)
           LogMG.e("tagyy", "文件已从回收站恢复: $originalFileName")
           return@withContext true
       }

      } catch (e: Exception) { LogMG.e("tagyy", "从回收站恢复失败: ${e.message}") e.printStackTrace() } return@withContext false }

    /**

    • 获取回收站中的所有文件 */ @RequiresApi(Build.VERSION_CODES.Q) suspend fun getTrashFiles(context: Context) = withContext(Dispatchers.IO) { val trashFiles = mutableListOf() val contentResolver = context.contentResolver

      // 查询所有已标记为回收站的文件 val selection = " <math xmlns="http://www.w3.org/1998/Math/MathML"> M e d i a S t o r e . M e d i a C o l u m n s . I S T R A S H E D = ? O R {MediaStore.MediaColumns.IS_TRASHED} = ? OR </math>MediaStore.MediaColumns.ISTRASHED=?OR{MediaStore.MediaColumns.DISPLAY_NAME} LIKE ?" val selectionArgs = arrayOf("1", ".Trash-%")

      // 查询不同类型的媒体 val uriTypes = listOf( MediaStore.Images.Media.EXTERNAL_CONTENT_URI, MediaStore.Video.Media.EXTERNAL_CONTENT_URI, MediaStore.Audio.Media.EXTERNAL_CONTENT_URI, MediaStore.Downloads.EXTERNAL_CONTENT_URI )

      for (uri in uriTypes) { contentResolver.query( uri, arrayOf(MediaStore.MediaColumns._ID), selection, selectionArgs, null )?.use { cursor -> while (cursor.moveToNext()) { val id = cursor.getLong(cursor.getColumnIndexOrThrow(MediaStore.MediaColumns._ID)) trashFiles.add(ContentUris.withAppendedId(uri, id)) } } }

      return@withContext trashFiles }

总结

Android 系统回收站的实现主要依赖于:

  • 文件名前缀(.Trash-)

  • MediaStore 中的 IS_TRASHED 标记

  • 将文件放在特定目录

您的实现已经涵盖了这些关键点,应该能够正常工作。记住,不同厂商的 Android 设备可能对回收站有不同的实现,但您的方法是最通用的解决方案。

相关推荐
斗锋在干嘛1 小时前
Android里面内存优化
android
jiet_h3 小时前
深入解析Kapt —— Kotlin Annotation Processing Tool 技术博客
android·开发语言·kotlin
alexhilton3 小时前
实战:探索Jetpack Compose中的SearchBar
android·kotlin·android jetpack
uhakadotcom4 小时前
EventBus:简化组件间通信的利器
android·java·github
笑鸿的学习笔记5 小时前
ROS2笔记之服务通信和基于参数的服务通信区别
android·笔记·microsoft
8931519606 小时前
Android开发融云获取多个会话的总未读数
android·android开发·android教程·融云获取多个会话的总未读数·融云未读数
zjw_swun6 小时前
实现了一个uiautomator玩玩
android
pengyu6 小时前
系统化掌握Dart网络编程之Dio(二):责任链模式篇
android·flutter·dart
水w6 小时前
【Android Studio】如何卸载干净(详细步骤)
android·开发语言·android studio·activity
亦是远方6 小时前
2025华为软件精英挑战赛2600w思路分享
android·java·华为