Android图库仅显示小于5MB视频的实现方案咨询
嘿,这个需求我之前做项目时也碰到过,其实有两种靠谱的实现思路,看你更看重开发速度还是用户体验:
方法一:选择后过滤(快速落地)
这种方式改动最小,不需要额外做界面,只是在用户选完视频后,判断大小是否符合要求,不符合就提示重新选择。
首先写个工具方法,通过Uri获取视频文件的大小:
private long getVideoSize(Uri videoUri) { Cursor cursor = getContentResolver().query( videoUri, new String[]{MediaStore.Video.Media.SIZE}, null, null, null ); if (cursor != null) { cursor.moveToFirst(); long size = cursor.getLong(0); cursor.close(); return size; } return 0; }
然后在处理选择结果的逻辑里加判断(如果用的是旧的onActivityResult):
@Override protected void onActivityResult(int requestCode, int resultCode, Intent data) { super.onActivityResult(requestCode, resultCode, data); if (requestCode == REQUEST_TAKE_GALLERY_VIDEO && resultCode == RESULT_OK && data != null) { Uri selectedVideoUri = data.getData(); // 5MB 转成字节单位 final long MAX_VIDEO_SIZE = 5 * 1024 * 1024; long videoSize = getVideoSize(selectedVideoUri); if (videoSize > MAX_VIDEO_SIZE) { Toast.makeText(this, "请选择小于5MB的视频哦", Toast.LENGTH_SHORT).show(); // 可以直接重新唤起选择界面,让用户再选一次 takeVideoFromGallery(); } else { // 这里处理符合大小要求的视频 handleSelectedVideo(selectedVideoUri); } } }
如果已经迁移到推荐的Activity Result API,可以改成这样:
// 先注册启动器 ActivityResultLauncher<Intent> videoPickerLauncher = registerForActivityResult( new ActivityResultContracts.StartActivityForResult(), result -> { if (result.getResultCode() == RESULT_OK && result.getData() != null) { Uri selectedVideoUri = result.getData().getData(); long videoSize = getVideoSize(selectedVideoUri); final long MAX_VIDEO_SIZE = 5 * 1024 * 1024; if (videoSize > MAX_VIDEO_SIZE) { Toast.makeText(this, "请选择小于5MB的视频哦", Toast.LENGTH_SHORT).show(); takeVideoFromGallery(); } else { handleSelectedVideo(selectedVideoUri); } } } ); // 调用图库的方法 public void takeVideoFromGallery(){ Intent intent = new Intent(); intent.setType("video/*"); intent.setAction(Intent.ACTION_GET_CONTENT); videoPickerLauncher.launch(Intent.createChooser(intent,"Select Video")); }
这个方法的优点是代码改动少,快速实现;缺点是用户可能选了大视频后才被提示,体验略有瑕疵。
方法二:提前查询过滤(更优体验)
如果想让用户一开始就看不到超过5MB的视频,就需要自己查询设备上的视频资源,筛选出符合大小的,再做个自定义选择界面展示。
步骤1:定义视频信息实体类
public class VideoItem { private Uri uri; private String name; private long size; public VideoItem(Uri uri, String name, long size) { this.uri = uri; this.name = name; this.size = size; } // Getter方法 public Uri getUri() { return uri; } public String getName() { return name; } public long getSize() { return size; } }
步骤2:查询符合条件的视频
private List<VideoItem> getSmallVideos() { List<VideoItem> videoList = new ArrayList<>(); final long MAX_VIDEO_SIZE = 5 * 1024 * 1024; // 查询需要的字段 String[] projection = { MediaStore.Video.Media._ID, MediaStore.Video.Media.DISPLAY_NAME, MediaStore.Video.Media.SIZE }; // 筛选条件:大小小于5MB String selection = MediaStore.Video.Media.SIZE + " < ?"; String[] selectionArgs = {String.valueOf(MAX_VIDEO_SIZE)}; Cursor cursor = getContentResolver().query( MediaStore.Video.Media.EXTERNAL_CONTENT_URI, projection, selection, selectionArgs, null ); if (cursor != null) { while (cursor.moveToNext()) { long videoId = cursor.getLong(cursor.getColumnIndexOrThrow(MediaStore.Video.Media._ID)); String videoName = cursor.getString(cursor.getColumnIndexOrThrow(MediaStore.Video.Media.DISPLAY_NAME)); long videoSize = cursor.getLong(cursor.getColumnIndexOrThrow(MediaStore.Video.Media.SIZE)); // 构建视频Uri Uri videoUri = ContentUris.withAppendedId(MediaStore.Video.Media.EXTERNAL_CONTENT_URI, videoId); videoList.add(new VideoItem(videoUri, videoName, videoSize)); } cursor.close(); } return videoList; }
步骤3:自定义选择界面
把查询到的视频列表展示在RecyclerView里,用户点击后直接处理即可,不需要再判断大小。这种方式用户体验更好,但需要自己实现列表界面,代码量稍大。
注意:Android 10及以下需要申请READ_EXTERNAL_STORAGE权限;Android 11+不需要额外权限,直接查询MediaStore即可。
内容的提问来源于stack exchange,提问作者Usman Khan
相关产品推荐
相关产品推荐

