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

Kotlin开发中从系统图库选择并删除视频的问题排查

Android 图库选择并删除视频功能实现问题

问题背景

我正在开发Android应用,需要实现打开系统图库、选择视频并删除的功能,使用了以下Kotlin代码:

private val pickVideoLauncher = registerForActivityResult(ActivityResultContracts.StartActivityForResult()) { result ->
        if (result.resultCode == Activity.RESULT_OK) {
            val data: Intent? = result.data
            videoUrl = data?.data
            // Handle the selected video URI
        }
    }
    private val deleteVideoLauncher = registerForActivityResult(ActivityResultContracts.StartActivityForResult()) { result ->
        if (result.resultCode == Activity.RESULT_OK) {
            videoUrl?.let { videoUri ->
                // The video has been deleted, perform necessary actions
                // after deleting the selected video
            }
        }
    }
binding.deleteVideo.setOnClickListener {
            deleteOriginalVideoFromGallery(videoUrl)

        }

private fun deleteOriginalVideoFromGallery(videoUri: Uri?) {
        val intent = Intent(Intent.ACTION_PICK, MediaStore.Video.Media.EXTERNAL_CONTENT_URI)
        intent.type = "video/*"

        pickVideoLauncher.launch(intent)
        videoUri?.let { videoUri ->
            val deleteIntent = Intent(Intent.ACTION_DELETE)
            deleteIntent.data = videoUri

            deleteVideoLauncher.launch(deleteIntent)
        }
    }

错误信息

运行时抛出异常:

E/AndroidRuntime: FATAL EXCEPTION: main
Process: harmony.valley.wamboocam, PID: 23073
android.content.ActivityNotFoundException: No Activity found to handle Intent { act=android.intent.action.DELETE
dat=content://media/... }
at android.app.Instrumentation.checkStartActivityResult(Instrumentation.java:2174)
at android.app.Instrumentation.execStartActivity(Instrumentation.java:1805)
at android.app.Activity.startActivityForResult(Activity.java:5596)
at androidx.activity.ComponentActivity.startActivityForResult(ComponentActivity.java:728)
at androidx.core.app.ActivityCompat$Api16Impl.startActivityForResult(ActivityCompat.java:809)
at androidx.core.app.ActivityCompat.startActivityForResult(ActivityCompat.java:246)
at androidx.activity.ComponentActivity$2.onLaunch(ComponentActivity.java:243)
at androidx.activity.result.ActivityResultRegistry$2.launch(ActivityResultRegistry.java:175)
at androidx.fragment.app.Fragment$10.launch(Fragment.java:3622)
at androidx.activity.result.ActivityResultLauncher.launch(ActivityResultLauncher.java:47)
at harmony.valley.wamboocam.HomeFragment.deleteOriginalVideoFromGallery(HomeFragment.kt:1043)
at harmony.valley.wamboocam.HomeFragment.initUI$lambda$24$lambda$23(HomeFragment.kt:763)

删除deleteVideoLauncher.launch(deleteIntent)后,图库能正常打开,但选中视频后仅返回应用,无任何删除操作执行。

解决方案

1. 修复核心逻辑顺序

你的代码错误在于同时启动了选择视频和删除两个Intent,而且初始时videoUri为null(还没选视频),直接触发删除Intent导致找不到对应处理Activity。正确流程是:先打开图库选视频,拿到URI后再执行删除操作。

修改后的完整代码:

// 只保留一个选择视频的Launcher,删除逻辑在选完视频后触发
private val pickVideoLauncher = registerForActivityResult(ActivityResultContracts.StartActivityForResult()) { result ->
    if (result.resultCode == Activity.RESULT_OK) {
        val videoUri = result.data?.data
        videoUri?.let {
            // 选中视频后执行删除
            deleteSelectedVideo(it)
        }
    }
}

binding.deleteVideo.setOnClickListener {
    // 点击按钮直接打开图库选择视频
    val pickIntent = Intent(Intent.ACTION_PICK, MediaStore.Video.Media.EXTERNAL_CONTENT_URI)
    pickIntent.type = "video/*"
    pickVideoLauncher.launch(pickIntent)
}

private fun deleteSelectedVideo(videoUri: Uri) {
    // 先尝试用系统删除Intent(部分图库应用支持)
    val deleteIntent = Intent(Intent.ACTION_DELETE)
    deleteIntent.data = videoUri
    
    if (deleteIntent.resolveActivity(packageManager) != null) {
        startActivity(deleteIntent)
    } else {
        // 系统不支持时,直接通过MediaStore删除(更可靠)
        deleteVideoViaMediaStore(videoUri)
    }
}

// 适配不同Android版本的MediaStore删除逻辑
private fun deleteVideoViaMediaStore(videoUri: Uri) {
    try {
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.R) {
            // Android 11+ 用官方推荐的批量删除请求,无需危险权限
            val uris = listOf(videoUri)
            val pendingIntent = MediaStore.createDeleteRequest(contentResolver, uris)
            startIntentSenderForResult(pendingIntent.intentSender, 0, null, 0, 0, 0, null)
        } else {
            // Android 10及以下,直接通过ContentResolver删除
            contentResolver.delete(videoUri, null, null)
            // 刷新媒体库,确保图库同步更新
            sendBroadcast(Intent(Intent.ACTION_MEDIA_SCANNER_SCAN_FILE, videoUri))
        }
        // 这里添加删除后的逻辑,比如更新UI、提示用户等
    } catch (e: Exception) {
        e.printStackTrace()
    }
}

2. 权限适配

  • Android 10(API 29)及以下:需要在Manifest中声明WRITE_EXTERNAL_STORAGE权限,并动态申请
  • Android 11(API 30)及以上:删除自己应用创建的视频无需额外权限;删除其他应用的视频,使用MediaStore.createDeleteRequest会自动弹出用户确认弹窗,无需申请MANAGE_EXTERNAL_STORAGE权限

3. 关键注意点

  • 必须按顺序执行流程:选视频→拿到URI→执行删除,禁止同时启动多个Activity Intent
  • 用resolveActivity检查Intent是否有对应处理Activity,避免ActivityNotFoundException
  • Android 11+优先使用MediaStore.createDeleteRequest,这是官方推荐的安全删除方式

内容的提问来源于stack exchange,提问作者Harmony Valley

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.21 05:27:18