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

Flutter在Android 14中访问设备全量视频与图像的实现求助

Android 14 下获取设备全部视频的实现方案

一、权限申请

Android 14(API 34)对媒体权限做了细分,不再使用统一的READ_EXTERNAL_STORAGE,需单独申请视频读取权限:

  • 先在AndroidManifest.xml中声明权限:
<!-- Android 13+ 专属视频读取权限 -->
<uses-permission android:name="android.permission.READ_MEDIA_VIDEO" />
<!-- 兼容低版本(若你的minSdk低于33) -->
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" android:maxSdkVersion="32" />
  • 动态申请权限:
// 检查权限状态
if (ContextCompat.checkSelfPermission(this, Manifest.permission.READ_MEDIA_VIDEO) != PackageManager.PERMISSION_GRANTED) {
    // 发起权限申请
    ActivityResultContracts.RequestPermission().launch(Manifest.permission.READ_MEDIA_VIDEO)
}

注意:Android 14中用户可选择仅授予「部分权限」(仅允许访问近期视频),若应用需要全量视频,需在权限申请前的说明文案里明确告知用户需求。

二、获取全量视频内容

推荐使用官方的MediaStore API查询设备视频,兼容性与稳定性最优:

1. 构建查询参数

// 定义需要查询的视频字段
val projection = arrayOf(
    MediaStore.Video.Media._ID,
    MediaStore.Video.Media.DISPLAY_NAME,
    MediaStore.Video.Media.DATE_ADDED,
    MediaStore.Video.Media.SIZE
)

// 外部存储视频的查询URI
val queryUri = MediaStore.Video.Media.EXTERNAL_CONTENT_URI

// 可选:按添加时间倒序,优先获取最新视频
val sortOrder = "${MediaStore.Video.Media.DATE_ADDED} DESC"

2. 执行查询并处理结果

contentResolver.query(
    queryUri,
    projection,
    null,
    null,
    sortOrder
)?.use { cursor ->
    // 遍历游标提取视频信息
    while (cursor.moveToNext()) {
        val videoId = cursor.getLong(cursor.getColumnIndexOrThrow(MediaStore.Video.Media._ID))
        val displayName = cursor.getString(cursor.getColumnIndexOrThrow(MediaStore.Video.Media.DISPLAY_NAME))
        val size = cursor.getLong(cursor.getColumnIndexOrThrow(MediaStore.Video.Media.SIZE))
        val dateAdded = cursor.getLong(cursor.getColumnIndexOrThrow(MediaStore.Video.Media.DATE_ADDED))
        
        // 生成视频的Content URI,用于后续读取内容
        val videoUri = ContentUris.withAppendedId(MediaStore.Video.Media.EXTERNAL_CONTENT_URI, videoId)
        
        // 示例:通过ContentResolver打开视频输入流,用于备份操作
        contentResolver.openInputStream(videoUri)?.use { inputStream ->
            // 此处编写备份逻辑,如上传至云端
        }
    }
}

3. 处理Android 14的权限限制

如果用户授予了「部分权限」,MediaStore仅会返回最近几天的视频。若要获取全量视频,需引导用户跳转至应用设置页修改权限为「允许所有媒体」:

val intent = Intent(Settings.ACTION_APPLICATION_DETAILS_SETTINGS).apply {
    data = Uri.fromParts("package", packageName, null)
}
startActivity(intent)

三、可选方案:同时查询图片和视频

若需同时处理图片和视频,可使用MediaStore.Files并过滤媒体类型:

val selection = "${MediaStore.Files.FileColumns.MEDIA_TYPE} = ?"
val selectionArgs = arrayOf(MediaStore.Files.FileColumns.MEDIA_TYPE_VIDEO.toString())

contentResolver.query(
    MediaStore.Files.getContentUri("external"),
    projection,
    selection,
    selectionArgs,
    sortOrder
)?.use { cursor ->
    // 遍历处理视频数据
}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.07 11:35:10