You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Android 10+设备如何无需MANAGE_EXTERNAL_STORAGE权限在视频播放器适配器删除视频文件

Android 10+无需MANAGE_EXTERNAL_STORAGE权限删除视频文件的方案(适配RecyclerView场景)

完全可以不用申请MANAGE_EXTERNAL_STORAGE权限实现播放后删除视频的功能,以下是针对不同存储场景的可行方案,以及适配RecyclerView+适配器的具体实现:

一、核心删除方案(分存储场景)

1. 应用私有目录下的视频

如果视频文件存放在应用私有目录(如getFilesDir()、getCacheDir(),或Android 11+的getExternalFilesDir(Environment.DIRECTORY_MOVIES)),直接通过File.delete()即可删除,无需任何存储权限——这是应用的专属空间,系统默认允许读写操作。

2. 公共媒体目录的视频(DCIM、Movies等)

在Android 10及以上的分区存储规则下,不能直接通过文件路径删除公共目录的视频,需借助MediaStore的ContentResolver操作,仅需申请对应权限:

  • Android 10-12:申请WRITE_EXTERNAL_STORAGE权限
  • Android 13+:申请MEDIA_VIDEO_WRITE权限(媒体权限细分后的专属权限)

示例删除代码:

fun deleteMediaStoreVideo(context: Context, videoUri: Uri): Boolean {
    return try {
        // 返回值为删除的行数,大于0则表示删除成功
        context.contentResolver.delete(videoUri, null, null) > 0
    } catch (e: Exception) {
        e.printStackTrace()
        false
    }
}

3. 用户通过文件选择器选择的视频

如果视频是用户通过ACTION_OPEN_DOCUMENT等系统文件选择器选中的,可先获取持久化URI权限,之后用ContentResolver.delete()删除,无需存储权限(这是用户主动授权的单个文件访问权限)。

获取持久化权限的代码:

fun takePersistableUriPermission(context: Context, uri: Uri) {
    val takeFlags = Intent.FLAG_GRANT_READ_URI_PERMISSION or Intent.FLAG_GRANT_WRITE_URI_PERMISSION
    context.contentResolver.takePersistableUriPermission(uri, takeFlags)
}

二、适配RecyclerView+适配器场景

1. 数据源设计

为适配器的数据源添加存储类型标识,方便后续调用对应删除逻辑:

enum class VideoStorageType {
    PRIVATE, MEDIA_STORE, DOCUMENT_URI
}

data class VideoItem(
    val id: Long,
    val title: String,
    val playUrl: String,
    // 根据存储类型赋值对应字段
    val privatePath: String? = null,
    val mediaStoreUri: Uri? = null,
    val documentUri: Uri? = null,
    val storageType: VideoStorageType
)

2. 适配器内的删除逻辑处理

将删除操作放在子线程执行(避免阻塞UI),删除成功后更新数据源并通知RecyclerView刷新:

class VideoAdapter(
    private val videoList: MutableList<VideoItem>,
    private val context: Context
) : RecyclerView.Adapter<VideoAdapter.VideoViewHolder>() {

    inner class VideoViewHolder(itemView: View) : RecyclerView.ViewHolder(itemView) {
        val deleteBtn: Button = itemView.findViewById(R.id.btn_delete_after_play)
        val playerView: PlayerView = itemView.findViewById(R.id.player_view)

        init {
            // 假设播放器播放完成后触发删除
            playerView.addOnCompletionListener {
                triggerDelete()
            }
            // 也支持手动点击删除按钮
            deleteBtn.setOnClickListener {
                triggerDelete()
            }
        }

        private fun triggerDelete() {
            val position = adapterPosition
            if (position == RecyclerView.NO_POSITION) return

            val targetVideo = videoList[position]
            // 子线程执行删除
            CoroutineScope(Dispatchers.IO).launch {
                val deleteSuccess = when (targetVideo.storageType) {
                    VideoStorageType.PRIVATE -> {
                        targetVideo.privatePath?.let { File(it).delete() } ?: false
                    }
                    VideoStorageType.MEDIA_STORE -> {
                        targetVideo.mediaStoreUri?.let { deleteMediaStoreVideo(context, it) } ?: false
                    }
                    VideoStorageType.DOCUMENT_URI -> {
                        targetVideo.documentUri?.let {
                            context.contentResolver.delete(it, null, null) > 0
                        } ?: false
                    }
                }

                // 主线程更新UI
                if (deleteSuccess) {
                    withContext(Dispatchers.Main) {
                        videoList.removeAt(position)
                        notifyItemRemoved(position)
                        // 可选:如果需要保持列表连续性,调用notifyItemRangeChanged
                        notifyItemRangeChanged(position, videoList.size)
                    }
                }
            }
        }
    }

    // 重写onCreateViewHolder、onBindViewHolder、getItemCount等方法...
}

三、注意事项

  • Android 10及以上禁止直接通过文件路径操作公共媒体目录的文件,必须使用MediaStore接口
  • Android 13+需替换原WRITE_EXTERNAL_STORAGE权限为MEDIA_VIDEO_WRITE,避免权限申请被拒
  • 对于用户选择的文件,务必在获取URI时调用takePersistableUriPermission,否则应用重启后会丢失权限无法删除

内容的提问来源于stack exchange,提问作者Ayan Mishra

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.28 21:33:15