Kotlin开发中从系统图库选择并删除视频的问题排查
问题背景
我正在开发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

