关于 uniapp 获取媒体文件
- 什么是 MediaStore
- MediaStore 内嵌类和常用查询字段
- 查询图片
- 查询视频
- 查询音乐
- 获取其它文件
- 参考
什么是 MediaStore
- MediaStore 是 Android 中的多媒体数据库,Android 中的多媒体数据都记录在在这里面
- Android 对所有的多媒体数据库接口进行了封装,直接用 ContentResolver 调用接口去进行数据库的操作就可以了
- 注:一般用于需要本地图片、视频、音乐的元数据查询
- 打开 /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;
},
参考文档
- 关于MediaStore.Files
- Android之MediaStore使用 (查找 音乐/视频/文档/自定义类型文件.apk .zip 等)
- Android系统详解之获取图片和视频的缩略图
- Android视频图片缩略图的获取
- Android查询手机媒体库
- Android MediaStore的基本使用
- Android如何高效地进行文件查询——MediaStore
- Android视频缩略图(二)
- Android 获取视频缩略图(获取视频每帧数据)的优化方案
- 【Android】缩略图Thumbnails
- Build.VERSION.SDK_INT < Build.VERSION_CODES.O的含义
- Android如何获取视频首帧图片
- Android如何高效地进行文件查询——MediaStore
- MediaStore.Video.Thumbnails
- Android 获取多媒体文件的缩略图