uniapp_03_获取媒体文件

关于 uniapp 获取媒体文件

  • 什么是 MediaStore
  • MediaStore 内嵌类和常用查询字段
  • 查询图片
  • 查询视频
  • 查询音乐
  • 获取其它文件
  • 参考

什么是 MediaStore

  1. MediaStore 是 Android 中的多媒体数据库,Android 中的多媒体数据都记录在在这里面
  2. Android 对所有的多媒体数据库接口进行了封装,直接用 ContentResolver 调用接口去进行数据库的操作就可以了
  3. 注:一般用于需要本地图片、视频、音乐的元数据查询
  4. 打开 /data/data/com.android.provider.media 下对应的数据库文件 然后导入到电脑用SQLite数据库查看软件之后打开数据库就可以看到对应的字段

MediaStore 内嵌类和常用查询字段

查询图片

查询相册中所有图片

/**
 * @method getPhotoAlbum
 * @return {Object} { "相册1": [ { filePath: "文件路径", dataAdded: "大小" } ],... } 
 * @description 获取相册中内容
 * @description https://blog.csdn.net/zhang0114/article/details/127669677#:~:text=%E5%9C%A8uni-app,d%E7%9B%B8%E5%86%8C%E7%9A%84%E4%BB%A3%E7%A0%81%E6%AE%B5%EF%BC%9A
 * @description https://blog.csdn.net/Jonly_W/article/details/106440072
 * @description https://www.jianshu.com/p/34a7e7d85ecc
 * @description https://blog.csdn.net/u013470102/article/details/89703973
 * @description https://blog.csdn.net/weixin_44008788/article/details/123532073
 * @description https://www.cnblogs.com/alwayswyy/p/4807248.html
 * @description https://blog.csdn.net/u013233097/article/details/50704360
 * */
getPhotoAlbum: function() {
  // #ifdef APP-PLUS
  let list = {};
  // MediaStore这个类是Android系统提供的一个多媒体数据库,android中多媒体信息都可以从这里提取
  // MediaStore包括了多媒体数据库的所有信息,包括音频,视频和图像,android把所有的多媒体数据库接口进行了封装,
  // 所有的数据库不用自己进行创建,直接使用ContentResolver去调用那些封装好的接口就可以进行数据库的操作了。
  const MediaStore = plus.android.importClass('android.provider.MediaStore');
  const PhotoColumns= [
    MediaStore.Images.Media._ID, 
    MediaStore.Images.Media.DATA, 
    MediaStore.Images.Media.DATE_ADDED,
    MediaStore.Images.Media.Thumbnails
  ];
  const Main = plus.android.runtimeMainActivity(); // 此处相当于 context
  const Resolver = Main.getContentResolver(); // 获取ContentResolver实例
  plus.android.importClass(Resolver);
  // url 需要操作的数据, projection resolver需要返回的数据  selection:类似于where selectionArgs: where的参数 sortOrder:排序Order by
  // resolver.query(url, projection, selection, selectionArgs, sortOrder)
  const Cursor = Resolver.query(MediaStore.Images.Media.EXTERNAL_CONTENT_URI, PhotoColumns, null, null, null);
  plus.android.importClass(Cursor);
  // Cursor默认是行的集合 cursor.moveToFirst()指向查询结果的第一个位置
  // 一般通过判断cursor.moveToFirst()的值为true或false来确定查询结果是否为空。
  // 遍历数据
  while(Cursor.moveToNext()){
    const _id = Cursor.getString(Cursor.getColumnIndexOrThrow(MediaStore.Images.Media._ID));
    const FilePath = Cursor.getString(Cursor.getColumnIndexOrThrow(MediaStore.Images.Media.DATA));
    const DateAdded = Cursor.getLong(Cursor.getColumnIndexOrThrow(MediaStore.Images.Media.DATE_ADDED));
    // 父路径
    const File = plus.android.newObject("java.io.File", `${FilePath}`); // 导入包并new这个类
    const ParentFile = plus.android.invoke(File, "getParentFile");
    // const ParentPath = plus.android.invoke(ParentFile, "getAbsolutePath");
    const ParentName = plus.android.invoke(ParentFile, "getName");
            
    const item = { filePath: FilePath, dataAdded: DateAdded, }
    // 判断 相册是否存在 ? 添加 item : 添加相册
    if(ParentName in list) list[ParentName].push(item);
    else list[ParentName] = [item];
  }
  Cursor.close(); // 关闭游标
  return list;
  // #endif
},

查询视频

视频缩略图会专门开一篇

/**
 * @method getVideoGather
 * @description 获取视频集合
 * @description https://blog.csdn.net/IrisJaneny/article/details/73807218
 * @description https://blog.csdn.net/LoneySmoke/article/details/108944485
 * @description https://www.jianshu.com/p/ca73161e5509
 * @description https://blog.csdn.net/weixin_44008788/article/details/123532073
 * @description https://blog.csdn.net/yann02/article/details/92844364
 * @description https://developer.aliyun.com/article/267936
 * @description https://blog.csdn.net/zhutoushifu/article/details/50667862
 * @description https://www.jianshu.com/p/f93b874043ae
 * @return {Objetc}
 * */
getVideoGather: function() {
  let list = {}
  const MediaStore = plus.android.importClass('android.provider.MediaStore');
  // const thumbColumns = [
  //   MediaStore.Video.Thumbnails.DATA,
  //   MediaStore.Video.Thumbnails.VIDEO_ID
  // ];
  const videoColumns = [
    MediaStore.Video.Media._ID, // 获取 id
    MediaStore.Video.Media.ALBUM, // 专辑
    MediaStore.Video.Media.ARTIST, // 艺术家姓名
    MediaStore.Video.Media.DATE_ADDED, // 视频文件创建时间
    MediaStore.Video.Media.DATE_MODIFIED, // 视频最后更改时间
    MediaStore.Video.Media.DISPLAY_NAME, // 视频文件名称
    MediaStore.Video.Media.TITLE, // 视频名
    MediaStore.Video.Media.DURATION, // 视频时长
    // MediaStore.Video.Media.WIDTH, // 视频宽
    // MediaStore.Video.Media.HEIGHT, // 视频搞、高
    // MediaStore.Video.Media.BITRATE, // 视频码率
    MediaStore.Video.Media.SIZE, // 视频时长
    MediaStore.Video.Media.DATA, // 视频保存路径
    MediaStore.Video.Media.MIME_TYPE, // 视频类型
  ];
  const Main = plus.android.runtimeMainActivity(); // 此处相当于 context
  const Resolver = Main.getContentResolver(); // 获取ContentResolver实例
  plus.android.importClass(Resolver);
  const cursor = Resolver.query(MediaStore.Video.Media.EXTERNAL_CONTENT_URI, videoColumns, null, null, null);
  plus.android.importClass(cursor);
  // 获得索引
  while(cursor !=null && cursor.moveToNext()){
    const _id = cursor.getString(cursor.getColumnIndexOrThrow(MediaStore.Video.Media._ID));
    const album = cursor.getString(cursor.getColumnIndexOrThrow(MediaStore.Video.Media.ALBUM));
    const artist = cursor.getString(cursor.getColumnIndexOrThrow(MediaStore.Video.Media.ARTIST));
    const dateAdded = cursor.getString(cursor.getColumnIndexOrThrow(MediaStore.Video.Media.DATE_ADDED));
    const displayName = cursor.getString(cursor.getColumnIndexOrThrow(MediaStore.Video.Media.DISPLAY_NAME));
    const title = cursor.getString(cursor.getColumnIndexOrThrow(MediaStore.Video.Media.TITLE));
    const duration = cursor.getString(cursor.getColumnIndexOrThrow(MediaStore.Video.Media.DURATION));
    const size = cursor.getString(cursor.getColumnIndexOrThrow(MediaStore.Video.Media.SIZE));
    const fileParh = cursor.getString(cursor.getColumnIndexOrThrow(MediaStore.Video.Media.DATA));
    const mimtType = cursor.getString(cursor.getColumnIndexOrThrow(MediaStore.Video.Media.MIME_TYPE));
    
    const item = { _id, album, artist, dateAdded, displayName, title, duration, size, fileParh, mimtType }
    
    // 判断 专辑是否存在与列表中 list.hasOwnProperty(album)
    if(album in list) list[album].push(item);
    else list[album] = [item];
  }
  console.log(list);
  cursor.close(); // 关闭游标
  return list;
},

获取音乐

/**
 * @method getAudioGather
 * @description 获取本机所有音频
 * @return {Object}
 * */
getAudioGather: function() {
  let list = {};
  const MediaStore = plus.android.importClass('android.provider.MediaStore');
  const audioColumns = [
    MediaStore.Audio.Media._ID,// 歌曲ID
    MediaStore.Audio.Media.ARTIST,// 歌曲的歌手名
    MediaStore.Audio.Media.ALBUM,// 歌曲的唱片集
    MediaStore.Audio.Media.TITLE,// 歌曲标题
    MediaStore.Audio.Media.DISPLAY_NAME,// 歌曲名称
    MediaStore.Audio.Media.MIME_TYPE,// 歌曲的播放格式
    MediaStore.Audio.Media.IS_RINGTONE,//
    MediaStore.Audio.Media.IS_ALARM,// 歌曲的专辑名
    MediaStore.Audio.Media.IS_MUSIC,//
    MediaStore.Audio.Media.IS_NOTIFICATION,//
    MediaStore.Audio.Media.DATA,// 歌曲文件的路径
    MediaStore.Audio.Media.DURATION // 歌曲的总播放时长
  ];
  const Main = plus.android.runtimeMainActivity(); // 此处相当于 context
  const Resolver = Main.getContentResolver(); // 获取ContentResolver实例
  plus.android.importClass(Resolver);
  const cursor = Resolver.query(MediaStore.Audio.Media.EXTERNAL_CONTENT_URI, audioColumns, null, null, null);
  plus.android.importClass(cursor);
  
  while(cursor !=null && cursor.moveToNext()) {
    const _id = cursor.getString(cursor.getColumnIndexOrThrow(MediaStore.Audio.Media._ID));
    const artist = cursor.getString(cursor.getColumnIndexOrThrow(MediaStore.Audio.Media.ARTIST));
    const album = cursor.getString(cursor.getColumnIndexOrThrow(MediaStore.Audio.Media.ALBUM));
    const title = cursor.getString(cursor.getColumnIndexOrThrow(MediaStore.Audio.Media.TITLE));
    const displayName = cursor.getString(cursor.getColumnIndexOrThrow(MediaStore.Audio.Media.DISPLAY_NAME));
    const mimtType = cursor.getString(cursor.getColumnIndexOrThrow(MediaStore.Audio.Media.MIME_TYPE));
    const isRingtone = cursor.getString(cursor.getColumnIndexOrThrow(MediaStore.Audio.Media.IS_RINGTONE));
    const isAlarm = cursor.getString(cursor.getColumnIndexOrThrow(MediaStore.Audio.Media.IS_ALARM));
    const isMusic = cursor.getString(cursor.getColumnIndexOrThrow(MediaStore.Audio.Media.IS_MUSIC));
    const isNotification = cursor.getString(cursor.getColumnIndexOrThrow(MediaStore.Audio.Media.IS_NOTIFICATION));
    const fileParh = cursor.getString(cursor.getColumnIndexOrThrow(MediaStore.Audio.Media.DATA));
    const duration = cursor.getString(cursor.getColumnIndexOrThrow(MediaStore.Audio.Media.DURATION));
    
    const item = { _id, artist, album, title, displayName, mimtType, isRingtone, isAlarm, isMusic, isNotification, fileParh, duration};
    album = album == "<unknown>" ? "default" : album;
    if(album in list) list[album].push(item);
    else list[album] = [item];
  }
  cursor.close();
  return list;
},

获取其它文件

/**
* @method getOtherFileGather
* @return {Object}
* @description 获取其它文件
* TODO 需要优化现在是获取所有的文件包括文件夹
* */
getOtherFileGather: function(type) {
let list = [];
const MediaStore = plus.android.importClass('android.provider.MediaStore');
const otherColumns = [
  MediaStore.Files.FileColumns._ID, // id
  MediaStore.Files.FileColumns.DATA, // 路径
  MediaStore.Files.FileColumns.SIZE, // 大小
  MediaStore.Files.FileColumns.DATE_MODIFIED, //
  MediaStore.Files.FileColumns.MIME_TYPE, // 文件类型
  MediaStore.Files.FileColumns.TITLE, // 文件标题
  MediaStore.Files.FileColumns.DATE_MODIFIED, // 
  MediaStore.Files.FileColumns.DATE_ADDED,
];
const selection = MediaStore.Files.FileColumns.MIME_TYPE + '= ?'
const selectionArgs = ["text/plain"];

const Main = plus.android.runtimeMainActivity(); // 此处相当于 context
const Resolver = Main.getContentResolver(); // 获取ContentResolver实例
plus.android.importClass(Resolver);
const url = MediaStore.Files.getContentUri("external");
// TODO 需要优化现在是获取所有的文件包括文件夹
// MediaStore.Files.FileColumns.DATA + " LIKE '%" + keyword + "%'"
// const cursor = Resolver.query(url, otherColumns, selection, selectionArgs, MediaStore.Files.FileColumns.DATE_ADDED + " DESC");
const cursor = Resolver.query(url, otherColumns, MediaStore.Files.FileColumns.DATA + " LIKE '%" + zip ?? '.zip' + "%'", null, null);
plus.android.importClass(cursor);
while(cursor !=null && cursor.moveToNext()) {  
  const _id = cursor.getString(cursor.getColumnIndexOrThrow(MediaStore.Files.FileColumns._ID));
  const filePath = cursor.getString(cursor.getColumnIndexOrThrow(MediaStore.Files.FileColumns.DATA));
  const size = cursor.getString(cursor.getColumnIndexOrThrow(MediaStore.Files.FileColumns.SIZE));
  const dateModified = cursor.getString(cursor.getColumnIndexOrThrow(MediaStore.Files.FileColumns.DATE_MODIFIED));
  const mimtType = cursor.getString(cursor.getColumnIndexOrThrow(MediaStore.Files.FileColumns.MIME_TYPE));
  const title = cursor.getString(cursor.getColumnIndexOrThrow(MediaStore.Files.FileColumns.TITLE));
  list.push({ _id, filePath, size, dateModified, mimtType, title, })
}
cursor.close();
return list;
},

参考文档

  1. 关于MediaStore.Files
  2. Android之MediaStore使用 (查找 音乐/视频/文档/自定义类型文件.apk .zip 等)
  3. Android系统详解之获取图片和视频的缩略图
  4. Android视频图片缩略图的获取
  5. Android查询手机媒体库
  6. Android MediaStore的基本使用
  7. Android如何高效地进行文件查询——MediaStore
  8. Android视频缩略图(二)
  9. Android 获取视频缩略图(获取视频每帧数据)的优化方案
  10. 【Android】缩略图Thumbnails
  11. Build.VERSION.SDK_INT < Build.VERSION_CODES.O的含义
  12. Android如何获取视频首帧图片
  13. Android如何高效地进行文件查询——MediaStore
  14. MediaStore.Video.Thumbnails
  15. Android 获取多媒体文件的缩略图
posted @ 2023-01-04 22:47  tsuru  阅读(638)  评论(0编辑  收藏  举报