如何从手机媒体库中获取全部视频文件

2018/07/01 Android

如何从手机媒体库中获取全部视频文件

最近项目在做一个视频选择的功能,一开始的思路是通过 MediaStore获取媒体信息:

  public static List<LocalVideoBean> getLocalVideoList(Context context) {
    List<LocalVideoBean> localVideoBeans = new ArrayList<>();
    // MediaStore.Video.Thumbnails.DATA:视频缩略图的文件路径
    String[] thumbColumns = {MediaStore.Video.Thumbnails.DATA,
            MediaStore.Video.Thumbnails.VIDEO_ID};
    // 视频其他信息的查询条件
    String[] mediaColumns = {MediaStore.Video.Media._ID,
            MediaStore.Video.Media.DATA, MediaStore.Video.Media.DURATION, MediaStore.Video.Media.SIZE};

    Cursor cursor = context.getContentResolver().query(MediaStore.Video.Media
                    .EXTERNAL_CONTENT_URI,
            mediaColumns, null, null, null);

    if (cursor == null) {
      return localVideoBeans;
    }

    try {
      if (cursor.moveToFirst()) {
        do {
          LocalVideoBean info = new LocalVideoBean();
          int id = cursor.getInt(cursor
                  .getColumnIndex(MediaStore.Video.Media._ID));
          Cursor thumbCursor = context.getContentResolver().query(
                  MediaStore.Video.Thumbnails.EXTERNAL_CONTENT_URI,
                  thumbColumns, MediaStore.Video.Thumbnails.VIDEO_ID
                          + "=" + id, null, null);
          if (thumbCursor == null) {
            continue;
          }
          try {
            if (thumbCursor.moveToFirst()) {
              info.setId(id);
              info.setVideoPath(cursor.getString(cursor.getColumnIndexOrThrow(MediaStore.Video.Media
                      .DATA)));
              ......
              localVideoBeans.add(info);
            }
          } catch (Exception e) {
            LogUtil.e(TAG, e.toString());
          } finally {
            if (!thumbCursor.isClosed()) {
              thumbCursor.close();
            }
          }
        } while (cursor.moveToNext());
      }
    } catch (Exception e) {
      LogUtil.e(TAG, e.toString());
    } finally {
      if (!cursor.isClosed()) {
        cursor.close();
      }
    }
    return localVideoBeans;
  }

可是发现在一加手机5和三星的部分机型上并不能将最近拍的新视频获取到。网络上也大多是相互抄差不多的代码。

后来灵机一动,既然手机上的图库软件都能将最近拍摄的视频加载出来,那么肯定存在实现方式,能将最新的视频加载出来。

后来找到一个图库实现库,看了下源码,其实和上面的代码并没有多少差别:

  /**
   * 获取本地视频
   *
   * @param context
   * @return 本地视频列表
   */
  public static List<LocalVideoBean> getLocalVideoList(Context context) {
    List<LocalVideoBean> localVideoBeans = new ArrayList<>();
    ContentResolver contentResolver = context.getContentResolver();
    String[] projection = new String[]{
            MediaStore.Video.Media._ID,
            MediaStore.Video.Media.DATA,
            MediaStore.Video.Media.DURATION,
            MediaStore.Video.Media.SIZE
    };

    Cursor cursor = contentResolver.query(
            MediaStore.Video.Media.EXTERNAL_CONTENT_URI,
            projection,
            null,
            null,
            MediaStore.Video.Media.DATE_ADDED + " DESC LIMIT " + Integer.MAX_VALUE + " OFFSET " + 0);

    if (cursor != null) {
      try {
        int count = cursor.getCount();
        if (count > 0) {
          cursor.moveToFirst();
          do {
            LocalVideoBean localVideoBean = parseVideoCursor(context, cursor);
            if (localVideoBean != null) {
              localVideoBeans.add(localVideoBean);
            }
          } while (cursor.moveToNext());
        }
      } catch (Exception e) {
        LogUtil.e(TAG, e);
      } finally {
        if (!cursor.isClosed()) {
          cursor.close();
        }
      }
    }
    return localVideoBeans;
  }

和第一段代码并没有什么不同之处,除了一处…

Cursor cursor = contentResolver.query( MediaStore.Video.Media.EXTERNAL_CONTENT_URI, projection, null, null, MediaStore.Video.Media.DATE_ADDED + “ DESC LIMIT “ + Integer.MAX_VALUE + “ OFFSET “ + 0);

为什么变为这个排序条件就可以将最近拍摄的视频取出呢?这需要看看源码是怎么实现的,阅读源码中…

如有缺漏不足之处,欢迎创建issue,PR 😄

Search

    Table of Contents