1/* 2 * Copyright (c) 2022 Huawei Device Co., Ltd. 3 * Licensed under the Apache License, Version 2.0 (the "License"); 4 * you may not use this file except in compliance with the License. 5 * You may obtain a copy of the License at 6 * 7 * http://www.apache.org/licenses/LICENSE-2.0 8 * 9 * Unless required by applicable law or agreed to in writing, software 10 * distributed under the License is distributed on an "AS IS" BASIS, 11 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 * See the License for the specific language governing permissions and 13 * limitations under the License. 14 */ 15 16import prompt from '@ohos.prompt' 17import fileio from '@ohos.fileio' 18import display from '@ohos.display' 19import screenshot from '@ohos.screenshot' 20import image from '@ohos.multimedia.image' 21import photoAccessHelper from '@ohos.file.photoAccessHelper'; 22import Logger from '../util/Logger' 23import MediaUtils from '../feature/MediaUtils' 24import { ShareConst } from '../util/ShareConst' 25 26const TAG: string = 'ShareUtils' 27 28export class ShareUtils { 29 private context: any 30 31 constructor(context) { 32 this.context = context 33 } 34 35 convertResourceToString(resource: Resource) { 36 return this.context.resourceManager.getStringSync(resource); 37 } 38 39 // 分享图片、链接 40 async startAbility(contextCaller, title: string, srcImage: string) { 41 try { 42 Logger.info(TAG, `begin to start ability explicitly, ${JSON.stringify(contextCaller)}`) 43 await contextCaller.startAbility({ 44 bundleName: "com.samples.chat", 45 abilityName: 'EntryAbility', 46 parameters: { // 分享的内容 47 "kindId": ShareConst.KIND_ID_NUMBER, 48 "text": title, 49 "srcImg": srcImage 50 } 51 }) 52 Logger.info(TAG, `explicit start ability succeed`) 53 } catch (error) { 54 prompt.showToast({ 55 message: this.convertResourceToString($r('app.string.start_chat_fail')), 56 duration: ShareConst.DURATION_NUMBER 57 }) 58 Logger.error(TAG, `explicit start ability failed with ${error.code}`) 59 } 60 Logger.info(TAG, `Callback when the second button is clicked`) 61 } 62 63 // 分享图片文件 64 async savePicture(data: image.PixelMap, contextCaller) { 65 let path 66 let fdTemp 67 try { 68 Logger.info(TAG, `savePicture`) 69 // 处理图片的格式 70 let packOpts: image.PackingOption = { 71 format: 'image/jpeg', 72 quality: ShareConst.QUALITY_NUMBER 73 } 74 // 创建图片打包 75 let imgPackerApi = image.createImagePacker() 76 let arrayBuffer = await imgPackerApi.packing(data, packOpts) 77 // 创建空的文件路径 78 path = contextCaller.filesDir 79 fdTemp = fileio.openSync(`${path}/phone.png`, ShareConst.FLAGS_NUMBER, ShareConst.MODE_NUMBER) // 新的文件 80 Logger.info(TAG, `FileIoPath:${path}, fileio fdImg: ${fdTemp}`) 81 // 路径格式: data/storage/el2/base/haps/entry/files 82 let numFromFd = await fileio.write(fdTemp, arrayBuffer) // arrayBuffer是内容 83 Logger.info(TAG, `savePicture number: ${numFromFd}`) 84 } catch (error) { 85 Logger.info(TAG, `savePicture error: ${JSON.stringify(error)}`) 86 } 87 88 await fileio.close(fdTemp) 89 fdTemp = fileio.openSync(`${path}/phone.png`) // 新的文件 90 Logger.info(TAG, `shareBefore fdImg: ${fdTemp}`) 91 return fdTemp 92 } 93 94 async shareImageStartAbility(fdImage: number, contextCaller) { 95 Logger.info(TAG, `begin to shareFileStartAbility`) 96 try { 97 Logger.info(TAG, `${JSON.stringify(contextCaller)}`) 98 let buf = new ArrayBuffer(ShareConst.BUFFER_LENGTH); 99 let opt = { 100 offset: ShareConst.OFFSET_NUMBER, 101 position: ShareConst.POSITION_NUMBER, 102 length: ShareConst.LENGTH_NUMBER 103 } 104 try { 105 let readOut = await fileio.readSync(fdImage, buf, opt) 106 Logger.info(TAG, `y, readOutBefore: ${JSON.stringify(readOut)}}`) 107 Logger.info(TAG, `y, buf: ${JSON.stringify(buf)}}`) 108 let view = new Uint32Array(buf) 109 Logger.info(TAG, `shareImageStartAbility, view: ${JSON.stringify(view)}`) 110 } catch (error) { 111 Logger.info(TAG, `shareImageStartAbility, error: ${JSON.stringify(error)}`) 112 } 113 114 let want = { 115 bundleName: 'com.samples.chat', 116 abilityName: 'EntryAbility', 117 parameters: { // 分享的内容 118 'kindId': ShareConst.KIND_ID, 119 'keyFd': { 'type': 'FD', 'value': fdImage } 120 } 121 } 122 await contextCaller.startAbility(want) 123 Logger.info(TAG, `shareFileStartAbility succeed`) 124 } catch (error) { 125 prompt.showToast({ 126 message: this.convertResourceToString($r("app.string.start_chat_fail")), 127 duration: ShareConst.DURATION_NUMBER 128 }) 129 Logger.error(TAG, `shareFileStartAbility failed with ${error.code}`) 130 } 131 } 132 133 async getScreen(isLand: boolean, contextCaller) { 134 let data: image.PixelMap 135 136 let screenShotHeight: number 137 let screenShotWeight: number 138 let fdImg: number 139 try { 140 // 截屏图片 141 let defaultDisplay = await display.getDefaultDisplay() 142 Logger.info(TAG, `getScreen,isFullScreen`) 143 screenShotWeight = defaultDisplay.width * 0.6 144 screenShotHeight = defaultDisplay.height * 0.75 145 let screenShotRectLeft = (defaultDisplay.width - screenShotWeight) / 2 146 let screenShotTop = (defaultDisplay.height - screenShotHeight) / 2 + ShareConst.TITLE_HEIGHT 147 let smScreenshotOptions: screenshot.ScreenshotOptions = { 148 screenRect: { // 表示截取图像的区域,不传值默认为全屏。以下参数仅支持number 149 left: screenShotRectLeft, 150 top: screenShotTop, // 二维码保存时图片顶部距离屏幕顶部边缘距离 151 width: screenShotWeight, 152 height: screenShotHeight 153 }, 154 imageSize: { // 表示截取图像的大小,不传值默认为全屏。 155 width: screenShotWeight, 156 height: screenShotHeight 157 }, 158 rotation: ShareConst.ROTATION_NUMBER, 159 displayId: ShareConst.DISPLAY_ID 160 } 161 let lgScreenshotOptions: screenshot.ScreenshotOptions = { 162 screenRect: { // 表示截取图像的区域,不传值默认为全屏。以下参数仅支持number 163 left: ShareConst.LEFT_NUMBER, 164 top: ShareConst.TOP_NUMBER, // 二维码保存时图片顶部距离屏幕顶部边缘距离 165 width: ShareConst.WIDTH, 166 height: ShareConst.HEIGHT 167 }, 168 imageSize: { // 表示截取图像的大小,不传值默认为全屏。 169 width: ShareConst.WIDTH, 170 height: ShareConst.HEIGHT 171 }, 172 rotation: ShareConst.ROTATION_NUMBER, 173 displayId: ShareConst.DISPLAY_ID 174 } 175 if (isLand) { 176 data = await screenshot.save(smScreenshotOptions) 177 } else { 178 data = await screenshot.save(lgScreenshotOptions) 179 } 180 } catch (error) { 181 Logger.error(TAG, `getScreen error : ${error}`) 182 } 183 // 保存图片 184 fdImg = await this.savePicture(data, contextCaller) 185 prompt.showToast({ 186 "message": this.convertResourceToString($r('app.string.shot_prompt')), 187 "duration": ShareConst.DURATION 188 }) 189 setTimeout(() => { 190 this.shareImageStartAbility(fdImg, contextCaller) 191 }, 1500) 192 } 193 194 // 分享视频文件 195 async startApp(fd: number, fileAssetName: string, contextCaller) { 196 Logger.info(TAG, `startApp:startApp fd : ${fd}`) 197 try { 198 let want = { 199 bundleName: 'com.example.revievedvideo', 200 abilityName: 'MainAbility', // 未设置ability名称,代表该want为隐式, 201 parameters: { // 分享的内容 202 'fileAssetName': fileAssetName, 203 'keyFd': { 'type': 'FD', 'value': fd } 204 } 205 } 206 await contextCaller.startAbility(want) 207 } catch (error) { 208 Logger.info(TAG, `startApp: startAbility error: ${JSON.stringify(error)}`) 209 } 210 } 211 212 async queryMedia(mediaList: Array<photoAccessHelper.PhotoAsset>, fileAssetName: string) { 213 let fdNum: number 214 for (let i = 0; i < mediaList.length; i++) { 215 Logger.info(TAG, `queryMedia: file.uri: ${mediaList[i].uri}, file.name: ${mediaList[i].displayName}`) 216 try { 217 if (mediaList[i].displayName === fileAssetName) { 218 let fileAsset = mediaList[i] 219 fdNum = await fileAsset.open('Rw') 220 Logger.info(TAG, `queryMedia:queryMedia fd: ${fdNum}`) 221 break 222 } 223 } catch (error) { 224 Logger.info(TAG, `queryMedia: ERROR: ${error}`) 225 } 226 } 227 return fdNum 228 } 229 230 async getFileData(contextCaller) { 231 let mediaList: Array<photoAccessHelper.PhotoAsset> = []; 232 let fileAssets = MediaUtils.getFileAssetsFromType(photoAccessHelper.PhotoType.VIDEO, this.context); 233 let fileAssetName: string = 'video_4.mp4' 234 let fdVideo 235 mediaList = await MediaUtils.getFileAssetsFromType(photoAccessHelper.PhotoType.VIDEO, this.context); 236 Logger.info(TAG, `getFileData: getFileData mediaList: ${mediaList}`) 237 fdVideo = await this.queryMedia(mediaList, fileAssetName) 238 Logger.info(TAG, `getFileData: getFileData fd: ${fdVideo}`) 239 await this.startApp(fdVideo, fileAssetName, contextCaller) 240 } 241}