@ionic-native-ohos/file-transfer
v5.36.0
Published
Ionic Native - Native File Transfer Plugin
Readme
@ionic-native/file-transfer
本项目基于 @ionic-native/[email protected]开发。
简介
@ionic-native/file-transfer是OpenHarmony Cordova生态系统中的核心插件,提供文件上传与下载功能,可实现进度监听、请求头自定义等能力,为跨平台应用开发提供设备差异化适配能力。兼容Android、iOS和OpenHarmony平台,为跨平台应用开发提供统一的文件传输能力。本文档主要说明在OpenHarmony系统中的应用。
@ionic-native/file-transferAPI提供文件上传与下载功能。
支持平台
- OpenHarmony:5.0+
下载安装
通过命令行或手动引入即可快速安装插件,支持从npm仓库获取。
命令行安装(推荐)
安装 hionic CLI:
npm install -g hionic以下两种方式中任选其一即可,无需重复操作:
npm安装:
# 安装插件
npm install @ionic-native/file-transfer
# 同步插件
hionic synchionic CLI安装:
hionic plugin add @ionic-native/file-transfer手动引入安装
1.添加插件配置
根据 plugin.xml 的 config-json 项,找到 entry 模块中 config.xml 文件,并根据 param 标签添加配置
<feature name="FileTransfer">
<param name="harmony-package" value="FileTransfer" />
<param name="onload" value="true" />
</feature>2.修改CMake配置
根据 plugin.xml 的 CMakeLists 项,找到 cordova 模块,路径为 target 字段的文件 CMakeLists.txt,添加 add_library
add_library(cordova SHARED
// ...
FileTransfer/FileTransfer.cpp
// ...
)3.复制源码文件
根据 plugin.xml 的 source-file 项,将 src 字段的路径代码复制到 cordova 模块中 target-dir 字段的目录中:
将源码中src/main/cpp/FileTransfer目录下的FileTransfer.h、FileTransfer.cpp文件引入到cordova模块中src/main/cpp/FileTransfer目录下。
将源码中src/main/ets/components/FileTransfer目录下的FileTransfer.ets文件引入到cordova模块中src/main/ets/components/FileTransfer目录下。
4.添加ArkTS配置
在 cordova 模块的 build-profile.json5 文件中,buildOption/arkOptions/runtimeOnly/sources 配置项数组中加入步骤3中拷贝的ets文件路径:
"buildOption":{
"arkOptions": {
"runtimeOnly": {
"sources": [
// ...
"./src/main/ets/components/FileTransfer/FileTransfer.ets"
// ...
]
}
}
}5.编译注意事项
由于依赖的插件@ionic-native/file依赖C++17环境,编译前需要在CMakeLists项中添加C++标准支持,不添加编译会报错
添加位置,根据 plugin.xml 的 CMakeLists 项找到CMakeLists文件,添加如下:
set(CMAKE_CXX_STANDARD 17)卸载
# hionic CLI 卸载
hionic plugin remove @ionic-native/file-transfer约束与限制
兼容性
在以下版本中已测试通过:
- SDK: 5.0.5(17); IDE: DevEco Studio: 6.0.0; ROM: 5.1.0.150;
权限要求
OpenHarmony应用权限添加参考申请应用权限,在主工程的 module.json5 的requestPermissions添加ohos.permission.INTERNET权限,示例如下:
{
"name" : "ohos.permission.INTERNET"
}使用示例
示例1:上传图片
实现上传图片到服务器的功能,包含进度监听。
import { FileTransfer } from '@ionic-native/file-transfer';
// 上传一张图片
function uploadPicture(imageUri) {
function win(r) {
console.log("Code = " + r.responseCode);
console.log("Response = " + r.response);
console.log("Sent = " + r.bytesSent);
if(r.response == "MAX") {
alert("图片太大超过4M,请剪裁小一点");
}
}
function fail(error) {
console.log("An error has occurred: Code = " + error.code);
console.log("upload error source " + error.source);
console.log("upload error target " + error.target);
}
// 显示上传进度
function progressFun(progressEvent) {
var progress = progressEvent.loaded / progressEvent.total * 100;
document.getElementById("progress").innerHTML = "上传进度:" + progress + "%100";
}
// 上传参数配置
var options = new FileUploadOptions();
options.fileKey = "picture";
options.fileName = imageUri.substr(imageUri.lastIndexOf('/') + 1);
options.mimeType = "image/pjpeg";
var headers = {'oss-token': 'your-token'};
options.headers = headers;
FileTransfer.onprogress = progressFun;
FileTransfer.upload(imageUri, "https://your-server-domain/ImageTempUpload", win, fail, options);
}
function upload() {
var options = {
quality: 50,
destinationType: Camera.DestinationType.FILE_URI,
sourceType: Camera.PictureSourceType.CAMERA,
encodingType: Camera.EncodingType.JPEG,
mediaType: Camera.MediaType.PICTURE,
allowEdit: false,
correctOrientation: true
}
navigator.camera.getPicture(function cameraSuccess(imageUri) {
var elem = document.getElementById('imageFile');
elem.src = imageUri;
window.resolveLocalFileSystemURL(imageUri, function (fileEntry) {
console.log(fileEntry.toURL());
uploadPicture(fileEntry.toURL());
});
}, function cameraError(error) {
console.debug("Unable to obtain picture: " + error, "app");
}, options);
}示例2:下载图片
实现从服务器下载图片到本地的功能,包含进度监听。
function download() {
function onErrorReadFile(error) {
}
function displayImage(blob) {
var elem = document.getElementById('imageFile2');
elem.src = window.URL.createObjectURL(blob);
}
function readBinaryFile(fileEntry) {
fileEntry.file(function (file) {
var reader = new FileReader();
reader.onloadend = function() {
console.log("Successful file write: " + this.result);
var blob = new Blob([new Uint8Array(this.result)], { type: "image/png" });
displayImage(blob);
};
reader.readAsArrayBuffer(file);
}, onErrorReadFile);
}
function successFun(fileEntry) {
console.log("download complete: " + fileEntry.toURL());
readBinaryFile(fileEntry);
}
function failFun(error) {
console.log("An error has occurred: Code = " + error.code);
console.log("upload error source " + error.source);
console.log("upload error target " + error.target);
alert('图片下载失败。');
}
function progressFun(progressEvent) {
var progress = progressEvent.loaded / progressEvent.total * 100;
document.getElementById("progress").innerHTML = "下载进度:" + progress + "%100";
}
var uri = "https://cordova.apache.org/static/img/cordova_bot.png";
window.resolveLocalFileSystemURL(cordova.file.externalDataDirectory, function(dirEntry) {
var targetPath = dirEntry.toURL() + "中文.png";
console.log("targetPath:" + targetPath);
FileTransfer.onprogress = progressFun;
FileTransfer.download(
uri,
targetPath,
successFun,
failFun,
false,
{}
);
});
}使用说明
依赖插件
该插件依赖 ionic-native 文件系统插件实现本地文件操作,依赖 @ionic-native/file 插件。
接口方法
| 方法名 | 请求参数 | 返回类型 | 描述 | 备注 |
|-------|---------|---------|------|------|
| download(...) | download(serverUrl: string, localFilePath: string, successCallback: (result: FileDownloadResult) => void, errorCallback: (error: FileTransferError) => void, trustAllHosts?: boolean, options?: FileDownloadOptions) | Promise<void> | 将文件下载到指定位置 | |
| upload(...) | upload(localFilePath: string | Blob, serverUrl: string, successCallback: (result: FileUploadResult) => void, errorCallback: (error: FileTransferError) => void, options?: FileUploadOptions, trustAllHosts?: boolean) | Promise<FileUploadResult> | 将文件上传到指定服务器 | |
| abort() | | Promise<void> | 中止上传或下载 | |
方法参数说明
1. 构造函数:创建文件传输对象
// 初始化文件传输对象
const fileTransfer = new FileTransfer();2. 核心方法:上传文件
interface FileUploadOptions {
fileKey?: string; // 表单字段名,默认 "file"
fileName?: string; // 上传后的文件名,默认 "image.jpg"
mimeType?: string; // 文件 MIME 类型,默认 "image/jpeg"
params?: { [key: string]: string | number }; // 额外表单参数
chunkedMode?: boolean; // 是否分片传输,openharmony 默认 true
headers?: { [key: string]: string }; // 自定义请求头
httpMethod?: "POST" | "PUT"; // HTTP 方法,默认 "POST"
}
interface FileUploadResult {
bytesSent: number; // 已上传字节数
responseCode: number; // HTTP 响应码
response: string; // 服务端响应数据(字符串)
objectId: string; // 任务ID
}
fileTransfer.upload(
localFilePath: string | Blob, // 本地文件路径
serverUrl: string, // 服务端上传接口 URL
successCallback: (result: FileUploadResult) => void, // 成功回调
errorCallback: (error: FileTransferError) => void, // 失败回调
options?: FileUploadOptions, // 上传配置
trustAllHosts?: boolean // openharmony 不校验域名
): void;3. 核心方法:下载文件
import { FileTransfer } from '@ionic-native/file-transfer';
// 下载结果是 fileEntry 对象
FileTransfer.download(
serverUrl: string, // 服务端文件 URL
localFilePath: string, // 本地保存路径
successCallback: (result: FileDownloadResult) => void, // 成功回调
errorCallback: (error: FileTransferError) => void, // 失败回调
trustAllHosts?: boolean, // 是否信任所有主机(SSL),默认 false
options?: FileDownloadOptions // 下载配置
): void;4. 事件:进度监听
// 上传/下载进度回调(共用同一个事件)
FileTransfer.onprogress = function(progressEvent: ProgressEvent) {
/**
* progressEvent 属性说明:
* - loaded:已传输字节数
* - total:总字节数(仅当服务端返回 Content-Length 时有效)
* - lengthComputable:是否可计算总进度(布尔值)
* - timeStamp:事件触发时间戳(毫秒)
*/
if (progressEvent.lengthComputable) {
const progress = (progressEvent.loaded / progressEvent.total) * 100;
console.log(`当前进度:${progress.toFixed(2)}%`);
} else {
console.log(`已传输:${(progressEvent.loaded / 1024 / 1024).toFixed(2)} MB`);
}
};5. 方法:取消传输
// 取消正在进行的上传/下载
FileTransfer.abort();数据结构
FileDownloadOptions
| 属性 | 类型 | 默认值 | 说明 |
|------|------|--------|------|
| headers | 对象 | {} | 自定义 HTTP 请求头(如 Accept、Cookie) |
FileUploadResult
| 属性 | 类型 | 描述 |
|------|------|------|
| bytesSent | number | 已上传的总字节数 |
| responseCode | string | 上传操作的 HTTP 响应码 |
| response | string | 上传操作的 HTTP 响应体(如果可用) |
| objectId | string | 任务ID |
| headers | { [key: string]: string; } | 上传响应的 HTTP 头信息(如果可用) |
FileUploadOptions
| 属性 | 类型 | 默认值 | 说明 |
|------|------|--------|------|
| fileKey | string | "file" | 服务端接收文件的表单字段名(如 PHP 中 $_FILES['file']) |
| fileName | string | "image.jpg" | 上传到服务端后的文件名,支持自定义扩展名(如 "video.mp4") |
| mimeType | string | "image/jpeg" | 文件的 MIME 类型,需与文件实际类型匹配(如 "application/pdf") |
| params | 对象 | {} | 额外的表单参数,服务端可通过请求体获取(如用户 ID、文件类型) |
| chunkedMode | boolean | true(移动平台) | 是否分片传输:大文件(>10MB)建议开启,减少内存占用;小文件可关闭,提升效率 |
| headers | 对象 | {} | 自定义 HTTP 请求头(如 token、用户代理) |
| httpMethod | "POST" / "PUT" | "POST" | 上传使用的 HTTP 方法,需与服务端接口匹配 |
错误码与处理方案
插件定义了标准化的错误码(FileTransferError),便于定位问题:
| 错误码 | 常量名 | 说明 | 常见原因与解决方案 |
|--------|--------|------|-------------------|
| 1 | FILE_NOT_FOUND_ERR | 本地文件不存在 | 1. 检查文件路径是否正确 2. 确保应用有文件读取权限 |
| 2 | INVALID_URL_ERR | 服务端 URL 无效 | 1. 检查 URL 格式(如是否遗漏 http://)2. 使用 encodeURI 编码 URL |
| 3 | CONNECTION_ERR | 网络连接错误 | 1. 检查设备网络状态(WiFi/4G)2. 确认服务端接口可访问 3. 处理超时(增大超时时间) |
| 4 | ABORT_ERR | 传输被主动取消 | 调用了 fileTransfer.abort(),属于正常流程,无需特殊处理 |
| 5 | NOT_MODIFIED_ERR | 文件未修改(HTTP 304) | 服务端返回 304 响应,说明本地文件已是最新版本,可停止下载 |
使用建议
不建议直接使用大文件上传或下载,如果应用进入后台,会被操作系统中断传输。
目录结构
|---- 目录
| |---- src/main # 插件的实现代码
| |---- cpp # C++ 代码
| |---- ets # ArkTS 代码
| |---- www # Web 侧代码
| |---- README.md # 说明文档
| |---- package.json # 配置文件
| |---- plugin.xml # 插件配置文件贡献代码
使用过程中发现任何问题都可以提 Issue,当然,也非常欢迎发 PR 共建。
许可证
本插件基于 MIT License 开源,详见 LICENSE 文件。
