在其它手機端,若想儲存圖片到相簿,需要申請對應的許可權,而鴻蒙中對應的許可權為受限開放許可權,普通應用一般不讓申請,這個時候我們可以使用安全儲存控制元件來臨時申請許可權,用於儲存圖片到相簿。
受限開放許可權
應用許可權分為三類,一類是對所有應用開放,所有應用均可申請使用;一類是受限開放許可權,僅少量符合特殊場景的應用可在透過審批後,使用受限許可權;最後一類是僅對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在本地真實存在。