uni-app 开发鸿蒙应用---uts实现文件下载并保存到系统文件资源管理器

 uni-app 开发鸿蒙应用---uts实现文件下载并保存到系统文件资源管理器 

当前编译器版本:HBuilderX 4.26 Alpha版

 当前工程文件:template-1.3.7.tgz

uni-app 开发鸿蒙应用 | uni-app官网 (dcloud.net.cn)

目的:文件下载并保存到系统文件资源管理器;

实现方法:通过uts插件方式接入鸿蒙原生api,实现文件下载并保存到系统文件资源管理器。

一、新建uts插件;

按照官网步骤新建uts插件

UTS插件介绍 | uni-app-x (dcloud.net.cn)

uni-app 开发鸿蒙应用 | uni-app官网 (dcloud.net.cn)

1. 右键 uni_modules 目录新建 uni_modules 插件,命名为 ha-downloadFile
uni-app 开发鸿蒙应用---uts实现文件下载并保存到系统文件资源管理器_第1张图片
2. 修改插件根目录的 package.json 中的 uni_modules 节点,新增如下配置
{
	...其他属性

	"uni_modules": {
		"uni-ext-api": {
			"uni": {
				"openAppProduct": {
					"name": "hmDownloadFile",
					"app": {
						"js": false,
						"kotlin": false,
						"swift": false,
						"arkts": true
					}
				}
			}
		},

		...其他属性
	}
}
 3. 编写插件根目录下的 /utssdk/interface.uts 文件,内容如下
/**
 * interface.uts
 * uts插件接口定义文件,按规范定义接口文件可以在HBuilderX中更好的做到语法提示
 */

/**
 * myApi 异步函数的参数,在type里定义函数需要的参数以及api成功、失败的相关回调函数。
 */
export type MyApiOptions = {
	fullUrl : string,
	renameUrl : string,
	fail ?: (res : string) => void,
}

/**
 * 函数返回结果
 * 可以是void, 基本数据类型,自定义type, 或者其他类型。
 * [可选实现]
 */
export type MyApiResult = {
	fieldA : number,
	fieldB : boolean,
	fieldC : string
}

/**
 * 错误码
 * 根据uni错误码规范要求,建议错误码以90开头,以下是错误码示例:
 * - 9010001 错误信息1
 * - 9010002 错误信息2
 */
export type MyApiErrorCode = 9010001 | 9010002;
/**
 * myApi 的错误回调参数
 */
export interface MyApiFail extends IUniError {
	errCode : MyApiErrorCode
};

/* 异步函数定义 */
export type MyApi = (options : MyApiOptions) => void

/* 同步函数定义 */
export type MyApiSync = (fullUrl : boolean) => MyApiResult
4. 编写插件根目录下的 /utssdk/app-harmony/index.uts 文件(没有则新建),内容如下 
/* 引入 interface.uts 文件中定义的变量 */
import { MyApiOptions, MyApi } from '../interface.uts';

import { BusinessError } from '@kit.BasicServicesKit';
import request from '@ohos.request';
import { picker } from '@kit.CoreFileKit';
import fs, { ReadOptions, WriteOptions } from '@ohos.file.fs';
import buffer from '@ohos.buffer';

// 1.文件下载
// 2.选取文件保存路径
// 3.已下载沙箱文件写入已选取的文件管理器保存路径中

export const hmDownloadFile : MyApi = function (options : MyApiOptions) {
	const context : Context = getContext();
	let filesDir = context.filesDir;
	let cfg : request.DownloadConfig = {
		url: options.fullUrl,
		filePath: filesDir + '/' + options.renameUrl,
		enableMetered: true
	}
	let downloadTask : request.DownloadTask;

	try {
		request.downloadFile(context.getApplicationContext(), cfg
			, (err, data) => {
				if (err) {
					console.error('Failed to request the download. Cause: ' + JSON.stringify(err));
					return;
				}
				downloadTask = data;

				downloadTask.on("complete", () => {
					// console.log('下载完成', JSON.stringify(options));
				
					try {
						const documentSaveOptions = new picker.DocumentSaveOptions(); // 创建文件管理器保存选项实例
						documentSaveOptions.newFileNames = [options.renameUrl]; // 保存文件名(可选),方括号里的文件名自定义,每次不能重复,设备里已有这个文件的话,名字就需要改个不一样的,不然接口会报错
						const documentViewPicker = new picker.DocumentViewPicker(context);
						// documentSaveOptions.pickerMode = picker.DocumentPickerMode.DOWNLOAD;
						documentViewPicker.save(documentSaveOptions)
							.then(async (documentSaveResult) => {
								let URI = documentSaveResult[0]
								// console.info('documentViewPicker.save successfully, uri:' + JSON.stringify(URI));
								// 判定文件是否存在
								if (fs.accessSync(URI)) {
									// 删除文件
									fs.unlinkSync(URI)
								}
								let srcFile = fs.openSync(cfg.filePath, fs.OpenMode.READ_WRITE | fs.OpenMode.CREATE);
								let destFile = fs.openSync(URI, fs.OpenMode.READ_WRITE);
								// 读取源文件内容并写入至目的文件
								let bufSize = 4096;
								let readSize = 0;
								let buf = new ArrayBuffer(bufSize);
								let readOptions : ReadOptions = {
									offset: readSize,
									length: bufSize
								};
								let readLen = fs.readSync(srcFile.fd, buf, readOptions);
								while (readLen > 0) {
									readSize += readLen;
									let writeOptions : WriteOptions = {
										length: readLen
									};
									fs.writeSync(destFile.fd, buf, writeOptions);
									readOptions.offset = readSize;
									readLen = fs.readSync(srcFile.fd, buf, readOptions);
								}
								// 关闭文件
								fs.closeSync(srcFile);
								fs.closeSync(destFile);
							}).catch((err : BusinessError) => {
                                options?.fail?.('保存失败,请重试');
								console.error(`Invoke documentViewPicker.save failed, code is ${err.code}, message is ${err.message}`);
							})
					} catch (err) {
                        options?.fail?.('下载失败,请重试');
						console.info(`Failed to save file.err: ${JSON.stringify(err)}`);
					}
				})
			});
	} catch (err) {
        options?.fail?.('下载失败,请重试');
		console.error('err.code : ' + err.code + ', err.message : ' + err.message);
	}
}

二、接入鸿蒙原生api,实现下载、保存功能;

完整代码如上 /utssdk/app-harmony/index.uts 文件

1. 调用 request.downloadFile 下载文件到应用沙箱路径;
2. 若同意授权,调用 request.downloadFile 下载媒体文件到沙箱路径;
3. 在下载完成回调中,将下载的沙箱文件源内容写入至已选取的文件管理器保存路径中

三、在页面中使用

1. import 引入
// #ifdef APP-HARMONY
	// 仅鸿蒙会编译
	import {
		hmDownloadFile
	} from "@/uni_modules/ha-downloadFile"
// #endif
2. 调用
methods: {
	download(payload) {
		// 下载并保存
        hmDownloadFile({
			fullUrl: payload.downloadUrl, // 完整下载链接
			renameUrl: payload.renameUrl, // 下载文件重命名
			fail: (err) => { // 下载失败
				if (err) {
					console.log('下载失败',err);
				}
			},
		});
	},
}

你可能感兴趣的:(harmonyos,uni-app,华为)