鴻蒙儲存圖片到相簿

龙儿筝發表於2024-12-31

在其它手機端,若想儲存圖片到相簿,需要申請對應的許可權,而鴻蒙中對應的許可權為受限開放許可權,普通應用一般不讓申請,這個時候我們可以使用安全儲存控制元件來臨時申請許可權,用於儲存圖片到相簿。

受限開放許可權

應用許可權分為三類,一類是對所有應用開放,所有應用均可申請使用;一類是受限開放許可權,僅少量符合特殊場景的應用可在透過審批後,使用受限許可權;最後一類是僅對MDM(Mobile Device Management)裝置管理應用開放。

儲存圖片到相機涉及到的許可權是ohos.permission.WRITE_IMAGEVIDEO,僅特殊場景與功能才可申請此許可權,例如應用需要克隆、備份或同步圖片/影片類檔案,其它場景下使用安全控制元件來臨時申請許可權。

使用安全控制元件儲存本地圖片到相機

我們先使用安全控制元件讓使用者點選臨時獲取許可權,獲取到許可權後,再使用photoAccessHelper來將我們本地的圖片儲存在相簿,示例如下

import { photoAccessHelper } from '@kit.MediaLibraryKit'

@Entry
@ComponentV2
struct Index {

  build() {
    Column() {
      SaveButton({ icon: SaveIconStyle.LINES, text: SaveDescription.SAVE_TO_GALLERY, buttonType: ButtonType.Capsule })
        .onClick(() => {
          this.savePhotoToGallery().then(() => {
            this.getUIContext().getPromptAction().showToast({ message: '儲存成功' })
          }).catch((err: Error) => {
            this.getUIContext().getPromptAction().showToast({ message: err.message })
          })
        })
    }
  }

  public async savePhotoToGallery(): Promise<void> {
    const ctx = getContext()
    const helper = photoAccessHelper.getPhotoAccessHelper(ctx)
    const src = ctx.resourceDir + '/icon.png'
    const request = photoAccessHelper.MediaAssetChangeRequest.createImageAssetRequest(ctx, src)
    return helper.applyChanges(request)
  }
}

以上示例請保證icon.png在本地真實的存在。當我們使用helper呼叫applyChanges時,因為是在安全控制元件點選後呼叫的,臨時獲取許可權,可以正常執行,若不在安全控制元件內,則需保證已獲取對應的許可權。

## 使用安全控制元件儲存服務端圖片到相機

服務端圖片我們一般使用下載服務將圖片下載到本地,若本地不需要備份,則直接將下載好的圖片buffer儲存到相簿即可。我們將本地圖片轉成buffer來模擬服務端下載後的圖片,再使用photoAccessHelper建立一個相簿圖片資源,並將我們的圖片buffer寫入到這個圖片資源中,就可以將圖片儲存到相簿了,示例如下

import { photoAccessHelper } from '@kit.MediaLibraryKit'
import fs from '@ohos.file.fs'
@Entry
@ComponentV2
struct Index {

  build() {
    Column() {
      SaveButton({ icon: SaveIconStyle.LINES, text: SaveDescription.SAVE_TO_GALLERY, buttonType: ButtonType.Capsule })
        .onClick(() => {
          this.savePhotoToGallery().then(() => {
            this.getUIContext().getPromptAction().showToast({ message: '儲存成功' })
          }).catch((err: Error) => {
            this.getUIContext().getPromptAction().showToast({ message: err.message })
          })
        })
    }
  }

  public async savePhotoToGallery(): Promise<void> {
    const ctx = getContext()
    const helper = photoAccessHelper.getPhotoAccessHelper(ctx)
    return Promise.all([helper.createAsset(photoAccessHelper.PhotoType.IMAGE, 'png').then((uri) => {
      return fs.open(uri, fs.OpenMode.READ_WRITE | fs.OpenMode.CREATE)
    }), ctx.resourceManager.getMediaContent($r('app.media.app_icon').id, 0)]).then((array) => {
      fs.writeSync(array[0].fd, array[1].buffer)
      fs.closeSync(array[0].fd)
    })
  }
}

使用儲存確認彈窗儲存圖片

前面的方式都是強依賴於安全控制元件,但在有些場景下,我們沒辦法使用安全控制元件,比如在H5頁面中,再比如在Flutter頁面中等等,這個時候我們可以藉助儲存確認彈窗來儲存圖片。當我們透過photoAccessHelper呼叫showAssetsCreationDialog時,系統會彈出一個確認彈窗,使用者點選允許,則我們可以將圖片儲存到相簿,若使用者點選禁止,則不能儲存圖片到相簿。使用這種方式,我們就不用強依賴於安全控制元件了,示例如下

import { photoAccessHelper } from '@kit.MediaLibraryKit'
import fs from '@ohos.file.fs'

@Entry
@ComponentV2
struct Index {
  @Local isShowHome: boolean = false

  build() {
    Column() {
      Button('儲存圖片到相簿').onClick(()=>{
        this.savePhotoToGallery().then(() => {
          this.getUIContext().getPromptAction().showToast({ message: '儲存成功' })
        }).catch((err: Error) => {
          this.getUIContext().getPromptAction().showToast({ message: err.message })
        })
      })
    }
  }

  public async savePhotoToGallery(): Promise<void> {
    const ctx = getContext()
    const helper = photoAccessHelper.getPhotoAccessHelper(ctx)
    const src = ctx.resourceDir + '/icon.png'
    const desFileUris = await helper.showAssetsCreationDialog([src], [{
      title: 'test',
      fileNameExtension: 'png',
      photoType: photoAccessHelper.PhotoType.IMAGE
    }])
    const desFile = fs.openSync(desFileUris[0], fs.OpenMode.WRITE_ONLY)
    const srcFile = fs.openSync(src, fs.OpenMode.READ_ONLY)
    fs.copyFileSync(srcFile.fd, desFile.fd)
    fs.closeSync(srcFile)
    fs.closeSync(desFile)
  }
}

以上示例請儲存icon.png在本地真實存在。

相關文章