前往小程序,Get更优阅读体验!
立即前往
发布
社区首页 >专栏 >uni-app 开发鸿蒙应用—uts实现媒体文件下载并保存到系统相册

uni-app 开发鸿蒙应用—uts实现媒体文件下载并保存到系统相册

作者头像
超级小可爱
发布2024-11-26 11:00:52
发布2024-11-26 11:00:52
17110
代码可运行
举报
文章被收录于专栏:小孟开发笔记小孟开发笔记
运行总次数:0
代码可运行

uni-app 开发鸿蒙应用---uts实现媒体文件下载并保存到系统相册

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

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

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

目的:媒体文件下载并保存到系统相册;

实现方法:通过uts插件方式接入鸿蒙原生api,实现媒体文件下载并保存到系统相册。

难点:uts插件暂时只允许api形式导入,无法使用保存控件,且鸿蒙 'ohos.permission.WRITE_IMAGEVIDEO' 权限申请较难审核通过,决定使用保存图片api:showAssetsCreationDialog 实现。

https://developer.huawei.com/consumer/cn/doc/harmonyos-references-V5/js-apis-photoaccesshelper-V5#showassetscreationdialog12

一、新建uts插件;

按照官网步骤新建uts插件

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

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

1. 右键 uni_modules 目录新建 uni_modules 插件,命名为 ha-downloadToSystemAlbum

2. 修改插件根目录的 package.json 中的 uni_modules 节点,新增如下配置

代码语言:javascript
代码运行次数:0
复制
代码语言:javascript
代码运行次数:0
复制
{
    ...其他属性
 
    "uni_modules": {
        "uni-ext-api": {
            "uni": {
                "openAppProduct": {
                    "name": "hmDownloadToSystemAlbum",
                    "app": {
                        "js": false,
                        "kotlin": false,
                        "swift": false,
                        "arkts": true
                    }
                }
            }
        },
 
        ...其他属性
    }
}
代码语言:javascript
代码运行次数:0
复制
3. 编写插件根目录下的 /utssdk/interface.uts 文件,内容如下
代码语言:javascript
代码运行次数:0
复制
代码语言:javascript
代码运行次数:0
复制
/**
 * interface.uts
 * uts插件接口定义文件,按规范定义接口文件可以在HBuilderX中更好的做到语法提示
 */
 
/**
 * myApi 异步函数的参数,在type里定义函数需要的参数以及api成功、失败的相关回调函数。
 */
export type MyApiOptions = {
    fullUrl : string,
    renameUrl : string,
    fileType : string,
    success ?: (res : MyApiResult) => void,
    fail ?: (res : string) => void,
    progress ?: (res : any) => void,
}
 
/**
 * 函数返回结果
 * 可以是void, 基本数据类型,自定义type, 或者其他类型。
 * [可选实现]
 */
export type MyApiResult = {
    fieldA : number,
    fieldB : boolean,
    fieldC : string
}
 
/**
 * 函数返回结果
 * 可以是void, 基本数据类型,自定义type, 或者其他类型。
 * [可选实现]
 */
export type MyApiFail = {
    errMessage : string
}
 
 
/* 异步函数定义 */
export type MyApi = (options : MyApiOptions) => void
 
/* 同步函数定义 */
export type MyApiSync = (fullUrl : string) => MyApiResult
代码语言:javascript
代码运行次数:0
复制
4. 编写插件根目录下的 /utssdk/app-harmony/index.uts 文件(没有则新建),内容如下
代码语言:javascript
代码运行次数:0
复制
代码语言:javascript
代码运行次数:0
复制
/* 引入 interface.uts 文件中定义的变量 */
import { MyApiOptions, MyApi } from '../interface.uts';
 
import request from '@ohos.request'; // 下载
import { fileUri } from '@kit.CoreFileKit'; // 获取getUriFromPath
import { photoAccessHelper } from '@kit.MediaLibraryKit'; // 保存到相册
import fs, { ReadOptions, WriteOptions } from '@ohos.file.fs';
import dataSharePredicates from '@ohos.data.dataSharePredicates';
 
// 1.是否同意下载-->同意:获取需要保存到媒体库的位于应用沙箱的媒体uri 
// 2.文件下载-->progress:98%
// 3.已下载的沙箱文件写入已获取的媒体uri文件中-->progress:100%
 
export const hmDownloadToSystemAlbum : MyApi = async function (options : MyApiOptions) {
    let context : Context = getContext();
    let phAccessHelper = photoAccessHelper.getPhotoAccessHelper(context);
    let filesDir = context.filesDir;
    let cfg : request.DownloadConfig = {
        url: options.fullUrl,
        filePath: filesDir + '/' + options.renameUrl,
        enableMetered: true
    }
    let downloadTask : request.DownloadTask;
 
    // 1.是否同意下载-->同意:获取需要保存到媒体库的位于应用沙箱的图片/视频uri
    try {
        let srcFileUri : string = fileUri.getUriFromPath(cfg.filePath) || '';
        let srcFileUris : Array<string> = [srcFileUri];
 
        let fileType : photoAccessHelper.PhotoType = photoAccessHelper.PhotoType.IMAGE;
        if (options.fileType === 'photo') fileType = photoAccessHelper.PhotoType.IMAGE;
        if (options.fileType === 'video') fileType = photoAccessHelper.PhotoType.VIDEO;
        let photoCreationConfigs : Array<photoAccessHelper.PhotoCreationConfig> = [
            {
                title: options.renameUrl.split('.')[0] || '', // 可选-图片或者视频的标题,例如'test2'
                fileNameExtension: options.renameUrl.split('.').pop() || '', // 必填-文件扩展名,例如'jpg'
                photoType: fileType, // 必填-创建的文件类型,IMAGE或者VIDEO
                subtype: photoAccessHelper.PhotoSubtype.DEFAULT, // 可选-图片或者视频的文件子类型,DEFAULT[默认照片类型]或者MOVING_PHOTO[动态照片文件类型]
            }
        ];
 
        let desFileUris : Array<string> = await phAccessHelper.showAssetsCreationDialog(srcFileUris, photoCreationConfigs);
        let URI = desFileUris[0];
 
        // 2.文件下载98%
        if (desFileUris.length > 0) {
            let progressNum : number = 0;
            options?.progress?.(progressNum);
 
            try {
                request.downloadFile(context.getApplicationContext(), cfg
                    , (err, data) => {
                        if (err) {
                            console.error('Failed to request the download. Cause: ' + JSON.stringify(err));
                            return;
                        }
                        downloadTask = data;
 
                        // 进度条
                        let progressCallback = (receivedSize : number, totalSize : number) => {
                            // console.info("download receivedSize:" + receivedSize + " totalSize:" + totalSize);
                            let numA : number = Math.round((totalSize / 98));
                            let numB : number = Math.round((receivedSize / numA));
                            options?.progress?.(numB);
                        };
                        downloadTask.on('progress', progressCallback);
 
                        // 下载完成
                        downloadTask.on("complete", async () => {
                            // console.log('下载完成', JSON.stringify(options));
                            try {
                                // 判定文件是否存在
                                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);
 
                                return options?.progress?.(100);
                            } catch (e) {
                                //TODO handle the exception
                                options?.fail?.('下载失败,请重试');
                            }
                        })
                    });
            } catch (err) {
                options?.fail?.('下载失败,请重试');
                console.error('err.code : ' + err.code + ', err.message : ' + err.message);
            }
        } else {
            // 取消授权
            options?.fail?.('已取消');
        }
    } catch (err) {
        console.error('showAssetsCreationDialog failed, errCode is ' + err.code + ', errMsg is ' + err.message);
    }
}
代码语言:javascript
代码运行次数:0
复制

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

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

1. 调用 showAssetsCreationDialog 接口拉起保存确认弹窗,获取已创建并授予保存权限的uri列表;
2. 若同意授权,调用 request.downloadFile 下载媒体文件到沙箱路径;
3. 在下载完成回调中,将下载的沙箱文件源内容写入至目的已授权uri中。

三、在页面中使用

1. import 引入
代码语言:javascript
代码运行次数:0
复制
代码语言:javascript
代码运行次数:0
复制
// #ifdef APP-HARMONY
// 仅鸿蒙会编译
import {
    hmDownloadToSystemAlbum
} from "@/uni_modules/ha-downloadToSystemAlbum"
// #endif
代码语言:javascript
代码运行次数:0
复制
2. 调用
代码语言:javascript
代码运行次数:0
复制
代码语言:javascript
代码运行次数:0
复制
methods: {
    downloadToSystemAlbum(payload) {
        // 下载并保存
        hmDownloadToSystemAlbum({
            fullUrl: payload.downloadUrl, // 完整下载链接
            renameUrl: payload.renameUrl, // 下载文件重命名
            fileType: payload.fileType, // 下载媒体文件类型 'photo' | 'video'
            progress: (res) => { // 下载进度条
                console.log('已下载' + res * 1 + '%');
            },
            fail: (err) => { // 下载失败
                if (err) {
                    console.log('下载失败');
                }
            },
        });
    },
}

文章知识点与官方知识档案匹配,可进一步学习相关知识

本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
原始发表:2024-10-22,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • uni-app 开发鸿蒙应用---uts实现媒体文件下载并保存到系统相册
    • 一、新建uts插件;
      • 1. 右键 uni_modules 目录新建 uni_modules 插件,命名为 ha-downloadToSystemAlbum
      • 3. 编写插件根目录下的 /utssdk/interface.uts 文件,内容如下
      • 4. 编写插件根目录下的 /utssdk/app-harmony/index.uts 文件(没有则新建),内容如下
  • 二、接入鸿蒙原生api,实现授权、下载、保存功能;
    • 1. 调用 showAssetsCreationDialog 接口拉起保存确认弹窗,获取已创建并授予保存权限的uri列表;
    • 2. 若同意授权,调用 request.downloadFile 下载媒体文件到沙箱路径;
    • 3. 在下载完成回调中,将下载的沙箱文件源内容写入至目的已授权uri中。
  • 三、在页面中使用
    • 1. import 引入
    • 2. 调用
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档