IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> 移动开发 -> uniapp文件管理 文件列表 获取媒体文件 图片、视频、音频、文档压缩包文件并实现可删除文件 图片文件列表 视频文件列表 音频文件列表 获取内存卡图片视频音频pdf xlxs docx txt -> 正文阅读

[移动开发]uniapp文件管理 文件列表 获取媒体文件 图片、视频、音频、文档压缩包文件并实现可删除文件 图片文件列表 视频文件列表 音频文件列表 获取内存卡图片视频音频pdf xlxs docx txt

[前言]
uniapp目前本身并不支持直接获取媒体文件列表,不过因为提供了原生插件使用和开发的功能,问题并不大,接下来进入正题。

Android 10以上的存储机制

因为Android 10以上高版本,开始执行更为安全分区存储机制,对外部存储文件访问方式重新设计,便于用户更好的管理外部存储文件。这个机制遵循三个原则:
1、文件由哪个应用创建,应用不需要存储权限即可以访问应用自己创建文件(这点不错)
2、添加外部存储应用私有目录文件访问限制,现在即使你的应用申请读写权限也不能访问其他应用外部存储私有目录文件(让数据更安全,防止篡改)
3、添加pdf、office、doc等非媒体、图片和音频文件的访问限制,你的应用即使申请了读写权限也无法访问其他应用创建的pdf、office、doc等文件

在这里插入图片描述

MediaStore API

MediaStore是Android系统提供的媒体库,可以通过ContentResolver来对媒体库执行查询、修改、删除文件的操作。本文开发的原生插件就是基于此API.

下面是uniapp调用层的方法,在这个方法里用Android代码逻辑编写插件功能。

// 获取文件的中枢函数
@UniJSMethod(uiThread = true)
    public void getFiles(final JSONObject options, UniJSCallback callback,UniJSCallback fail) {
        JSONObject param = new JSONObject();
        param.put("fileType","image");

        if(options != null){
            param = options;
        }

        JSONObject data = new JSONObject();
        String fileType = param.getString("fileType");

        ContentResolver resolver = mUniSDKInstance.getContext().getContentResolver();
        switch (fileType){
            case "image": data = FileManageUtils.getAllPhoto(resolver); break;
            case "video": data = FileManageUtils.getAllVideo(resolver); break;
            case "audio": data = FileManageUtils.getAllMusic(resolver); break;
            case "document": data = FileManageUtils.getAllText(resolver); break;
            case "zip": data = FileManageUtils.getAllZip(resolver); break;
        }

	 // 到这里已经获取到了文件列表数据, 通过uniapp传过来的回调返回数据
        if(callback != null){
            callback.invoke(data);
        }else{
            if(fail != null){
                JSONObject result = new JSONObject();
                result.put("code",201);
                result.put("message","获取文件列表失败");
                fail.invoke(result);
            }
        }
    }

获取照片文件列表

对每种类型都进行了一层函数封装,getAllPhoto获取所有图片,getAllVideo获取所有视频,getAllMusic获取或有音频,getAllText获取所有文档,getAllZip获取所有压缩文件。

	// 获取文件列表并进行一个简单封装,返回 list / 长度 / 媒体文件类型
    public static JSONObject getAllPhoto(ContentResolver resolver) {
        String[] projection = new String[]{MediaStore.Images.ImageColumns._ID,MediaStore.Images.ImageColumns.SIZE, MediaStore.Images.ImageColumns.DATA, MediaStore.Images.ImageColumns.DISPLAY_NAME};
        List<JSONObject> list = getFiles(MediaStore.Images.Media.EXTERNAL_CONTENT_URI,resolver,null,null,projection,MediaStore.Images.ImageColumns.DISPLAY_NAME,MediaStore.Images.ImageColumns.DATA,MediaStore.Images.ImageColumns.SIZE,MediaStore.Images.ImageColumns._ID);
        JSONObject data = new JSONObject();
        data.put("fileList",list);
        data.put("fileNum",list.size());
        data.put("fileType","image");
        return data;
    }

getFile函数的核心代码

这个方法通过外部传入的类型和字段等参数来查询媒体文件,获取一个游标索引,从中可以循环取出数据封装成目标格式。

private static List<JSONObject> getFiles(Uri uri, ContentResolver resolver, String selection, String[] selectionArgs, String[] projection, String colName, String colPath, String colSize, String colId){
        List<JSONObject> files = new ArrayList<>();

        //projection 是定义返回的数据,selection 通常的sql 语句,例如  selection=MediaStore.Images.ImageColumns.MIME_TYPE+"=? " 那么 selectionArgs=new String[]{"jpg"};
        Cursor cursor = resolver.query(uri, projection, selection, selectionArgs, MediaStore.Images.ImageColumns.DATE_MODIFIED + "  desc");

        float fileSize = 0;
        long fileId = 0;
        String fileName;
        String filePath;

        while (cursor.moveToNext()) {
            fileSize = cursor.getFloat(cursor.getColumnIndex(colSize));
            fileName = cursor.getString(cursor.getColumnIndex(colName));
            filePath = cursor.getString(cursor.getColumnIndex(colPath));
            fileId = cursor.getLong(cursor.getColumnIndex(colId));

            JSONObject obj = new JSONObject();
            obj.put("path",filePath);
            obj.put("size",fileSize);
            obj.put("name",fileName);
            obj.put("id",fileId);
            files.add(obj);
        }

        cursor.close();

        return files;
    }

uniapp层调用

<template>
	<view>
		<uni-segmented-control 
			:values="['图片','视频','音频','文档','zip']" 
			styleType="button" 
			@clickItem="onClickItem"
			class="segmented-style">
		</uni-segmented-control>
		
		<view class="list-style" v-if="listData && listData.length > 0">
			<view v-for="(item, index) in listData" v-bind:key="index" class="list-item-style" @longpress="longPressEvent(item)">
				<text class="list-item-text">{{getUnitValue(item.size)}}</text>
				<image :src="item.path" class="list-item-media-style" v-if="mode === 'image'"></image>
				<view v-else-if="mode === 'video'" style="background-color: bisque;display: flex;align-items: center;justify-content: center;" class="list-item-media-style">
					<image src="../../static/icon_play.png" style="width: 50rpx; height: 50rpx;"></image>
				</view>
				
				<view v-else-if="mode === 'audio'" style="background-color: indianred;display: flex;align-items: center;justify-content: center;" class="list-item-media-style">
					<image src="../../static/icon_audio.png" style="width: 50rpx; height: 50rpx;"></image>
				</view>
			</view>
		</view>
		<view v-else style="color: #999999;min-height: calc(60vh);display: flex;align-items: center;justify-content: center;">
			设备中没有发现该类型文件
		</view>
	</view>
</template>

<script>
	var fileManage = uni.requireNativePlugin("luanqing-file-manage");
	
	export default {
		data() {
			return {
				mode:'image', // 0|图片 1|视频  2|音频  3|文件
				listData:[],
			}
		},
		onShow() {
			this.loadFiles();
		},
		methods: {
			longPressEvent(data){
				const $that = this;
				uni.showModal({
					title:'是否确定删除?',
					cancelText:'取消',
					confirmText:'删除',
					complete(res) {
						if(res.confirm){
							console.error("长按删除:",data);
							fileManage.deleteFile({fileType:$that.mode,fileId:data.id, filePath:data.path},(res=>{
								console.error("删除成功:",res);
								$that.loadFiles();
							}), (res=>{
								console.error("删除失败:",res);
							}));
						}
					}
				})
			},
			loadFiles(){
				const $that = this;
				console.error("是否是空:",fileManage === undefined || fileManage === null);
				fileManage.getFiles({fileType:this.mode}, (res=>{
					console.error("接口返回的数据:",res.files);
					$that.listData = res.fileList;
				}), (fail=>{
					console.error("获取文件列表失败:",fail);
				}));
			},
			onClickItem(e){
				this.mode = this.getFileType(e.currentIndex);
				this.loadFiles();
			},
			// 获取文件类型
			getFileType(typeId){
				switch(typeId){
					case 0: return "image";
					case 1: return "video";
					case 2: return "audio";
					case 3: return "document";
					case 4: return "zip";
					default: return "image";
				}
			},
			// 计算文件大小值和单位
			getUnitValue(value){
				if(value > 1000000)
					return (value / 1000000).toFixed(1) + 'MB';
				else if(value > 1000)
					return Math.floor(value / 1000).toFixed(1) + 'KB';
				else if(value < 1000)		
					return Math.floor(value / 1000).toFixed(1) + 'KB';
				// return value > 1000 ? 
			}
		}
	}
</script>

<style>
	.segmented-style{
		margin-left: 20rpx;
		margin-right: 20rpx;
		margin-top: 25rpx;
	}
	.list-style{
		display: flex;
		flex-direction: row;
		flex-wrap: wrap;
	}
	.list-item-style{
		width: 115rpx;
		height: 115rpx;
		margin: 5rpx;
		position: relative;
		background-color: #ffffff;
	}
	.list-item-media-style{
		width: 115rpx;
		height: 115rpx;
		position: absolute;
		top: 0rpx;
		bottom: 0rpx;
		left: 0rpx;
		right: 0rpx;
		z-index: 10;
	}
	.list-item-text{
		z-index: 100;
		position: absolute;
		bottom: 0rpx;
		right: 0rpx;
		color: #333333;
		padding: 0rpx 10rpx;
		font-size: 20rpx;
		background-color: #F2F2F2;
	}
</style>

链接: 下载地址

示例图:在这里插入图片描述在这里插入图片描述

  移动开发 最新文章
Vue3装载axios和element-ui
android adb cmd
【xcode】Xcode常用快捷键与技巧
Android开发中的线程池使用
Java 和 Android 的 Base64
Android 测试文字编码格式
微信小程序支付
安卓权限记录
知乎之自动养号
【Android Jetpack】DataStore
上一篇文章      下一篇文章      查看所有文章
加:2022-08-06 10:55:38  更:2022-08-06 10:59:21 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年11日历 -2024/11/25 4:25:15-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码