HarmonyOS 安全控件的使用 —— (2) 保存控件的使用

190 阅读1分钟

保存控件允许临时使用权限,不需要重复性通过权限弹窗申请权限。当用户点击该控件时,应用会获得10秒内访问媒体库特权接口的授权。

一、组件截图

保存控件通常用于保存图片或视频等,这里以图片为例,保存图片时可以配合截图工具一起使用,在原生鸿蒙中每个组件都可以使用.id("")来给组件设定一个组件名称,这个组件名称可以用户相对布局也可以用于组件截图。

这里以最简单常用的方式来实现组件截图。

Screenshot.gif

这个组件中有TexT()和Image()两个组件,我们给外面column组件组件设置.id("root"),通过componentSnapshot.get("root")来获取"root"这个id对应的组件,再进行展示即可完成组件截图。

import { componentSnapshot } from '@kit.ArkUI'
import { image } from '@kit.ImageKit'

@Entry
@Component
struct SnapshotExample {
  @State pixmap: image.PixelMap | undefined = undefined

  build() {
    Column() {
      Column() {
        Text('home')
          .fontSize(16)
        Image($r('app.media.home'))
          .autoResize(true)
          .width(200)
          .height(200)
          .margin(5)
      }
      .id("root") //设置id
      .backgroundColor(Color.White)

      Button("点击截图")
        .onClick(async () => {
          const pixmap = await componentSnapshot.get("root") //截取对应id的组件图片
          this.pixmap = pixmap //把截取到的组件图片赋给全局
        })
        .margin(10)
      Image(this.pixmap)//展现截到的组件
        .width(300)
        .height(400)
        .border({ color: Color.Black, width: 2 })
        .margin(5)
    }
    .width('100%')
    .height('100%')
    .alignItems(HorizontalAlign.Center)
  }
}

二、保存控件

调用保存控件,在点击时会根据是否有对应权限做出对应处理。 保存控件外观有严格要求,如果出现遮挡、透明、超出手机边界等会在测试上线时出现上线失败等问题。

ScreenshotTOSave.gif

``` SaveButton() .onClick(async (event: ClickEvent, result: SaveButtonOnClickResult) => { if (result === SaveButtonOnClickResult.SUCCESS) { // 免去权限申请和权限请求等环节,获得临时授权,保存对应图片 this.savePixelMapToAlbum() } else { promptAction.showToast({ message: '设置权限失败!' }) } }) ``` 当用户首次点击应用中的保存控件,系统将弹窗请求用户授权。如果用户点击“取消”,弹窗消失,应用无授权,用户再次点击保存控件时,将会重新弹窗;如果用户点击“允许”,弹窗消失,应用将被授予临时保存权限,此后点击该应用的保存控件将不会弹窗。

应用在onClick()触发回调到调用媒体库特权接口的时间间隔不能大于10秒。

三、完整代码(组件截图 -> 图片保存)

import { componentSnapshot, promptAction } from '@kit.ArkUI'
import { image } from '@kit.ImageKit'
import { photoAccessHelper } from '@kit.MediaLibraryKit';
import { fileIo } from '@kit.CoreFileKit';

@Entry
@Component
struct SnapshotExample {
  @State pixmap: image.PixelMap | undefined = undefined

  async savePixelMapToAlbum() {
    try {
      const context = getContext()
      console.log('hello context', JSON.stringify(context));
      const helper = photoAccessHelper.getPhotoAccessHelper(getContext());
      const uri = await helper.createAsset(photoAccessHelper.PhotoType.IMAGE, 'jpeg');
      const file = await fileIo.open(uri, fileIo.OpenMode.READ_WRITE | fileIo.OpenMode.CREATE);
      const imagePackerApi = image.createImagePacker();
      // 保存图片到相册,保存时可以做图片压缩
      await imagePackerApi.packToFile(this.pixmap, file.fd, { format: 'image/jpeg', quality: 98 })
      await imagePackerApi.release()
      fileIo.close(file.fd);
      promptAction.showToast({ message: '已保存至相册!' });
    } catch (error) {
      console.error('hello context' + JSON.stringify(error))
    }
  }

  build() {
    Column() {
      Column() {
        Text('home')
          .fontSize(16)
        Image($r('app.media.home'))
          .autoResize(true)
          .width(200)
          .height(200)
          .margin(5)
      }
      .id("root")
      .backgroundColor(Color.White)

      Button("点击截图")
        .onClick(async () => {
          const pixmap = await componentSnapshot.get("root")
          this.pixmap = pixmap
        })
        .margin(10)

      Image(this.pixmap)
        .width(300)
        .height(400)
        .border({ color: Color.Black, width: 2 })
        .margin(5)

      SaveButton()
        .onClick(async (event: ClickEvent, result: SaveButtonOnClickResult) => {
          if (result === SaveButtonOnClickResult.SUCCESS) {
            // 免去权限申请和权限请求等环节,获得临时授权,保存对应图片
            this.savePixelMapToAlbum()
          } else {
            promptAction.showToast({ message: '设置权限失败!' })
          }
        })
    }
    .width('100%')
    .height('100%')
    .alignItems(HorizontalAlign.Center)
  }
}