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

Android Studio(Kotlin):复制图片/视频后相册不显示的解决咨询

解决复制文件后相册不显示的问题

问题核心是Android相册依赖MediaStore内容提供者获取媒体文件,直接复制文件到存储目录后,系统不会自动扫描识别新文件,因此需要主动通知系统扫描或通过MediaStore API写入文件。

方案1:通知媒体扫描器扫描新文件

复制完成后,调用MediaScannerConnection扫描目标文件,让系统将其加入媒体库:

override fun onButtonClick(position: Int) {
    val origin = File(statuses[position])
    val destination = if (statuses[position].endsWith(".jpg", ignoreCase = true)) {
        val picturesDir = File(
            Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_PICTURES),
            FilePath.PICTURES_DIRECTORY
        )
        // 确保目录存在
        picturesDir.mkdirs()
        File(picturesDir, "${Random.nextInt()}.jpg")
    } else {
        val moviesDir = File(
            Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_MOVIES),
            FilePath.VIDEO_DIRECTORY
        )
        moviesDir.mkdirs()
        File(moviesDir, "${Random.nextInt()}.mp4")
    }

    origin.copyTo(destination)

    // 通知媒体扫描器
    MediaScannerConnection.scanFile(
        this@YourActivity, // 替换为实际Context,比如Activity或Fragment的requireContext()
        arrayOf(destination.absolutePath),
        arrayOf(if (destination.extension.equals("jpg", ignoreCase = true)) "image/jpeg" else "video/mp4"),
        null
    )
}

方案2:适配Android 10+分区存储(推荐)

Android Q(API 29)及以上,直接操作公共目录文件需要适配分区存储,使用MediaStore API写入文件时,系统会自动将文件纳入媒体库,无需额外扫描:

通用保存方法

private fun saveMediaToGallery(context: Context, originFile: File, isImage: Boolean) {
    val contentValues = ContentValues().apply {
        val fileName = "${Random.nextInt()}.${if (isImage) "jpg" else "mp4"}"
        val mimeType = if (isImage) "image/jpeg" else "video/mp4"
        val relativePath = if (isImage) {
            "${Environment.DIRECTORY_PICTURES}/${FilePath.PICTURES_DIRECTORY}"
        } else {
            "${Environment.DIRECTORY_MOVIES}/${FilePath.VIDEO_DIRECTORY}"
        }

        put(MediaStore.MediaColumns.DISPLAY_NAME, fileName)
        put(MediaStore.MediaColumns.MIME_TYPE, mimeType)
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q) {
            put(MediaStore.MediaColumns.RELATIVE_PATH, relativePath)
            put(MediaStore.MediaColumns.IS_PENDING, 1)
        } else {
            // Android 9及以下,直接指定文件路径
            val targetDir = if (isImage) {
                File(Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_PICTURES), FilePath.PICTURES_DIRECTORY)
            } else {
                File(Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_MOVIES), FilePath.VIDEO_DIRECTORY)
            }
            targetDir.mkdirs()
            val targetFile = File(targetDir, fileName)
            put(MediaStore.MediaColumns.DATA, targetFile.absolutePath)
        }
    }

    val contentUri = if (isImage) {
        MediaStore.Images.Media.EXTERNAL_CONTENT_URI
    } else {
        MediaStore.Video.Media.EXTERNAL_CONTENT_URI
    }

    context.contentResolver.insert(contentUri, contentValues)?.let { uri ->
        context.contentResolver.openOutputStream(uri).use { outputStream ->
            originFile.inputStream().use { inputStream ->
                inputStream.copyTo(outputStream!!)
            }
        }

        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q) {
            contentValues.clear()
            contentValues.put(MediaStore.MediaColumns.IS_PENDING, 0)
            context.contentResolver.update(uri, contentValues, null, null)
        }
    }
}

// 调用示例
override fun onButtonClick(position: Int) {
    val origin = File(statuses[position])
    val isImage = statuses[position].endsWith(".jpg", ignoreCase = true)
    saveMediaToGallery(this@YourActivity, origin, isImage)
}

注意事项

  • 权限处理:
    • Android 6.0-9.0:需要申请WRITE_EXTERNAL_STORAGE权限,并在运行时请求用户授权。
    • Android 10-10.1:使用MediaStore API无需额外权限;若直接操作文件需在Manifest中开启requestLegacyExternalStorage。
    • Android 11+:使用MediaStore API无需特殊权限;若直接操作公共目录,需申请MANAGE_EXTERNAL_STORAGE权限。
  • 目录创建:必须确保目标目录存在,调用mkdirs()避免因目录不存在导致复制或写入失败。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.19 00:00:30