更新记录

1.0.11(2026-06-09)

  1. iOS增加从cloud下载图片/视频接口UTSGetFiles.downloadFromCloud

1.0.10(2026-05-18)

  1. 增加鸿蒙支持

1.0.9(2025-11-23)

  1. 优化icloud视频逻辑
查看更多

平台兼容性

uni-app(3.7.9)

Vue2 Vue3 Chrome Safari app-vue app-nvue Android iOS 鸿蒙
- - 5.0
微信小程序 支付宝小程序 抖音小程序 百度小程序 快手小程序 京东小程序 鸿蒙元服务 QQ小程序 飞书小程序 小红书小程序 快应用-华为 快应用-联盟
- - - - - - - - - - - -

uni-app x(3.7.9)

Chrome Safari Android iOS 鸿蒙 微信小程序
- - 5.0 -

其他

多语言 暗黑模式 宽屏模式

读取本地相册图片视频音频,可自定义UI界面

  1. 获取相册图片
  2. 获取相册视频
  3. 获取音频文件

常用文件处理插件

  1. 文件预览https://ext.dcloud.net.cn/plugin?id=17167

    • 支持pdf/word/excel/ppt/图片,支持本地或在线文件
  2. 文件增删查改copy遍历https://ext.dcloud.net.cn/plugin?id=14130

    • 文件读写、copy、move、遍历文件夹、是否存在、删除、重命名......等等
  3. 读取常用文件目录(包含U盘)https://ext.dcloud.net.cn/plugin?id=15243

    • uniapp(_www、_doc、_download)
    • Android(数据目录、文件目录、缓存目录、环境environment目录、SDCard目录、外接U盘)
    • iOS(documentDirectory、temporaryDirectory、libraryDirectory、cachesDirectory)
    • 从U盘读取或保存文件
  4. 读取本地相册图片视频音频,可自定义UI界面-新版https://ext.dcloud.net.cn/plugin?id=18288

    • 获取相册图片、视频、音频文件
    • 常用于自定义相册UI

插件咨询或定制请点击上面"进入交流群"私聊作者

获取视频缩略图插件https://ext.dcloud.net.cn/plugin?name=wrs-uts-videocover

配置权限

android:


"<uses-permission android:name=\"android.permission.READ_EXTERNAL_STORAGE\"/>",
"<uses-permission android:name=\"android.permission.WRITE_EXTERNAL_STORAGE\"/>",

ios:


"NSPhotoLibraryUsageDescription" : "访问相册需要你的授权",
"NSPhotoLibraryAddUsageDescription" : "访问相册需要你的授权",

harmonyos:

    "requestPermissions": [
   {
        "name": 'ohos.permission.READ_IMAGEVIDEO',
        "reason": '$string:bt_reason',
        "usedScene": {
          "abilities": [
            "EntryAbility"
          ],
          "when": "always"
        }
      },
      {
        "name": 'ohos.permission.WRITE_IMAGEVIDEO',
        "reason": '$string:bt_reason',
        "usedScene": {
          "abilities": [
            "EntryAbility"
          ],
          "when": "always"
        }
      },
      {
        "name": 'ohos.permission.MEDIA_LOCATION',
        "reason": '$string:bt_reason',
        "usedScene": {
          "abilities": [
            "EntryAbility"
          ],
          "when": "always"
        }
      }
]

集成步骤

  1. 拷贝demo里的AndroidManifest.xml、Info.plist、harmony-configs文件到项目根目录
  2. 鸿蒙端权限ohos.permission.READ_IMAGEVIDEO和ohos.permission.WRITE_IMAGEVIDEO为受限权限,参考鸿蒙官方授权https://developer.huawei.com/consumer/cn/doc/harmonyos-guides/declare-permissions-in-acl
  3. 本页面右上角可以点击"使用HBuilderX导入示例项目"下载demo,导入demo的时候选vue3,插件支持vue2和vue3
  4. 插件详细集成步骤可以参考https://www.jianshu.com/p/c1615a7880a7
  5. 如需定制或增加功能请点击插件标题下方的"进入交流群"私聊作者

导入变量


import {
    UTSGetFiles,
    requestPermissionsFromUser
} from "@/uni_modules/wrs-uts-getfiles"

获取相册图片数据


var params = {}
params.page = 1
params.pageSize = 100
switch (uni.getSystemInfoSync().platform) {
    case 'android': {
        if (this.startTime && this.endTime) {
            var start_time = this.getTimeStamp(this.startTime)
            var end_time = this.getTimeStamp(this.endTime)

            params.projection = ["_data"] // 要返回的属性数组
            // params.selection = "date_added >= " + start_time + " and date_added <= " + end_time
            // params.selection =
            //  "date_added >= ? and date_added <= ? and _data LIKE ?" // 筛选条件,时间传的是时间戳,精确到秒,参数不传到话会返回所有图片数据
            // params.selectionArgs = [start_time + "", end_time + "", "%aweme%"] // 筛选条件里?代表的值
            params.selection =
                "date_added >= ? and date_added <= ?" // 筛选条件,时间传的是时间戳,精确到秒,参数不传到话会返回所有图片数据
            params.selectionArgs = [start_time + "", end_time + ""] // 筛选条件里?代表的值
            params.sortOrder = "date_added DESC" // 排序
        }
    }
    break;
    case 'ios': {
        // this.startTime = "2025-11-22 00:00:00"
        // this.endTime = "2025-11-22 23:59:59"
        if (this.startTime && this.endTime) {
            var start_time = this.getTimeStamp(this.startTime)
            var end_time = this.getTimeStamp(this.endTime)
            params.predicate = {
                format: "creationDate >= %@ and creationDate <= %@",
                argumentArray: [{
                        type: "time", // 参数类型
                        value: start_time // 时间格式:yyyy-MM-dd HH:mm:ss
                    },
                    {
                        type: "time",
                        value: end_time
                    }
                ]
            }
            params.sortDescriptors = [ // 排序
                {
                    key: "creationDate",
                    ascending: false
                }
            ]
        }
        // params.sortDescriptors = [ // 排序
        //  {
        //      key: "creationDate",
        //      ascending: false
        //  }
        // ]
        params.isNetworkAccessAllowed = true // 当图片在iCloud时,是否从上面下载
        params.livePhoto = true // 是否需要返回实况图视频
    }
    break;
    case 'harmonyos': {
        // display_name、date_added、date_modified、duration、is_favorite、title
        params.orderByAsc = "date_added"

        // params.orderByDesc = ""
    }
    break;
}

console.log("params:" + JSON.stringify(params))
UTSGetFiles.getPhotos(params, (resp) => {
    console.log("getPhotos resp:" + JSON.stringify(resp))
    this.imageArray.length = 0
    this.imageArray = []
    let fileArray = resp.fileArray
    if (fileArray && fileArray.length > 0) {
        this.imageArray.length = 0
        this.imageArray = []
        for (let i = 0; i < fileArray.length; i++) {
            let model = fileArray[i]
            switch (uni.getSystemInfoSync().platform) {
                // android
                case 'android': {
                    let _data = model._data
                    this.imageArray.push({
                        src: "file://" + _data // image显示本地图片需要使用file协议
                    })
                }
                break;
                case "ios": {
                    let path = model.path
                    if (!path) { // 当图片在icloud下载失败没在本地时,取displaySizeImage(缩略图)
                        path = model.displaySizeImage
                    }
                    this.imageArray.push({
                        src: "file://" + path // image显示本地图片需要使用file协议
                    })
                }
                break;
                case "harmonyos": {
                    let path = model.path
                    this.imageArray.push({
                        src: "file://" + path // image显示本地图片需要使用file协议
                    })
                }
                break;
                default:
                    break;
            }

        }
    }
    // console.log(JSON.stringify(this.imageArray))
})

    // android图片模型
    // {
    //  "is_pending": 0,
    //  "primary_directory": "Pictures",
    //  "relative_path": "Pictures/WeiXin/",
    //  "is_trashed": 0,
    //  "group_id": 1828545592,
    //  "height": 1920,
    //  "date_modified": 1692360447,
    //  "width": 1080,
    //  "date_added": 1692360446,
    //  "_size": 1104141,
    //  "secondary_directory": "WeiXin",
    //  "title": "wx_camera_1692360446825",
    //  "_id": 2906,
    //  "volume_name": "external_primary",
    //  "_display_name": "wx_camera_1692360446825.jpg",
    //  "bucket_display_name": "WeiXin",
    //  "is_drm": 0,
    //  "bucket_id": "-643270046",
    //  "mime_type": "image/jpeg",
    //  "owner_package_name": "com.tencent.mm",
    //  "_data": "/storage/emulated/0/Pictures/WeiXin/wx_camera_1692360446825.jpg"
    // }

    // ios模型
 // {
 //            "pixelWidth": 3264, 
 //            "isHidden": false, 
 //            "size": 2006251, 
 //            "localIdentifier": "3C8D97EF-7494-4C29-8296-398632A71D4F/L0/001", 
 //            "pixelHeight": 2448, 
 //            "isFavorite": false, 
 //            "duration": 0, 
 //            "mediaType": 1, 
 //            "modificationDate": 1646887251.624751, 
 //            "creationDate": 1394025729.167, 
 //            "path": "/var/mobile/Media/DCIM/100APPLE/IMG_0044.JPG",
 //              "livePhoto": "/var/xxxx/xxx.mov"
 //        }

获取视频文件


// params参数和返回模型参考【获取相册图片数据】的参数
var params = {}
params.page = 1
params.pageSize = 100
switch (uni.getSystemInfoSync().platform) {
    // android
    case 'android': {
        if (this.startTime && this.endTime) {
            var start_time = this.getTimeStamp(this.startTime)
            var end_time = this.getTimeStamp(this.endTime)

            params.projection = ["_data"] // 要返回的属性数组
            // params.selection = "date_added >= " + start_time + " and date_added <= " + end_time
            params.selection =
                "date_added >= ? and date_added <= ?" // 筛选条件,时间传的是时间戳,精确到秒,参数不传到话会返回所有图片数据
            params.selectionArgs = [start_time + "", end_time + ""] // 筛选条件里?代表的值
            params.sortOrder = "date_added DESC" // 排序
        }

    }
    break;
    case 'ios': {
        if (this.startTime && this.endTime) {
            var start_time = this.getTimeStamp(this.startTime)
            var end_time = this.getTimeStamp(this.endTime)
            params.predicate = {
                format: "creationDate >= %@ and creationDate <= %@",
                argumentArray: [{
                        type: "time", // 参数类型
                        value: start_time // 时间格式:yyyy-MM-dd HH:mm:ss
                    },
                    {
                        type: "time",
                        value: end_time
                    }
                ]

            }
            params.sortDescriptors = [ // 排序
                {
                    key: "creationDate",
                    ascending: false
                }
            ]
        }
    }
    break;
    case "harmonyos": {

    }
    break;
    default:
        break;
}

params = {
    "page": 1,
    "pageSize": 24,
    // "sortDescriptors": [{
    //  "key": "creationDate",
    //  "ascending": false
    // }]
}
// params.projection = ["_data"] // 要返回的属性数组

// params.sortOrder = "date_added DESC" // 排序
console.log("getVideos params:" + JSON.stringify(params))
UTSGetFiles.getVideos(params, (resp) => {
    console.log("getVideos resp:" + JSON.stringify(resp))
    this.videoArray.length = 0
    this.videoArray = []
    let fileArray = resp.fileArray
    if (fileArray && fileArray.length > 0) {
        this.videoArray.length = 0
        this.videoArray = []
        for (var i = 0; i < fileArray.length; i++) {
            let model = fileArray[i]
            switch (uni.getSystemInfoSync().platform) {
                // android
                case 'android': {
                    model.videoId = model._id + ""
                }
                break;
                case 'ios': {
                    model.videoId = model.localIdentifier + ""
                }
                break;
                case 'harmonyos': {

                }
                break;
                default:
                    break;
            }

            this.videoArray.push(model)
        }
    }
})

要显示视频缩略图的话需要使用组件(暂不支持鸿蒙),即:


<view v-for="(item, index) in videoArray" class="file">
    <wrs-image  :videoId="item.videoId" style="width: 50px; height: 50px; background-color: #eeeeee;"
        :mode="mode"></wrs-image>
</view>

videoId属性值得是Android数据模型的_id、iOS数据模型的localIdentifier,即:


if (this.isAndroid) {
    model.videoId = model._id + ""
} else {
    model.videoId = model.localIdentifier + ""
}

获取音频文件(暂不支持鸿蒙)


var params = {}
// params参数和返回模型参考【获取相册图片数据】的参数
UTSGetFiles.getAudios(params, (resp) => {
    var fileArray = resp.fileArray
    if (fileArray && fileArray.length > 0) {
        this.imageArray.length = 0
        this.imageArray = []
        for (var i = 0; i < fileArray.length; i++) {
            var model = fileArray[i]
            if(this.isAndroid) {
                var _data = model._data
                this.imageArray.push({
                    src: "file://" + _data // image显示本地图片需要使用file协议
                })
            } else {
                var path = model.path
                this.imageArray.push({
                    src: path // image显示本地图片需要使用file协议
                })
            }
        }
    }
    // console.log(JSON.stringify(resp))
})

获取访问相册权限(仅支持iOS)

如果要在页面上使用显示图片的话,页面需要用nvue


    UTSGetFiles.requestAuthorization((resp) => {
        // 0: PHAuthorizationStatusNotDetermined
        // 1: PHAuthorizationStatusRestricted
        // 2: PHAuthorizationStatusDenied
        // 3: PHAuthorizationStatusAuthorized
        // 4: PHAuthorizationStatusLimited API_AVAILABLE(ios(14))
        let status = resp.status

    console.log(JSON.stringify(resp))
})

返回的数据模型(如需更多字段***252797991)

ios:


{
    "fileArray": [{
        "pixelWidth": 1575,
        "isHidden": false,
        "localIdentifier": "D150757D-6B19-4998-9C25-3B5B4CC5E8DC/L0/001",
        "pixelHeight": 2100,
        "isFavorite": false,
        "duration": 0,
        "mediaType": 1,
        "path": "file:///var/mobile/Media/PhotoData/Mutations/DCIM/101APPLE/IMG_1027/Adjustments/FullSizeRender.jpg"
    }, {
        "pixelWidth": 1575,
        "isHidden": false,
        "localIdentifier": "23400FEE-0965-4479-9C1B-CD639CB122A6/L0/001",
        "pixelHeight": 2100,
        "isFavorite": false,
        "duration": 0,
        "mediaType": 1,
        "path": "file:///var/mobile/Media/PhotoData/Mutations/DCIM/101APPLE/IMG_1028/Adjustments/FullSizeRender.jpg"
    }, {
        "pixelWidth": 1575,
        "isHidden": false,
        "localIdentifier": "80DD4D31-4E01-4A43-A87D-FCD4D45F0110/L0/001",
        "pixelHeight": 2100,
        "isFavorite": false,
        "duration": 0,
        "mediaType": 1,
        "path": "file:///var/mobile/Media/PhotoData/Mutations/DCIM/101APPLE/IMG_1029/Adjustments/FullSizeRender.jpg"
    }, {
        "pixelWidth": 1575,
        "isHidden": false,
        "localIdentifier": "76FC3185-E34D-49E5-A283-372AD0B9172B/L0/001",
        "pixelHeight": 2100,
        "isFavorite": false,
        "duration": 0,
        "mediaType": 1,
        "path": "file:///var/mobile/Media/PhotoData/Mutations/DCIM/101APPLE/IMG_1030/Adjustments/FullSizeRender.jpg"
    }, {
        "pixelWidth": 1575,
        "isHidden": false,
        "localIdentifier": "B6334694-F4C4-4CEB-9AF8-0282D10DE45F/L0/001",
        "pixelHeight": 2100,
        "isFavorite": false,
        "duration": 0,
        "mediaType": 1,
        "path": "file:///var/mobile/Media/PhotoData/Mutations/DCIM/101APPLE/IMG_1031/Adjustments/FullSizeRender.jpg"
    }],
    "totalCount": 5
}

android:


{
    "fileArray": [{
        "is_pending": 0,
        "title": "IMG_20231214_102405_edit_1190978885987016",
        "primary_directory": "DCIM",
        "mime_type": "image/jpeg",
        "relative_path": "DCIM/Camera/",
        "is_drm": 0,
        "date_added": 1702520666,
        "is_trashed": 0,
        "group_id": 1023065387,
        "height": 3648,
        "date_modified": 1702520666,
        "width": 2736,
        "bucket_display_name": "Camera",
        "bucket_id": "-1739773001",
        "secondary_directory": "Camera",
        "_id": 6026,
        "description": "hdrpl",
        "volume_name": "external_primary",
        "_size": 2526131,
        "orientation": 0,
        "datetaken": 1713598594,
        "mini_thumb_magic": 0,
        "_display_name": "IMG_20231214_102405_edit_1190978885987016.jpg",
        "_data": "/storage/emulated/0/DCIM/Camera/IMG_20231214_102405_edit_1190978885987016.jpg"
    }, {
        "is_pending": 0,
        "title": "IMG_20231214_102339_edit_1190954225183894",
        "primary_directory": "DCIM",
        "mime_type": "image/jpeg",
        "relative_path": "DCIM/Camera/",
        "is_drm": 0,
        "date_added": 1702520641,
        "is_trashed": 0,
        "group_id": -467912425,
        "height": 3648,
        "date_modified": 1702520642,
        "width": 2736,
        "bucket_display_name": "Camera",
        "bucket_id": "-1739773001",
        "secondary_directory": "Camera",
        "_id": 6024,
        "description": "qrf",
        "volume_name": "external_primary",
        "_size": 2054439,
        "orientation": 0,
        "datetaken": 1713571550,
        "mini_thumb_magic": 0,
        "_display_name": "IMG_20231214_102339_edit_1190954225183894.jpg",
        "_data": "/storage/emulated/0/DCIM/Camera/IMG_20231214_102339_edit_1190954225183894.jpg"
    }],
    "totalCount": 5
}
  • 当ios端图片或视频文件在cloud时,可以调用下面接口从cloud下载下来,仅支持iOS

// 或者从cloud下载图片
let cloudParams = {}
cloudParams.localIdentifier = model.localIdentifier
cloudParams.mediaType = 1 // 媒体类型: 1:图片 2:视频
cloudParams.saveDir = getFilesDir()
UTSGetFiles.downloadFromCloud(cloudParams, (cloudResp) => {
    let cloudOpt = cloudResp.opt
    switch (cloudOpt) {
        case "": {
            let progress = cloudResp.progress
        }
        break;
        case "onFinish": {
            let filePath = cloudResp.filePath
            if (filePath) { // 下载成功
                model.filePath = filePath
            }
        }
        break;
        default:
            break;
    }
    console.log("downloadFromCloud resp:" + JSON.stringify(
        cloudResp))
})

如果觉得可以就点个👍吧,欢迎粉丝收藏,土豪打赏,您的关注就是我们创作的动力!

隐私、权限声明

1. 本插件需要申请的系统权限列表:

android: 读写权限 ios: 相册权限

2. 本插件采集的数据、发送的服务器地址、以及数据用途说明:

插件不采集任何数据

3. 本插件是否包含广告,如包含需详细说明广告表达方式、展示频率: