From dbd0d86c8327827e4e02ecdfc833f4ff6dd0a129 Mon Sep 17 00:00:00 2001 From: haoxiaohui Date: Wed, 7 May 2025 15:02:28 +0800 Subject: [PATCH] =?UTF-8?q?web=E8=8E=B7=E5=8F=96=E7=9B=B8=E6=9C=BA?= =?UTF-8?q?=E5=9B=BE=E7=89=87Sample=E5=A2=9E=E5=8A=A0=E5=88=86=E4=BA=AB?= =?UTF-8?q?=E5=8A=9F=E8=83=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: haoxiaohui --- .../Web/WebGetCameraImage/README.md | 53 ++++++++++++++++-- .../Web/WebGetCameraImage/build-profile.json5 | 6 +- .../Web/WebGetCameraImage/ohosTest.md | 13 +++-- .../main/ets/components/mainpage/MainPage.ets | 56 +++++++++++++++++++ .../src/main/resources/rawfile/camera.html | 45 ++++++++------- 5 files changed, 141 insertions(+), 32 deletions(-) diff --git a/code/BasicFeature/Web/WebGetCameraImage/README.md b/code/BasicFeature/Web/WebGetCameraImage/README.md index 009a50c4bc..2226d9ee15 100644 --- a/code/BasicFeature/Web/WebGetCameraImage/README.md +++ b/code/BasicFeature/Web/WebGetCameraImage/README.md @@ -13,7 +13,7 @@ 2. 完成拍照后,将图片在HTML的img标签中显示。 ### 实现思路 -1. 添加Web组件,设置[onShowFileSelector](https://gitee.com/openharmony/docs/blob/master/zh-cn/application-dev/reference/apis-arkweb/ts-basic-components-web.md#onshowfileselector9)属性,接收HTML页面中input的点击事件。在onShowFileSelector中调用invokeCamera接口,拉起原生相机进行拍照,并通过callback回调方法获得照片的uri。然后将uri放在[FileSelectorResult](https://gitee.com/openharmony/docs/blob/master/zh-cn/application-dev/reference/apis-arkweb/ts-basic-components-web.md#fileselectorresult9)中,通过event参数返回给HTML页面。源码参考[MainPage.ets](./webgetcameraimage/src/main/ets/components/mainpage/MainPage.ets)。 +1. 添加Web组件,设置[onShowFileSelector](https://gitee.com/openharmony/docs/blob/master/zh-cn/application-dev/reference/apis-arkweb/ts-basic-components-web.md#onshowfileselector9)和[javaScriptProxy](https://gitee.com/openharmony/docs/blob/master/zh-cn/application-dev/reference/apis-arkweb/ts-basic-components-web.md#javascriptproxy)属性,接收HTML页面中input的点击事件。在onShowFileSelector中调用invokeCamera接口,拉起原生相机进行拍照,并通过callback回调方法获得照片的uri。然后将uri放在[FileSelectorResult](https://gitee.com/openharmony/docs/blob/master/zh-cn/application-dev/reference/apis-arkweb/ts-basic-components-web.md#fileselectorresult9)中,通过event参数返回给HTML页面。源码参考[MainPage.ets](./webgetcameraimage/src/main/ets/components/mainpage/MainPage.ets)。 ```typescript Web({ src: $rawfile(LOCAL_HTML_PATH), controller: this.controller }) @@ -23,9 +23,15 @@ })) return true; }) + .javaScriptProxy({ + object: this.shareObject, + name: 'shareObject', + methodList: ['share'], + controller: this.controller + }) ``` -2. 实现invokeCamera接口,拉起原生相机,并通过callback回调方法返回拍照结果。源码参考[MainPage.ets](./webgetcameraimage/src/main/ets/components/mainpage/MainPage.ets)。 +2. 实现invokeCamera接口,拉起原生相机,通过callback回调方法返回拍照结果,并保存到应用沙箱中。源码参考[MainPage.ets](./webgetcameraimage/src/main/ets/components/mainpage/MainPage.ets)。 ```typescript invokeCamera(callback: (uri: string) => void) { @@ -44,13 +50,48 @@ let resultUri: string = data.want?.parameters?.resourceUri as string; if (callback && resultUri) { callback(resultUri); + this.copyFileToSandBox(pickerResult.resultUri); } } context.startAbilityForResult(want, result); } ``` -3. 在HTML页面中添加input标签,并在onChange属性中添加js方法,通过dom tree返回的描述事件相关信息的event对象接收ArkTS返回的照片,并显示在img标签上。源码参考[camera.html](./webgetcameraimage/src/main/resources/rawfile/camera.html)。 +3. 实现拉起分享面板接口,源码参考[MainPage.ets](./webgetcameraimage/src/main/ets/components/mainpage/MainPage.ets)。 + + ```typescript + shareObject: ShareClass = { + share: async () => { + if (!this.filePath) { + this.getUIContext().getPromptAction().showToast({ + message: '未选择任何文件' + }); + return; + } + let utdTypeId = uniformTypeDescriptor.getUniformDataTypeByFilenameExtension('.jpg', + uniformTypeDescriptor.UniformDataType.IMAGE); + let uri: string = fileUri.getUriFromPath(this.filePath); + let shareData: systemShare.SharedData = new systemShare.SharedData({ + utd: utdTypeId, + uri: uri, + title: 'Picture Title', + description: 'Picture Description' + }); + let controller: systemShare.ShareController = new systemShare.ShareController(shareData); + let context = this.getUIContext().getHostContext() as common.UIAbilityContext; + controller.show(context, { + selectionMode: systemShare.SelectionMode.SINGLE, + previewMode: systemShare.SharePreviewMode.DEFAULT + }).then(() => { + console.info('ShareController show success'); + }).catch((error: BusinessError) => { + console.error(`ShareController show error, code: ${error.code}, message: ${error.message}`); + }) + } + }; + ``` + +4. 在HTML页面中添加input标签,并在onChange属性中添加js方法,通过dom tree返回的描述事件相关信息的event对象接收ArkTS返回的照片,并显示在img标签上。添加sharePic()方法并在button标签上调用,使html可以拉起分享面板。源码参考[camera.html](./webgetcameraimage/src/main/resources/rawfile/camera.html)。 ```html +

图片预览

``` @@ -98,7 +143,7 @@ 1.本示例仅支持在标准系统上运行,支持设备:Phone。 -2.本示例为Stage模型,支持API12版本SDK,SDK版本号(API Version 12 Release)。 +2.本示例为Stage模型,支持API13版本SDK,SDK版本号(API Version 13 Release)。 3.本示例需要使用DevEco Studio 5.0.4 Release 才可编译运行。 diff --git a/code/BasicFeature/Web/WebGetCameraImage/build-profile.json5 b/code/BasicFeature/Web/WebGetCameraImage/build-profile.json5 index fbde639bf6..b6b62316cb 100644 --- a/code/BasicFeature/Web/WebGetCameraImage/build-profile.json5 +++ b/code/BasicFeature/Web/WebGetCameraImage/build-profile.json5 @@ -20,9 +20,9 @@ { "name": "default", "signingConfig": "default", - "compatibleSdkVersion": 12, - "compileSdkVersion": 12, - "runtimeOS": "OpenHarmony", + "compatibleSdkVersion": '5.0.1(13)', + "targetSdkVersion": '5.0.1(13)', + "runtimeOS": "HarmonyOS", "buildOption": { "strictMode": { "caseSensitiveCheck": true, diff --git a/code/BasicFeature/Web/WebGetCameraImage/ohosTest.md b/code/BasicFeature/Web/WebGetCameraImage/ohosTest.md index 0be3effcbc..27df3dc45b 100644 --- a/code/BasicFeature/Web/WebGetCameraImage/ohosTest.md +++ b/code/BasicFeature/Web/WebGetCameraImage/ohosTest.md @@ -2,8 +2,11 @@ ## 用例表 -| 测试功能 | 预置条件 | 输入 | 预期输出 | 是否自动 | 测试结果 | -|-------------|---------------|----------------------|----------------|------|------| -| 验证相机拉起功能 | 成功拉起应用,进入案例页面 | 1.点击选择文件按钮 | 1.成功拉起相机 | 否 | Pass | -| 验证相机拍照功能 | 成功拉起应用,进入案例页面 | 1.点击屏幕底部拍照按钮 | 1.成功拍照 | 否 | Pass | -| 验证Web展示照片功能 | 成功拉起应用,进入案例页面 | 1.成功后点击右侧确定按钮返回Web页面 | 1.成功在Web组件展示照片 | 否 | Pass | \ No newline at end of file +| 测试功能 | 预置条件 | 输入 | 预期输出 | 是否自动 | 测试结果 | +|-------------|---------------|-----------------------|----------------------------------|------|------| +| 验证相机拉起功能 | 成功拉起应用,进入案例页面 | 1.点击选择文件按钮 | 1.成功拉起相机 | 否 | Pass | +| 验证相机拍照功能 | 成功拉起应用,进入案例页面 | 1.点击屏幕底部拍照按钮 | 1.成功拍照 | 否 | Pass | +| 验证Web展示照片功能 | 成功拉起应用,进入案例页面 | 1.成功后点击右侧确定按钮返回Web页面 | 1.成功在Web组件展示照片 | 否 | Pass | +| 验证图片分享功能 | 成功拍照,返回Web页面 | 1.拍照成功后在Web页面点击分享图片按钮 | 1.成功拉起分享面板
2.显示图片缩略图及图片名称和描述 | 否 | Pass | +| 验证图片分享功能 | 成功拉起分享面板 | 1.选择一个应用点击 | 1.成功拉起二级分享面板
2.显示图片缩略图 | 否 | Pass | +| 验证图片分享功能 | 成功拉起二级分享面板 | 1.点击分享图片 | 1.分享成功,弹出提示框
2.返回Web页面 | 否 | Pass | \ No newline at end of file diff --git a/code/BasicFeature/Web/WebGetCameraImage/webgetcameraimage/src/main/ets/components/mainpage/MainPage.ets b/code/BasicFeature/Web/WebGetCameraImage/webgetcameraimage/src/main/ets/components/mainpage/MainPage.ets index 0af27478b0..a9645a3eba 100644 --- a/code/BasicFeature/Web/WebGetCameraImage/webgetcameraimage/src/main/ets/components/mainpage/MainPage.ets +++ b/code/BasicFeature/Web/WebGetCameraImage/webgetcameraimage/src/main/ets/components/mainpage/MainPage.ets @@ -17,6 +17,10 @@ import web_webview from '@ohos.web.webview'; import { BusinessError } from '@ohos.base'; import { camera, cameraPicker } from '@kit.CameraKit'; import { logger } from '../../utils/Logger'; +import { systemShare } from '@kit.ShareKit'; +import { uniformTypeDescriptor } from '@kit.ArkData'; +import { fileUri, fileIo as fs } from '@kit.CoreFileKit'; +import { common, Context } from '@kit.AbilityKit'; /** * 功能描述: 本示例介绍如何在HTML页面中拉起原生相机进行拍照,并获取返回的图片 @@ -47,9 +51,44 @@ class FileResult { } } +interface ShareClass { + // 分享方法,提供给HTML页面使用 + share: Function; +} + @Component export struct WebGetCameraImageView { controller: web_webview.WebviewController = new web_webview.WebviewController(); + filePath: string = ''; + shareObject: ShareClass = { + share: async () => { + if (!this.filePath) { + this.getUIContext().getPromptAction().showToast({ + message: '未选择任何文件' + }); + return; + } + let utdTypeId = uniformTypeDescriptor.getUniformDataTypeByFilenameExtension('.jpg', + uniformTypeDescriptor.UniformDataType.IMAGE); + let uri: string = fileUri.getUriFromPath(this.filePath); + let shareData: systemShare.SharedData = new systemShare.SharedData({ + utd: utdTypeId, + uri: uri, + title: 'Picture Title', + description: 'Picture Description' + }); + let controller: systemShare.ShareController = new systemShare.ShareController(shareData); + let context = this.getUIContext().getHostContext() as common.UIAbilityContext; + controller.show(context, { + selectionMode: systemShare.SelectionMode.SINGLE, + previewMode: systemShare.SharePreviewMode.DEFAULT + }).then(() => { + logger.info('ShareController show success'); + }).catch((error: BusinessError) => { + logger.error(`ShareController show error, code: ${error.code}, message: ${error.message}`); + }) + } + }; build() { // TODO:知识点:Web组件通过onShowFileSelector接口,处理具有“文件”输入类型的HTML表单,响应用户按下的“选择文件”按钮,并通过event对象,将选择的图片/文件路径返回给input标签中onchange属性调用的js方法。onShowFileSelector接口的用法详见官方文档 https://gitee.com/openharmony/docs/blob/master/zh-cn/application-dev/reference/apis-arkweb/ts-basic-components-web.md#onshowfileselector9 @@ -63,6 +102,12 @@ export struct WebGetCameraImageView { // 当返回值为true时,用户可以调用系统提供的弹窗能力。当回调返回false时,绘制的自定义弹窗无效。 return true; }) + .javaScriptProxy({ + object: this.shareObject, + name: 'shareObject', + methodList: ['share'], + controller: this.controller + }) } /** @@ -72,6 +117,8 @@ export struct WebGetCameraImageView { */ async invokeCamera(callback: (uri: string) => void) { try { + let pathDir = (this.getUIContext().getHostContext() as Context).filesDir; + this.filePath = pathDir + `/${new Date().getTime()}.jpg`; let pickerProfile: cameraPicker.PickerProfile = { cameraPosition: camera.CameraPosition.CAMERA_POSITION_UNSPECIFIED }; @@ -80,10 +127,19 @@ export struct WebGetCameraImageView { logger.info('the pick pickerResult is:' + JSON.stringify(pickerResult)); if (callback && pickerResult) { callback(pickerResult.resultUri); + this.copyFileToSandBox(pickerResult.resultUri); } } catch (error) { let err = error as BusinessError; logger.error(`the pick call failed. error code: ${err.code}`); } } + + copyFileToSandBox(uri: string) { + let sourceFile = fs.openSync(uri, fs.OpenMode.READ_ONLY); + let targetFile = fs.openSync(this.filePath, fs.OpenMode.READ_WRITE | fs.OpenMode.CREATE); + fs.copyFileSync(sourceFile.fd, targetFile.fd); + fs.close(sourceFile); + fs.close(targetFile); + } } \ No newline at end of file diff --git a/code/BasicFeature/Web/WebGetCameraImage/webgetcameraimage/src/main/resources/rawfile/camera.html b/code/BasicFeature/Web/WebGetCameraImage/webgetcameraimage/src/main/resources/rawfile/camera.html index f4cbe6c77c..8a0be1dbe0 100644 --- a/code/BasicFeature/Web/WebGetCameraImage/webgetcameraimage/src/main/resources/rawfile/camera.html +++ b/code/BasicFeature/Web/WebGetCameraImage/webgetcameraimage/src/main/resources/rawfile/camera.html @@ -17,25 +17,25 @@ - - + + @@ -55,8 +55,13 @@ document.getElementById('image_preview').style.display = 'block'; document.getElementById('image').style.display = 'block'; } + + function sharePic() { + shareObject.share(); + } - + +

图片预览

-- Gitee