uniapp安卓文档选择器(pdf、doc/docx、txt)

最近有一个业务需求,需要增加一个简简单单的功能——上传pdf文件。我直接就是插件市场随便下载一个文件选择器。

实现了功能。我歪嘴一笑,心想这根本没难度好吧,又可以多摸一会鱼了。

摸鱼了一段时间之后,我更新了功能。客户有说了:王工、王工,就是那个上传的功能,能不能做成那种我点击去,不用我一个一个文件夹的去找这些文件啊,这样太麻烦了。

看到这个消息我内心一紧,由于没有在插件市场找到比较合适的插件,所以最终还是决定亲自写一下。

安卓文档选择器效果图

文件选择器代码

<template>
	<view class="file-outerBox" @touchmove.prevent v-if="isOpen">
		<u-navbar title="选择文件" @leftClick="leftClick" :safeAreaInsetTop="true" :placeholder='true' bgColor="#0b4ea5"
			style="color: #ffffff;" id="navHeight" leftIconColor="#ffffff" titleStyle="color:#ffffff">
		</u-navbar>
		<view class="file-address">
			<view class="root-box"  @click="backRoot">
				微信下载
				<image src="@/static/files/youzhixiangjiantou.png" mode="widthFix" class="to-img-box"></image>
			</view>
			<scroll-view :scroll-x="true" class="address-scroll">
				<view class="address-box" v-for="(item,index) in addressBar" >
					{{item.name}}
					<image src="@/static/files/youzhixiangjiantou.png" mode="widthFix" class="to-img-box"></image>
				</view>
			</scroll-view>
		</view>
		<view class="">
			<scroll-view :scroll-y="true" :style="{height: 'calc(100vh - ' +  (barHeight*2 + 280) + 'rpx)'}" @scrolltolower="scrolltolower">
				<view class="select-tips" v-if="inaccessible">
					<view style="line-height: 40rpx;">
						无法访问的文件夹
					</view>
					<view style="line-height: 40rpx;">
						建议前往安卓存储访问框架查看文件
					</view>
				</view>
				<!-- <view class="folder-box" v-for="item in folderArr" @click="toFolder(item)">
					<view class="folder-name-box">
						<image :src="folderImg" mode="widthFix" class="folder-img"></image>
						<view class="name-box">{{item.name}}</view>
					</view>
					<view>
						<image :src="enterImg" mode="widthFix" class="toFolder-img"></image>
					</view>
				</view> -->
				<view class="file-box" v-for="(item,index) in fileArr" @click="selectFile(index)">
					<view class="file-name-box">
						<image src="@/static/files/save.png" mode="widthFix" class="file-img" v-if="item.type == 'file'"></image>
						<image src="@/static/files/save.png" mode="widthFix" class="file-img" v-if="item.type == 'txt'"></image>
						<image src="@/static/files/save.png" mode="widthFix" class="file-img" v-if="item.type == 'doc'"></image>
						<image src="@/static/files/PDFwenjiantubiao.png" mode="widthFix" class="file-img" v-if="item.type == 'pdf'"></image>
						<view class="name-box">
							{{item.name}}
						</view>
					</view>
					<view>
						<image src="@/static/files/PDFwenjiantubiao_1.png" mode="widthFix" class="select-img" v-if="item.select"></image>
						<image src="@/static/files/PDFwenjiantubiao.png" mode="widthFix" class="select-img" v-else></image>
					</view>
				</view>
			</scroll-view>
		</view>
		<view class="">
			<button type="default" class="select-foot-btn" :style="btnStyle" @click="uploadBtn">{{btnText}}</button>
		</view>
	</view>
</template>

<script>
import http from '../../api/request.js'
const $http = http
/*
*	
* {property} 使用 v-model 绑定一个变量来控制组件的开启与关闭
* {property} navBgColor [String] 顶部标题栏背景色
* {property} folderImg [String] 文件夹的图片
* {property} backImg [String] 返回上一级图片
* {property} directionImg [String] 右指向箭头 
* {property} enterImg [String] 进入文件夹箭头
* {property} fileImg [String] 未知文件通用图标,当前仅可识别 pdf、doc/docx、txt
* {property} txtImg [String] txt文件图标
* {property} docImg [String] doc/docx文件图标
* {property} pdfImg [String] pdf文件图标 
* {property} selectedImg [String] 选中状态下的按钮图标
* {property} unselectedImg [String] 未选中状态下的按钮图标
* {property} titel [String] 标题文字,默认 '选择文件'
* {property} titelSize [String,Number] 标题文字大小,默认 36rpx
* {property} titelWeight [String,Number] 标题文字粗细,默认 600
* {property} titelColor [String] 标题文字颜色,默认 #373737
* {property} btnText [String] 底部按钮文字, 默认 '上传'
* {property} btnSize [String,Number] 底部按钮文字大小, 默认 36rpx
* {property} btnHeight [String,Number] 底部按钮高度, 默认 92rpx
* {property} btnBgColor [String] 底部按钮颜色, 默认 #6521e2
* {property} btnTextColor [String] 底部按钮文字颜色, 默认 #fff
* {property} filterArr [Array] 筛选文件类型,示例:['doc','PDF'],不区分大小写
*
* {event} confirm [Function] 点击上传按钮触发的回调事件,会返回选中文件的地址 event = [{name: name, url: path, sizeMB: sizeMb}]
*		name: 文件名  url: 文件地址  sizeMB: 文件大小,单位MB
*/
	
	export default {
		name:"nk-select-file",
		props:{
			value:{
				type: Boolean,
				default: false
			},
			backImg:{
				type: String,
				default: '@/static/files/fanhui.png'
			},
			directionImg:{
				type: String,
				default: '@/static/files/youzhixiangjiantou.png'
			},
			enterImg:{
				type: String,
				default: '@/static/files/dakai.png'
			},
			folderImg:{
				type: String,
				default: '@/static/files/wenjianjia.png'
			},
			fileImg:{
				type: String,
				default:  '@/static/files/save.png'
			},
			txtImg:{
				type: String,
				default: '@/static/files/pdf.png'
			},
			docImg:{
				type: String,
				default: '@/static/files/pdf.png'
			},
			pdfImg:{
				type: String,
				default: '@/static/files/PDFwenjiantubiao.png'
			},
			selectedImg:{
				type: String,
				default: '@/static/files/PDFwenjiantubiao_1.png'
			},
			unselectedImg:{
				type: String,
				default: '@/static/files/PDFwenjiantubiao.png'
			},
			titel:{
				type: String,
				default: '选择文件'
			},
			titelSize: {
				type: [String,Number],
				default: 36
			},
			titelWeight: {
				type: [String,Number],
				default: 600
			},
			titelColor: {
				type: String,
				default: '#373737'
			},
			btnText: {
				type: String,
				default: '上传'
			},
			btnSize: {
				type: [String,Number],
				default: 36
			},
			btnHeight: {
				type: [String,Number],
				default: 92
			},
			btnBgColor: {
				type: String,
				default: '#0b4ea5'
			},
			btnTextColor: {
				type: String,
				default: '#fff'
			},
			navBgColor: {
				type: String,
				default: '#fff'
			},
			filterArr: {
				type: Array,
				default () {
					return []
				}
			}
		},
		data() {
			return {
				barHeight: '', // 状态栏高度
				rootAddress: {}, // 根目录
				addressBar: [], // 地址栏记录栈
				folderArr: [], // 文件夹
				fileArr: [], // 文件
				selectArr:[], // 选中文件集合
				isExit: true, // 退出
				isOpen: false,
				inaccessible: false, // 无法访问提示
				titelStyle: {
					fontSize: this.titelSize + 'rpx',
					fontWeight: this.titelWeight,
					color: this.titelColor
				},
				btnStyle: {
					height: this.btnHeight + 'rpx',
					backgroundColor: this.btnBgColor,
					color: this.btnTextColor,
					fontSize: this.btnSize + 'rpx'
				},
				filterReg: '',
				index: 0,
				oldList: [],
			};
		},
		watch:{
			value(val){
				if(val){
					this.open();
				}else{
					this.close();
				}
			}
		},
		mounted() {
			if(Object.prototype.toString.call(this.filterArr) === '[object Array]' && this.filterArr.length > 0){
				let str = this.filterArr.join("|");
				this.filterReg = new RegExp(str,'i');
			}
		},
		methods:{
			leftClick() {
				uni.navigateBack()
			},
			// 滚动到底部
			scrolltolower(){
				this.pagination();
			},
			// 打开组件
			open(){
				this.isOpen = true;
				this.getBarHeight();
				this.fileArr = [];
				this.oldList = uni.getStorageSync("fileArr");
				this.pagination();
				
			},
			pagination(){
				
				let flieArrNum = this.fileArr.length;
				let oldListNum = this.oldList.length;
				if(flieArrNum == oldListNum){
					// console.log('已经加载完毕了')
					return 
				}
				if(flieArrNum >= 0 && oldListNum > flieArrNum && (oldListNum - flieArrNum) > 20  ){
					// console.log('执行到了这里')
					this.fileArr = this.fileArr.concat(this.oldList.slice(flieArrNum,flieArrNum+20))
				}
				if(flieArrNum >= 0 && oldListNum > flieArrNum && (oldListNum - flieArrNum) <= 20  ){
					// console.log('已经加载到头了')
					this.fileArr = this.fileArr.concat(this.oldList.slice(flieArrNum))
				}
				
				return
			},
			// 关闭组件
			close(){
				this.isOpen = false;
				this.rootAddress = {}; // 根目录
				this.addressBar = []; // 地址栏记录栈
				this.folderArr = [];
				this.fileArr = [];
				this.selectArr = []; // 选中文件集合
				this.$emit('input', false);
				// 放到下一个生命周期,因为双向绑定的value修改父组件状态需要时间,且是异步的
				this.$nextTick(() => {
					this.$emit('change', false);
				})
			},
			
			// 获取状态栏高度
			getBarHeight(){
				var self = this;
				uni.getSystemInfo({
					success(res) {
						self.barHeight = res.statusBarHeight;
					}
				})
			},
			// 进入文件夹
			toFolder(event){
				
				this.isExit = false; // 地址栈中存在新地址,重置退出状态
				// this.folderArr = [];
				// this.fileArr = [];
				this.addressBar.push(event)
				
				var files = plus.android.invoke(event.file,"listFiles");
				// console.log('查看点击文件夹事件')
				// if(files == null){
				// 	this.inaccessible = true;
				// }
				if(files){
					var len = files.length;
				}
				if(len > 0){
					for(let i = 0; i < len; i++){
						// console.log("执行了几次2",i)
						// 过滤隐藏文件
						if(!plus.android.invoke(files[i],"isHidden")){
							// 判断是文件还是文件夹
							if(plus.android.invoke(files[i],"isDirectory")){
								var folderName = plus.android.invoke(files[i],"getName")
								// 这里是默认查找手机微信下载文件夹里面的文件可以根据自己的需要选择需要扫码的文件夹
								if(folderName == 'WeiXin'){
									this.toFolder({name: folderName,file: files[i]});
								}
							}
							else{
								var fileName = plus.android.invoke(files[i],"getName")
								// lastModified
								var time = plus.android.invoke(files[i],"lastModified")
								if(this.filterArr.length > 0){
									if(fileName.search(this.filterReg) < 0){
										continue;
									}
								}
								if(fileName.search(/txt/i) > -1){
									// txt 文件
									this.fileArr.push({name: fileName,file: files[i],type: 'txt',select: false,createtime: time})
								}
								else if(fileName.search(/doc|docx/i) > -1){
									// doc/docx 文件
									this.fileArr.push({name: fileName,file: files[i],type: 'doc',select: false,createtime: time})
								}
								else if(fileName.search(/pdf/i) > -1){
									// pdf 文件
									this.fileArr.push({name: fileName,file: files[i],type: 'pdf',select: false,createtime: time})
								}
								else{
									// 其他文件
									this.fileArr.push({name: fileName,file: files[i],type: 'file',select: false,createtime: time})
								}
							}
						}
					}
				}
				
				// 排序,不区分大小写
				this.folderArr.sort(function(a,b){return a.file.__UUID__.toUpperCase() > b.file.__UUID__.toUpperCase() ? '1' : '-1'});
				this.fileArr.sort(function(a,b){return a.file.__UUID__.toUpperCase() > b.file.__UUID__.toUpperCase() ? '1' : '-1'});
			},
			
			// 返回根目录
			backRoot(){
				
			},
			
			// 选中文件
			selectFile(index){
				
				if(this.fileArr[index].select){
					// 取消选中
					this.$set(this.fileArr[index],'select',false);
					let name = this.fileArr[index].name;
					for(let i = 0; i < this.selectArr.length; i++){
						if(name == this.selectArr[i].name){
							this.selectArr.splice(i,1);
							break;
						}
					}
				}else{
					if(this.selectArr.length >= 6){
						uni.showToast({
							title:'最多选择6个附件',
							icon: 'none'
						})
						return
					}
					// 选中
					this.$set(this.fileArr[index],'select',true);
					
					// 读文件大小  
					var FileInputStream = plus.android.importClass("java.io.FileInputStream");  
					var fileSize = new FileInputStream(this.fileArr[index].file);  
					var size = fileSize.available(); 
					var sizeMb = size / 1048576;
					sizeMb = sizeMb.toFixed(4);
					
					// 获取文件的相对路径
					var Path = plus.android.invoke(this.fileArr[index].file,"getPath")
					this.selectArr.push({name: this.fileArr[index].name, url: Path, sizeMB: sizeMb})
				}
			},
			// 点击上传按钮
			uploadBtn(){
				// console.log("选中的pdf文件",this.selectArr)
				this.$emit("confirm",this.selectArr);
				this.close();
			},
		}
	}
</script>

<style lang="scss">
.file-outerBox{
	width: 100%;
	height: 100vh;
	position: fixed;
	top: 0;
	left: 0;
	right: 0;
	bottom: 0;
	z-index: 1070;
	padding-bottom: 40rpx;
	background-color: #fff;
	.file-titel{
		width: 100%;
		height: 80rpx;
		line-height: 80rpx;
		text-align: center;
		// background-color: #FFFFFF;
		padding: 0 32rpx;
		display: flex;
		align-items: center;
		justify-content: space-between;
		.file-nav-leftBox{
			width: 60rpx;
			height: 100%;
			display: flex;
			align-items: center;
			justify-content: center;
			.file-back-img{
				width: 36rpx;
			}
		}
		.file-nav-rightBox{
			width: 60rpx;
			height: 100%;
		}
	}
	.file-address{
		width: 100%;
		height: 60rpx;
		background-color: #FBFBFB;
		padding: 0 32rpx;
		display: flex;
		color: #373737;
		font-size: 24rpx;
		.address-scroll{
			width: calc(100% - 116rpx);
			white-space: nowrap;
			height: 100%;
			.address-box{
				height: 60rpx;
				line-height: 60rpx;
				display: inline-block;
				.to-img-box{
					width: 20rpx;
				}
			}
		}
		.root-box{
			width: 116rpx;
			height: 60rpx;
			line-height: 60rpx;
			display: inline-block;
			box-shadow: 10rpx 0 10rpx -10rpx rgba(8,8,8,0.3);
			.to-img-box{
				width: 20rpx;
			}
		}
	}
	.folder-box{
		height: 120rpx;
		display: flex;
		align-items: center;
		justify-content: space-between;
		margin: 0 32rpx;
		border-bottom: 1px solid #EEEEEE;
		.folder-name-box{
			width: 80%;
			display: flex;
			align-items: center;
			flex-wrap: wrap; 
			.folder-img{
				width: 72rpx;
				margin-right: 16rpx;
			}
			.name-box{
				width: calc(100% - 100rpx);
				overflow: hidden;
				word-wrap: break-word;
				text-overflow: ellipsis;
				display: -webkit-box;
				-webkit-line-clamp: 2;
				-webkit-box-orient: vertical;
			}
		}
		.toFolder-img{
			width: 28rpx;
		}
	}
	.select-tips{
		width: 100%;
		height: 160rpx;
		text-align: center;
		font-size: 32rpx;
		color: #888;
		padding-top: 60rpx;
	}
	.file-box{
		height: 120rpx;
		display: flex;
		align-items: center;
		justify-content: space-between;
		margin: 0 32rpx;
		border-bottom: 1px solid #EEEEEE;
		.file-name-box{
			width: 80%;
			display: flex;
			align-items: center;
			.file-img{
				width: 72rpx;
				margin-right: 16rpx;
			}
			// .type-file{
			// 	width: 60rpx;
			// 	margin-left: 10rpx;
			// }
			.name-box{
				width: calc(100% - 100rpx);
				overflow: hidden;
				word-wrap: break-word;
				text-overflow: ellipsis;
				display: -webkit-box;
				-webkit-line-clamp: 2;
				-webkit-box-orient: vertical;
			}
		}
		.select-img{
			width: 32rpx;
		}
	}
	.select-foot-btn{
		width: calc(100% - 64rpx);
		margin-top: 20rpx;
	}
}
</style>

文件选择器封装成组件

<template>
	<view class="" >
		<view class="" style="display: inline-block;position: relative;" v-for="(item,index) in fileList1" :key="index">
			<image src="../static/image/pdf.png" mode="widthFix" style="width: 220rpx;height: 220rpx;"
				 @click="opFile(item.fullurl)">
			</image>
			<view style="position: absolute;top: 0;right: 0;padding: 0rpx 0rpx 0rpx 4rpx;border-radius: 0rpx 0 0 50%;" v-if="deletable" @click="deletePic(index)">
				<uni-icons type="closeempty" size="18"  style="margin: 0;padding: 0;"></uni-icons>
			</view>
		</view>
		<image src="../static/image/photo.png" mode="widthFix" style="width: 220rpx;height: 220rpx;"
			@click="chengFile()"></image>
		<uni-select-file :filterArr="['pdf']" @confirm="confirmfile" v-model="show"></uni-select-file>
	</view>
</template>

<script>
import uniSelectFile from './uni-select-file.vue';
	export default {
		components:{
			uniSelectFile
		},
		props: {
			fileList1: {
				type: Array,
				default: () => {
					return []
				}
			},
			bgImage: {
				type: String,
				default: "2"
			},
			maxCount: {
				type: Number,
				default: 1
			},
			height: {
				type: Number,
				default: 106
			},
			width: {
				type: Number,
				default: 170
			},
			disabled: {
				type: Boolean,
				default: false
			},
			deletable: {
				type: Boolean,
				default: true
			},
			
		},
		data() {
			return {
				file: null,
				filelist: [],
				fileLists: [],
				show: false,
				serviceUrl: this.$http.baseUrl, // 文件上传服务器地址
			}
		},
		created() {

		},
		onLoad() {
			// 
		},
		onShow() {

		},
		methods: {
			// 打开文档
			opFile(url) {
				let fileUrl = this.serviceUrl + url;
				uni.showLoading({
					title: '加载中'
				});
				uni.downloadFile({
				  url: fileUrl,
				  success: function (res) {
				    var filePath = res.tempFilePath;
				    uni.openDocument({
				      filePath: filePath,
				      showMenu: true,
				      success: function (res) {
				        // console.log('打开文档成功');
						uni.hideLoading();
				      },
					  fail(err) {
						console.log("err",err)
					  	uni.showToast({
					  		title: err.errMsg,
					  		duration: 2000,
							icon:"none"
					  	});
					  }
				    });
				  }
				});
			},
			uploalfile(url){
				let userInfo = uni.getStorageSync("userinfo");
				return new Promise((resolve, reject) => {
					let a = uni.uploadFile({
						url: this.serviceUrl + '/api/Common/upload', // 文件上传地址
						filePath: url,
						name: 'file',
						formData: {
							token: userInfo.token
						},
						success: (res) => {
							let data = JSON.parse(res.data);
							if (data.code) {
								this.$emit('returnUrl', data.data);
							}
							setTimeout(() => {
								resolve({
									url: data.data.fullurl,
									fullurl: data.data.url
								})
							}, 500)
						},
					});
				})
			},
			async confirmfile(e) {
				
				let userInfo = uni.getStorageSync("userinfo")
				let that = this;
				uni.showLoading({
					title: '加载中'
				});
				// console.log('获取到的文件',e)
				if(e.length > 0){
					for(let i = 0; i < e.length ; i++){
						const result = await that.uploalfile('file://' + e[i].url)
						that.fileList1.push(result)
					}
				}
				
				uni.hideLoading();
				// console.log('现在执行的数据',that.fileList1)
				this.$emit('returnAllUrl', this.fileList1)
				
			},
			selectfile(e) {
				console.log(e);
				this.file = e.target.files[0];
				if (!this.file) {
					uni.showToast({
						title: ''
					})
					return
				}
				const uploadTask = uni.uploadFile({
					url: '',
					filePath: this.file,
					name: '',
					formData: {
						token
					},
					success(res) {
						console.log(res);
					},
					fail(err) {
						console.log(err)
					}
				});
				uploadTask.onProgressUpdate((res) => {
					console.log('上传进度' + res.progress);
				})
			},
			chengFile() {
				if(!this.deletable){
					return
				}
				this.show = true;
				let userInfo = uni.getStorageSync("userinfo")
			},
			// 点击事件
			clickPreview(e) {
				console.log('点击事件', e)
			},
			// 删除图片
			deletePic(index) {
				this.fileList1.splice(index, 1);
				// console.log('删除图片执行了')
				this.$emit('deleteUrl');
				this.$emit('returnAllUrl', this.fileList1)
			},
			// 新增文件
			async afterRead(event) {
				// 当设置 multiple 为 true 时, file 为数组格式,否则为对象格式
				let lists = [].concat(event.file)
				let fileListLen = this[`fileList${event.name}`].length
				lists.map((item) => {
					this[`fileList${event.name}`].push({
						...item,
						// status: 'uploading',
						// message: '上传中'
					})
				})
				for (let i = 0; i < lists.length; i++) {
					const result = await this.uploadFilePromise(lists[i].url)
					let item = this[`fileList${event.name}`][fileListLen]
					this[`fileList${event.name}`].splice(fileListLen, 1, Object.assign(item, {
						// status: 'success',
						// message: '',
						url: result.url,
						fullurl: result.fullurl
					}))
					fileListLen++
				}
				this.$emit('returnAllUrl', this.fileList1)
				// console.log('测试图片路径',this.fileList1)
			},
			uploadFilePromise(url) {
				let userInfo = uni.getStorageSync("userinfo")
				return new Promise((resolve, reject) => {
					let a = uni.uploadFile({
						url: this.serviceUrl + '/api/Common/upload', // 文件上传地址
						filePath: url,
						name: 'file',
						formData: {
							token: userInfo.token
						},
						success: (res) => {
							let data = JSON.parse(res.data);
							if (data.code) {
								this.$emit('returnUrl', data.data);
							}
							setTimeout(() => {
								resolve({
									url: data.data.fullurl,
									fullurl: data.data.url
								})
							}, 500)
						}
					});
				})
			},
			// 读取前函数
			beforeRead(e) {
				console.log('读取前函数', e)
			},

		}
	}
</script>

<style>
</style>

页面引用组件

获取手机下载文件方法因为是通过便利手机下载文件夹实现的,由于查找文件时间过长所以建议获取指定的下载文件夹或者获取文件方法直接在App.vue文件中使用。

获取手机下载文件方法

// 获取根目录
			getRootDirectory() {
				this.inaccessible = false;
				// 修改退出状态,以便在点击返回按钮时最后一层返回的是根目录,再点击一次才会退出
				this.isExit = false;
				this.addressBar = [];
				var environment = plus.android.importClass("android.os.Environment");
				environment.getExternalStorageState() === environment.MEDIA_MOUNTED;
				var sdRoot = environment.getExternalStorageDirectory();
				var rootName = plus.android.invoke(sdRoot, "getName");
				this.rootAddress = {
					name: rootName,
					file: sdRoot,
				};
				var files = plus.android.invoke(sdRoot, "listFiles");
				if (!(Object.prototype.toString.call(files) === '[object Array]')) {
					uni.showToast({
						icon: 'none',
						title: '请在权限管理中授权文件和文档访问!',
						duration: 2000,
						success() {
							setTimeout(() => {
								uni.openAppAuthorizeSetting({
									success(e) {
										// console.log('重新运行的数据', e)
									}
								})
							}, 2000)
						}
					});

					return;
				}
				var len = files.length;
				for (let i = 0; i < len; i++) {
					// 过滤隐藏文件
					if (!plus.android.invoke(files[i], "isHidden")) {
						// 判断是文件还是文件夹
						if (plus.android.invoke(files[i], "isDirectory")) {
							var folderName = plus.android.invoke(files[i], "getName")
							if (folderName == 'Download') {
								this.toFolder({
									name: folderName,
									file: files[i]
								});
							}
						} else {
							var fileName = plus.android.invoke(files[i], "getName");

							var time = plus.android.invoke(files[i], "lastModified")
							if (this.filterArr.length > 0) {
								if (fileName.search(this.filterReg) < 0) {
									continue;
								}
							}
							if (fileName.search(/txt/i) > -1) {
								// txt 文件
								this.fileArr.push({
									name: fileName,
									file: files[i],
									type: 'txt',
									select: false,
									createtime: time
								})
							} else if (fileName.search(/doc|docx/i) > -1) {
								// doc/docx 文件
								this.fileArr.push({
									name: fileName,
									file: files[i],
									type: 'doc',
									select: false,
									createtime: time
								})
							} else if (fileName.search(/pdf/i) > -1) {
								// pdf 文件
								this.fileArr.push({
									name: fileName,
									file: files[i],
									type: 'pdf',
									select: false,
									createtime: time
								})
							} else {
								// 其他文件
								this.fileArr.push({
									name: fileName,
									file: files[i],
									type: 'file',
									select: false,
									createtime: time
								})
							}
						}
					}
				}
				// 排序,不区分大小写

				this.folderArr.sort(function(a, b) {
					return a.createtime < b.createtime ? '1' : '-1'
				});
				this.fileArr.sort(function(a, b) {
					return a.createtime < b.createtime ? '1' : '-1'
				});
				this.rootAddress.folderArr = this.folderArr;
				this.rootAddress.fileArr = this.fileArr;
			},
			// 进入文件夹
			toFolder(event) {

				this.isExit = false; // 地址栈中存在新地址,重置退出状态
				// this.folderArr = [];
				// this.fileArr = [];
				this.addressBar.push(event)
				// console.log('获取的文件夹信息',event)
				var files = plus.android.invoke(event.file, "listFiles");
				// console.log('查看点击文件夹事件')
				// if(files == null){
				// 	this.inaccessible = true;
				// }
				if (files) {
					var len = files.length;
				}
				if (len > 0) {
					for (let i = 0; i < len; i++) {
						// console.log("执行了几次2",i)
						// 过滤隐藏文件
						if (!plus.android.invoke(files[i], "isHidden")) {
							// 判断是文件还是文件夹
							if (plus.android.invoke(files[i], "isDirectory")) {
								var folderName = plus.android.invoke(files[i], "getName")
								// this.folderArr.push({name: folderName,file: files[i]})
								// this.toFolder({name: folderName,file: files[i]})
								if (folderName == 'WeiXin') {

									// console.log(folderName,"目录名")
									this.toFolder({
										name: folderName,
										file: files[i]
									});

								}
							} else {
								var fileName = plus.android.invoke(files[i], "getName")
								// lastModified
								var time = plus.android.invoke(files[i], "lastModified")
								// console.log('产看文件的方法',plus.android.invoke(files[i],"lastModified"))
								if (this.filterArr.length > 0) {
									if (fileName.search(this.filterReg) < 0) {
										continue;
									}
								}
								if (fileName.search(/txt/i) > -1) {
									// txt 文件
									this.fileArr.push({
										name: fileName,
										file: files[i],
										type: 'txt',
										select: false,
										createtime: time
									})
								} else if (fileName.search(/doc|docx/i) > -1) {
									// doc/docx 文件
									this.fileArr.push({
										name: fileName,
										file: files[i],
										type: 'doc',
										select: false,
										createtime: time
									})
								} else if (fileName.search(/pdf/i) > -1) {
									// pdf 文件
									this.fileArr.push({
										name: fileName,
										file: files[i],
										type: 'pdf',
										select: false,
										createtime: time
									})
									// console.log('打印pdf文件',files[i].)
								} else {
									// 其他文件
									this.fileArr.push({
										name: fileName,
										file: files[i],
										type: 'file',
										select: false,
										createtime: time
									})
								}
							}
						}
					}
				}

				// 排序,不区分大小写
				this.folderArr.sort(function(a, b) {
					return a.file.__UUID__.toUpperCase() > b.file.__UUID__.toUpperCase() ? '1' : '-1'
				});
				this.fileArr.sort(function(a, b) {
					return a.file.__UUID__.toUpperCase() > b.file.__UUID__.toUpperCase() ? '1' : '-1'
				});
				// console.log('排序',this.fileArr)
			},

获取到的文件存储到本地

async openPDF() {
				this.fileArr = [];
				await this.getRootDirectory();
				uni.setStorageSync('fileArr', this.fileArr)
				// console.log('fileArr查找完毕')
			},

App.vue onShow生命周期引用

onShow(){
    this.openPDF();
}

ok,到这里文件选择器插件就搞定了。比起直接用现成的插件,虽然多了摸鱼的时间,但是自己手写也确实能够让自己的小脑瓜更灵活点。当然如果能摸鱼我还是选择摸鱼的。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值