更新记录

1.0.21(2022-07-04)

1.更新Tim应用文件读取目录
2.解决android11及以上版本,在申请分区存储权限后,回到应用时,切换标签崩溃问题
3.增加copyIfNeed参数,当copyIfNeed为true时,在Android10及以下版本的设备,选择公共目录非媒体文件时,会把这些文件复制到应用沙盒目录,再返回新的沙盒目录的文件路径,用以解决,选择公共目录非媒体文件时,非沙盒文件路径上传失败问题

1.0.20(2022-05-17)

1.增加用户无操作时(如直接返回待操作),返回uniapp结果判断
2.修复部分机型(如vivo等),返回时崩溃问题

1.0.19(2022-04-11)

1.解决部分机型Android11+系统中QQ文件读取不到问题
2.优化用户体验,内部存储中记录上次滚动位置

查看更多

平台兼容性

Android Android CPU类型 iOS
适用版本区间:4.4 - 12.0 armeabi-v7a:未测试,arm64-v8a:未测试,x86:未测试 ×

原生插件通用使用流程:

  1. 购买插件,选择该插件绑定的项目。
  2. 在HBuilderX里找到项目,在manifest的app原生插件配置中勾选模块,如需要填写参数则参考插件作者的文档添加。
  3. 根据插件作者的提供的文档开发代码,在代码中引用插件,调用插件功能。
  4. 打包自定义基座,选择插件,得到自定义基座,然后运行时选择自定义基座,进行log输出测试。
  5. 开发完毕后正式云打包

付费原生插件目前不支持离线打包。
Android 离线打包原生插件另见文档 https://nativesupport.dcloud.net.cn/NativePlugin/offline_package/android
iOS 离线打包原生插件另见文档 https://nativesupport.dcloud.net.cn/NativePlugin/offline_package/ios

注意事项:使用HBuilderX2.7.14以下版本,如果同一插件且同一appid下购买并绑定了多个包名,提交云打包界面提示包名绑定不一致时,需要在HBuilderX项目中manifest.json->“App原生插件配置”->”云端插件“列表中删除该插件重新选择


K-ChooseFilesModule 简介

文件选择android原生插件,支持多选单选,简单样式选择等。支持如下:

  1. 支持多选单选
  2. 根据文件类型显示相应图标(如视频类的文件,会用视频类图标显示),若为图片类型,会显示图片缩略图
  3. 常用文件选择,如读取微信、QQ、Tim、钉钉等常用应用传输的文件
  4. 文件会显示大小及最后修改时间,并根据修改时间降序排列
  5. 支持从内部存储中选择文件
  6. 支持设置筛选文件类型
  7. 支持筛选出大于或小于某大小的文件们
  8. 支持设置可选限制文件大小
  9. 支持返回的文件带名字,后缀名,大小等
  10. 将文件的操作方法进行了封装并开放,不依赖UI,不依赖用户选择,用户可根据自己的需要调用封装的方法,或自定义ui
  11. 支持Android10及以上设备,公共目录非媒体文件拷贝到应用沙盒目录,用以解决文件上传失败问题
  12. 支持Android11及以上设备,分区存储权限申请

使用说明

本插件现提供三个方法chooseFileAction(带可以选择文件的UI,如截图中所示)、getFilesWithoutUiAsync(不带UI的获取内部存储中某个目录,某些类型文件的异步方法)、getExternalStorageDirectory(获取android手机内部存储绝对路径,这个方法主要为getFilesWithoutUiAsync方法使用)。

1. 调用chooseFileAction方法介绍,以下代码只是常用举例,具体可根据自己的需求,参考传参介绍,参数自由组合来满足自己的需求:
/**
 * 多选;允许选择最大数量文件30个;选择文件,不允许选择文件夹;搜索全部类型的文件;右下角按钮为“发送”
 */
chooseFileDefault() {
    const plugin = uni.requireNativePlugin('K-ChooseFilesModule');
    plugin.chooseFileAction({},
    result = >{
        console.log(JSON.stringify(result));
        this.content = JSON.stringify(result);
    });
},
/**
 * 单选,只允许选择1个文件;选择文件,不允许选择文件夹;搜索全部类型的文件;右下角按钮为“发送”
 */
chooseFileOnlyOne() {
    const plugin = uni.requireNativePlugin('K-ChooseFilesModule');
    plugin.chooseFileAction({
        maxNum: 1
    },
    result = >{
        console.log(JSON.stringify(result));
        this.content = JSON.stringify(result);
    });
},
/**
 * 多选;允许选择最大数量文件30个;选择文件,不允许选择文件夹;筛选文件类型为'png','jpg','txt', 'doc'的文件;右下角按钮为“发送”
 */
chooseFileFileTypes() {
    const plugin = uni.requireNativePlugin('K-ChooseFilesModule');
    plugin.chooseFileAction({
        fileTypes: ['png', 'jpg', 'txt', 'doc']
    },
    result = >{
        console.log(JSON.stringify(result));
        this.content = JSON.stringify(result);
    });
},
/**
 * maxSize参数举例,限制所选文件的总大小不能超过20M,否则不能再继续向下选择,并有友好提示
 */
chooseFileMaxSize() {
    const plugin = uni.requireNativePlugin("K-ChooseFilesModule");
    plugin.chooseFileAction({
        maxSize: 20 * 1024 * 1024
    }, result => {
        console.log(JSON.stringify(result));
        this.content = JSON.stringify(result);
    });
},
/**
* filterIsGreater、filterFileSize参数举例,筛选出大小大于等于10M的文件(即留下大小大于等于10M的文件)
*/
chooseFileFilterGreater() {
    const plugin = uni.requireNativePlugin("K-ChooseFilesModule");
    plugin.chooseFileAction({
        filterIsGreater: true,
        filterFileSize: 10 * 1024 * 1024
    }, result => {
        console.log(JSON.stringify(result));
        this.content = JSON.stringify(result);
    });
},
/**
* isNeedDetail参数举例,需要返回所选文件的详细信息,包括路径,名字,大小,后缀名,时间等
*/
chooseFileisNeedDetail() {
    const plugin = uni.requireNativePlugin("K-ChooseFilesModule");
    plugin.chooseFileAction({
        isNeedDetail: true
    }, result => {
        console.log(JSON.stringify(result));
        this.content = JSON.stringify(result);
    });
},
/**
 * 多选;允许选择最大数量文件30个;选择文件,不允许选择文件夹;搜索全部类型的文件;右下角按钮为“我是自定义按钮”
 */
chooseFileBtnTxt() {
    const plugin = uni.requireNativePlugin('K-ChooseFilesModule');
    plugin.chooseFileAction({
        btnText: '我是自定义按钮'
    },
    result = >{
        console.log(JSON.stringify(result));
        this.content = JSON.stringify(result);
    });
},
/**
 * 读取钉钉应用中的文件,显示钉钉标签页
 */
chooseFileDingTalk() {
    const plugin = uni.requireNativePlugin('K-ChooseFilesModule');
    plugin.chooseFileAction({extraApps:['dingtalk']},
    result = >{
        console.log(JSON.stringify(result));
        this.content = JSON.stringify(result);
    });
}
/**
 * 读取QQ浏览器中的文件,显示QQ浏览器标签页,微信QQ等软件中,通过QQ浏览器另存为的文件都会显示在这里
 */
chooseFileQqbrowser() {
    const plugin = uni.requireNativePlugin('K-ChooseFilesModule');
    plugin.chooseFileAction({extraApps:['qqbrowser']},
    result = >{
        console.log(JSON.stringify(result));
        this.content = JSON.stringify(result);
    });
}
chooseFileAction方法,传参介绍如下:
参数 类型 默认值 说明
copyIfNeed Boolean false 用以解决,Android10及以上设备,当选择非媒体文件时,上传会失败问题;
原理,当此参数为true时,会把公共目录下的非媒体文件拷贝到应用沙盒目录下,并返回沙盒目录下的文件路径,当为false时,文件路径不变,为照顾以前老用户,此参数默认false
maxNum Integer 30 允许选择的最大文件数,默认30;
若想单选效果,请设置为1
maxSize Integer 默认不传此参数,无限制 允许选择文件的最大大小;
设置此参数后,若选择的文件总大小超过设置的值后,不再允许选择,且有友好提示;
不传此参数,默认无此限制;
单位比特(B),如20MB,可设置20 * 1024 * 1024
chooseMode Boolean 不传此参数,默认true 设置文件夹选择模式;
不传此参数或传true(默认)为选择文件,false为选择文件夹
fileTypes Array 全部文件类型 筛选文件类型(文件后缀名);
不传此参数,默认全部,样例数据:let filters = ['txt', 'doc'];
#### filterIsGreater Boolean 不传此参数,默认true 指定过滤方式;
true(默认)为留下大于等于指定大小文件,false留下小于等于指定大小文件,与filterFileSize配合使用;
举例想要留下小于等于20MB的所有文件,filterIsGreater设置为fasle,filterFileSize设置为20 * 1024 * 1024;
当filterIsGreater与filterFileSize都不传时,则表示对文件大小没有限制(即留下大于等于0的所有文件)
filterFileSize Integer 不传此参数,默认0 指定过滤文件大小;
单位比特(B),与filterIsGreater参数配合使用;使用请参考filterIsGreater说明
isNeedDetail Boolean 不传此参数,默认false 是否需要返回文件的详细,如文件名字,最后修改时间,后缀名,文件大小等详细信息;
如果需要返回,设置为true,返回参数中会有dataDetail字段,具体参看返回参数说明
extraApps Array 额外支持的应用,目前这里只有QQ浏览器(qqbrowser)、钉钉(dingtalk),其它的应用如飞书等以后会支持 为照顾老用户,默认是不显示QQ浏览器/钉钉等应用的,如果想读取QQ浏览器、钉钉等软件,可在这里设置,样例数据:['qqbrowser','dingtalk'];这里注意,微信QQ等软件中,通过QQ浏览器另存为的文件都会在"QQ浏览器"显示
btnText String "发送" 右下方"发送"按钮文字
chooseFileAction方法,返回参数说明:
{
"code":"0",
"msg":"success",
"data":[//只返回所选文件的绝对路径
    "绝对路径一",
    "绝对路径二"
    ],
"dataDetail":[//当传参isNeedDetail为true时,才会有此字段,否则没有dataDetail字段返回
    {
            "suffix":"mp4",//文件后缀名
            "name":"wx_camera_1613445581666.mp4",//文件名字
            "size":3680434,//文件大小,单位比特(B)
            "lastModifiedTime":1613445581000,//最后修改时间
            "path":"/storage/emulated/0/Pictures/WeiXin/wx_camera_1613445581666.mp4"//绝对路径
    },
    {
            "suffix":"mp4",
            "name":"wx_camera_1613445581666.mp4",
            "size":3680434,
            "lastModifiedTime":1613445581000,
            "path":"/storage/emulated/0/Pictures/WeiXin/wx_camera_1613445581666.mp4"
    }
    ]
}

2. 方法getFilesWithoutUiAsync,不带UI,异步获取内存存储下,某个目录,某些类型文件;本方法是在完成带UI功能的过程中,对文件操作的封装,用户可根据以下方法自定义UI了,或不需要ui,后台异步获取自己所需文件,调用举例如下:

/**
 * 获取内部存储绝对路径,异步方法,方便getFilesWithoutUiAsync方法调用
 * 大部分android手机外部存储路径为“/storage/emulated/0”,但也有可能对于深度定制手机,可能不是这个,所以把这个开放出来
 */
getExternalStorageDirectory() {
    const plugin = uni.requireNativePlugin('K-ChooseFilesModule');
    plugin.getExternalStorageDirectory({},
    result = >{
        console.log(result);
        this.content = result;
    });
},
/**
 * 获取手机所有文件,即默认所有参数不传
 * 异步方法,因获取存储中所有文件,比较耗时,请耐心等待
 */
getFilesWithoutUiAsync() {
    uni.showLoading({
        title: '请稍后...'
    });
    const plugin = uni.requireNativePlugin('K-ChooseFilesModule');
    plugin.getFilesWithoutUiAsync({},
    result = >{
        uni.hideLoading();
        //这里loading可能会先消失,然后待一段时间才会在ui上显示,原因是数据大多,ui渲染需要时间,这里用户可根据自己情况自行优化,这里建议拿到所有数据后,先渲染前10条,再继续向下渲染
        this.content = JSON.stringify(result);
    });
},
/**
 * 传参示例,获取手机内部存储DCIM文件夹下的所有图片文件
 * path: 内部存储中某个文件夹的绝对路径,默认不传此参数为,内部存储中所有文件
 * fileTypes:筛选文件的类型(文件的后缀名),默认不传此参数,为所有文件类型都搜索出来;这里列举出两个样例:
 * 所有图片:let arrPic = ["jpg", "png", "jpeg", "bmp", "tif", "gif", "pcx", "tga", "exif", "fpx", "svg", "psd"];
   所有视频:let arrVideo = ["mp4", "rm", "rmvb", "mpeg", "mov", "mtv", "wmv", "avi", "3gp", "amv", "dmv", "flv", "mkv","mpg","mk", "m4v"];
 * isNeedRareFiles:是否筛选出一些少见的文件,如可能会有一些系统文件,这类文件不带后缀名,不常见的文件,默认不传此参数,不搜索出这类文件,如果想要这些文件,请设置为true
 */
getFilesWithoutUiAsyncPicInDCIM() {
    uni.showLoading({
        title: '请稍后...'
    }) ;
    const plugin = uni.requireNativePlugin('K-ChooseFilesModule');
    //主线程同步方法
    plugin.getExternalStorageDirectory({},
    result = >{
        let pathSdcard = result;
        //所有图片
        let arrPic = ["jpg", "png", "jpeg", "bmp", "tif", "gif", "pcx", "tga", "exif", "fpx", "svg", "psd"];
        //所有视频
        let arrVideo = ["mp4", "rm", "rmvb", "mpeg", "mov", "mtv", "wmv", "avi", "3gp", "amv", "dmv", "flv", "mkv", "mpg", "mk", "m4v"];
        plugin.getFilesWithoutUiAsync({
            path: pathSdcard + '/DCIM',
            fileTypes: arrPic
        },
        result = >{
            uni.hideLoading();
            console.log(JSON.stringify(result));
            this.content = JSON.stringify(result);
        });
    });
},
/**
 * filterIsGreater、filterFileSize参数举例,筛选出大小大于等于300M的文件(即留下大小大于等于300M的文件)
 */
getFilesWithoutUiAsyncFilterGreater(){
    uni.showLoading({
        title: '请稍后...'
    })
    const plugin = uni.requireNativePlugin(config.chooseFileModule);
    plugin.getFilesWithoutUiAsync({filterIsGreater:true,filterFileSize:300*1024*1024}, result => {
        uni.hideLoading();
        console.log(JSON.stringify(result));
        //这里loading可能会先消失,然后待一段时间才会在ui上显示,原因是数据大多,ui渲染需要时间,这里用户可根据自己情况自行优化,这里建议拿到所有数据后,先渲染前10条,再继续向下渲染
        this.content = JSON.stringify(result);
    });
}
getFilesWithoutUiAsync方法,传参介绍如下:
参数 类型 默认值 说明
path String 不传此参数为手机所有文件 指定内部存储某个目录下的所有文件,用法示例,可参看[调用方法]中的代码示例
fileTypes Array 不传此参数为全部文件类型 筛选文件的类型(文件的后缀名);
默认不传此参数,为所有文件类型都搜索出来;
这里列举出两个样例:
所有图片:
let arrPic = ["jpg", "png", "jpeg", "bmp", "tif", "gif", "pcx", "tga", "exif", "fpx", "svg", "psd"];
所有视频:
let arrVideo = ["mp4", "rm", "rmvb", "mpeg", "mov", "mtv", "wmv", "avi", "3gp", "amv", "dmv", "flv", "mkv","mpg","mk", "m4v"];
filterIsGreater Boolean 不传此参数,默认true 指定过滤方式;
true(默认)为留下大于等于指定大小文件,false留下小于等于指定大小文件,与filterFileSize配合使用;
举例想要留下小于等于20MB的所有文件,filterIsGreater设置为fasle,filterFileSize设置为20*1024*1024;
当filterIsGreater与filterFileSize都不传时,则表示对文件大小没有限制(即留下大于等于0的所有文件)
filterFileSize Integer 不传此参数,默认0 指定过滤文件大小,单位比特(B),与filterIsGreater参数配合使用;
具体使用请参考filterIsGreater说明
isNeedRareFiles Boolean 不传此参数,不需要稀有文件 是否筛选出一些稀有少见的文件;
可能会有一些系统文件,这类文件不带后缀名,不常见的文件,默认不传此参数,不搜索出这类文件,如果想要这些文件,请设置为true
getFilesWithoutUiAsync方法,返回参数说明:
{
"code":"0",//"0"代表成功,非"0"代表失败,某是失败,失败原因会在msg中返回
"msg":"success",
"data":[
    {
        "suffix":"mp4",//文件后缀名
        "name":"wx_camera_1613445581666.mp4",//文件名字
        "size":3680434,//文件大小,单位比特(B)
        "lastModifiedTime":1613445581000,//最后修改时间
        "path":"/storage/emulated/0/Pictures/WeiXin/wx_camera_1613445581666.mp4"//绝对路径
    },
    {
        "suffix":"mp4",//文件后缀名
        "name":"wx_camera_1613445581666.mp4",//文件名字
        "size":3680434,//文件大小,单位比特(B)
        "lastModifiedTime":1613445581000,//最后修改时间
        "path":"/storage/emulated/0/Pictures/WeiXin/wx_camera_1613445581666.mp4"//绝对路径
    }
    ]
}

3.问题汇总:

(1). 关于微信中的一些文件没有问题,有两种解决文案(根据需求,选择其中一种文案即可):
a.通过设置extraApps参数,传参样例:extraApps: ['qqbrowser'],把QQ浏览器标签页显示出来,微信QQ等软件中,通过QQ浏览器另存为的文件都会显示在这个标签页中。
b.请用最新微信版本,在微信中,在相应的文件点击选择“保存到手机”后,再尝试进入插件选择;有的微信没有“保存到手机”选项,解决请参看文章 https://www.jianshu.com/p/0cbbd613bb8d

(2). 若返回的路径无法使用(如,在image组件中无法展示,uni.uploadFile无法识别到本路径),请在返回后的相关路径前加"file://"再尝试使用

4.Demo下载

您可下载Demo安装到手机上,参看一下效果,本Demo包括了作者开发的大部分插件,您可以进入相应插件模块查看效果,Demo中实现的效果只是常用举例且功能有限,而且并不及时更新,所以用户还是应以详细文档中的说明为准,参数自由组合实现想要的功能。Demo下载链接如下:
https://pan.baidu.com/s/1YMLAx21N2p5sirJqwkLJoA 提取码: awh9

5.联系方式:

(1)若有插件问题或需求,可以评论留言描述,或加本人QQ
我的QQ是:3516626205 (加好友麻烦备注:uni文件选择插件)
支持付费定制
(2)关于售后:
a.承诺bug类问题,终身免费维护
b.新功能新需求类,若两个小时能完成的小工作量功能,免费完善

本sdk的使用许可,详见HBuilder X使用许可协议

隐私、权限声明

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

<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" /> <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>

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

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

使用中有什么不明白的地方,就向插件作者提问吧~ 我要提问