Preview Kit(文件预览服务)为应用提供便捷的文件快速预览能力,支持跳出应用进行文件的预览。
约束与限制 | 说明 |
|---|---|
支持的国家和地区 | 当前Preview Kit仅支持中国境内(香港特别行政区、澳门特别行政区、中国台湾除外)。 |
支持的设备 | 模拟器支持情况,请见模拟器与真机的差异列表中应用服务章节的Preview Kit(文件预览服务)说明。 文件预览功能支持华为Phone、Tablet和2in1,文件打开加速功能仅支持2in1设备。 |
通过HarmonyOS提供的Preview Kit(文件预览服务)实现pdf文件在应用外预览。实现思路如下:
let srcFileDescriptor = this.context.resourceManager.getRawFdSync('test.pdf'); // 需要在rawfile目录下手动添加名为test.pdf的文件
if (!fs.statSync(srcFileDescriptor.fd).isFile()) { console.error('Not a regular file'); return; }
let pathDir = this.context.filesDir; // 通过UIAbilityContext获取沙箱地址filesDir let filePath = pathDir + '/test.pdf'; // 以同步方法打开文件或目录。若文件不存在,则创建文件/读写打开 file = fs.openSync(filePath, fs.OpenMode.CREATE | fs.OpenMode.READ_WRITE) as fs.File; let bufsize = 4096; let buf = new ArrayBuffer(bufsize); // 用于保存读取到的文件数据的缓冲区。 let off = 0, len = 0, readLen = 0; // 动态调整目标文件的写入位置. 写入实际读取的字节数,累计已读取的总字节数 len = fs.readSync(srcFileDescriptor.fd, buf, { offset: srcFileDescriptor.offset + off, length: bufsize }); while (len) { readLen += len; fs.writeSync(file.fd, buf, { offset: off, length: len }); off = off + len; // 当剩余未读取的字节数小于当前分块大小时,调整bufsize为剩余大小,避免无效读取 if ((srcFileDescriptor.length - readLen) < bufsize) { bufsize = srcFileDescriptor.length - readLen; } len = fs.readSync(srcFileDescriptor.fd, buf, { offset: srcFileDescriptor.offset + off, length: bufsize }); }
filePreview.openPreview(this.uiContext, this.fileInfo).then(() => { console.info('openPreview success'); }).catch((err: BusinessError) => { console.error('openPreview failed, err = ' + err.message); });
import common from '@ohos.app.ability.common'; import fs from '@ohos.file.fs'; import { filePreview } from '@kit.PreviewKit'; import { BusinessError } from '@kit.BasicServicesKit'; @Entry @Component struct pdfPreviewDemo { context: common.UIAbilityContext = this.getUIContext().getHostContext() as common.UIAbilityContext; uiContext: Context = this.getUIContext().getHostContext() as common.Context; // 文件预览信息 private fileInfo: filePreview.PreviewInfo = { title: 'test.pdf', // 文件的标题名称 uri: 'file://com.example.myapplication/data/storage/el2/base/haps/entry/files/test.pdf', // 文件的uri,此处com.example.myapplication为包名,请按照应用的实际包名替换 mimeType: 'application/pdf' // 文件(夹)的媒体资源类型 }; copyFile() { let file: fs.File | undefined = undefined; try { // 获取resources/rawfile目录下rawfile文件所在HAP的文件描述符(fd) let srcFileDescriptor = this.context.resourceManager.getRawFdSync('test.pdf'); // 需要在rawfile目录下手动添加名为test.pdf的文件 // 判断文件是否是普通文件。true:是普通文件;false:不是普通文件。 if (!fs.statSync(srcFileDescriptor.fd).isFile()) { console.error('Not a regular file'); return; } let pathDir = this.context.filesDir; // 通过UIAbilityContext获取沙箱地址filesDir let filePath = pathDir + '/test.pdf'; // 以同步方法打开文件或目录。若文件不存在,则创建文件/读写打开 file = fs.openSync(filePath, fs.OpenMode.CREATE | fs.OpenMode.READ_WRITE) as fs.File; let bufsize = 4096; let buf = new ArrayBuffer(bufsize); // 用于保存读取到的文件数据的缓冲区。 let off = 0, len = 0, readLen = 0; // 动态调整目标文件的写入位置. 写入实际读取的字节数,累计已读取的总字节数 len = fs.readSync(srcFileDescriptor.fd, buf, { offset: srcFileDescriptor.offset + off, length: bufsize }); while (len) { readLen += len; fs.writeSync(file.fd, buf, { offset: off, length: len }); off = off + len; // 当剩余未读取的字节数小于当前分块大小时,调整bufsize为剩余大小,避免无效读取 if ((srcFileDescriptor.length - readLen) < bufsize) { bufsize = srcFileDescriptor.length - readLen; } len = fs.readSync(srcFileDescriptor.fd, buf, { offset: srcFileDescriptor.offset + off, length: bufsize }); } } catch (error) { console.error('openPreview failed, err = ' + error.message); } finally { // 关闭文件或目录 if (file) { fs.closeSync(file); } this.context.resourceManager.closeRawFdSync('test.pdf'); } } build() { Row() { Column() { Button('传到沙箱') .onClick(() => { this.copyFile(); }) .margin({ bottom: 10 }); Button('预览文件') .onClick(() => { filePreview.openPreview(this.uiContext, this.fileInfo).then(() => { console.info('openPreview success'); }).catch((err: BusinessError) => { console.error('openPreview failed, err = ' + err.message); }); }); } .width('100%'); } .height('100%'); } }