HarmonyOS 使用photoAccessHelper保存图片,实际没有保存到相册?

示例代码如下:

let imgUrl = 'xxx.png'
const fileName = Date.now() + '.' + "png"
const imageLocal = FileUtil.getCacheDirPath('') + '/' + fileName
await this.saveNetImage(imgUrl, imageLocal)
/**
 * 获取缓存目录下的文件夹路径或文件路径。
 * @param dirPath 文件路径;支持完整路径和相对路径(download/wps/doc);dirPath传空字符串表示根目录
 * @param fileName 文件名(test.text);fileName传空字符串表示文件夹路径
 * @param blHap true:HAP级别文件路径、 false:App级别文件路径
 * @returns
 */
static getCacheDirPath(dirPath: string = "", fileName: string = "", blHap: boolean = true): string {
  let filePath = blHap ? getContext().cacheDir : getContext().getApplicationContext().cacheDir; //根目录
  if (StringUtil.isNotEmpty(dirPath)) {
    if (FileUtil.hasDirPath(dirPath)) { //路径中包含根目录,是完整路径。
      filePath = dirPath;
    } else { //路径中不包含根目录,拼接成完整路径。
      filePath = filePath + FileUtil.separator + dirPath;
    }
    if (!FileUtil.accessSync(filePath)) {
      FileUtil.mkdirSync(filePath) //如果文件夹不存在就创建
    }
  }
  if (StringUtil.isNotEmpty(fileName)) {
    filePath = filePath + FileUtil.separator + fileName;
  }
  return filePath;
}
/**
 * 通过http的request方法从网络下载图片资源
 */
async saveNetImage(imageUrl: string, imageLocal: string) {
  http.createHttp()// 显示网络图片的地址
    .request(imageUrl,
      async (error: BusinessError, data: http.HttpResponse) => {
        if (http.ResponseCode.OK === data.responseCode) {
          let imageBuffer: ArrayBuffer = data.result as ArrayBuffer;
          try {
            //保存到本地
            const file = fs.openSync(imageLocal, fs.OpenMode.READ_WRITE | fs.OpenMode.CREATE);
            // 写入文件
            fileIo.writeSync(file.fd, imageBuffer);
            // 关闭文件
            fileIo.closeSync(file.fd);

            //显示icon
            const imageSource: image.ImageSource = image.createImageSource(imageLocal);
            let decodingOptions: image.DecodingOptions = {
              editable: true,
              desiredPixelFormat: 3,
            }
            // 创建pixelMap
            let pixelMap = imageSource.createPixelMapSync(decodingOptions)
            this.imageSrc = pixelMap

            //保存到相册
            await this.saveToMul(imageLocal, imageBuffer)
          } catch (error2) {
            console.error("error is " + JSON.stringify(error2))
          }
        } else {
          console.error("error occurred when image downloaded!")
        }
      }
    )
}

async saveToMul(imageLocal: string, buffer: ArrayBuffer) {
  console.info('ShowAssetsCreationDialogDemo.');
  const file = fs.openSync(imageLocal, fs.OpenMode.READ_WRITE | fs.OpenMode.CREATE);
  // 写入文件
  fileIo.writeSync(file.fd, buffer);
  // 关闭文件
  fileIo.closeSync(file.fd);
  let phAccessHelper = photoAccessHelper.getPhotoAccessHelper(getContext())
  try {
    // 获取需要保存到媒体库的位于应用沙箱的图片/视频uri
    let srcFileUris: Array<string> = [
      imageLocal// 实际场景请使用真实的uri
    ];
    let photoCreationConfigs: Array<photoAccessHelper.PhotoCreationConfig> = [
      {
        title: 'test2', // 可选
        fileNameExtension: 'jpg',
        photoType: photoAccessHelper.PhotoType.IMAGE,
        subtype: photoAccessHelper.PhotoSubtype.DEFAULT, // 可选
      }
    ];
    let desFileUris: Array<string> = await phAccessHelper.showAssetsCreationDialog(srcFileUris, photoCreationConfigs);
    console.info('showAssetsCreationDialog success, data is ' + desFileUris);
    let predicates: dataSharePredicates.DataSharePredicates = new dataSharePredicates.DataSharePredicates();
    predicates.equalTo('uri', desFileUris[0]);
    let fetchOptions: photoAccessHelper.FetchOptions = {
      fetchColumns: [],
      predicates: predicates
    };
    // 通过返回的媒体库uri获取对应的PhotoAsset对象
    let fetchResult: photoAccessHelper.FetchResult<photoAccessHelper.PhotoAsset> = await phAccessHelper.getAssets(
      fetchOptions);
    let photoAssets: Array<photoAccessHelper.PhotoAsset> = await fetchResult.getAllObjects();
    for (let i = 0; i < photoAssets.length; i++) {
      // 将应用沙箱文件内容写入到媒体库
      let changeRequest: photoAccessHelper.MediaAssetChangeRequest =
        new photoAccessHelper.MediaAssetChangeRequest(photoAssets[i]);
      changeRequest.addResource(photoAccessHelper.ResourceType.IMAGE_RESOURCE, srcFileUris[i]);
      phAccessHelper.applyChanges(changeRequest);
    }
  } catch (err) {
    console.error('showAssetsCreationDialog failed, errCode is ' + err.code + ', errMsg is ' + err.message);
  }
}
阅读 469
1 个回答

参考示例:

import { BusinessError, request } from '@kit.BasicServicesKit';
import { photoAccessHelper } from '@kit.MediaLibraryKit';
import { fileIo, fileUri } from '@kit.CoreFileKit';
import promptAction from '@ohos.promptAction';

let context = getContext(this);
let phAccessHelper = photoAccessHelper.getPhotoAccessHelper(context);

@Entry
@Component
struct ImagePage {
  @State src: string = 'xxx.png'
  @State isDownload: boolean = false
  @State total: number = 0
  @State value: number = 0

  build() {
    Column() {
      Image(this.src).height(100).width(100)

      Button('保存').onClick(() => {
        this.saveImage(this.src)
      })

      if (this.isDownload) {
        Progress({ value: this.value, total: this.total, type: ProgressType.Linear }).margin({ top: 20 })
      }
    }
    .align(Alignment.BottomEnd).width('100%').height('100%').backgroundColor(Color.White)
  }

  //保存图片
  async saveImage(imageURL: string) {
    try {
      let filePath = context.cacheDir + '/test.png'
      fileIo.access(filePath).then(async (result: boolean) => {
        if (result) {
          this.total = 0
          this.value = 0
          await fileIo.unlink(filePath)
        }
      })

      let uri = fileUri.getUriFromPath(filePath);
      let srcFileUris: Array<string> = [
        uri// 实际场景请使用真实的uri
      ];
      let photoCreationConfigs: Array<photoAccessHelper.PhotoCreationConfig> = [
        {
          title: 'test', // 可选
          fileNameExtension: 'png',
          photoType: photoAccessHelper.PhotoType.IMAGE,
          subtype: photoAccessHelper.PhotoSubtype.DEFAULT, // 可选
        }
      ];
      let desFileUris: Array<string> = await phAccessHelper.showAssetsCreationDialog(srcFileUris, photoCreationConfigs);

      promptAction.showToast({
        message: "开始下载"
      })

      request.downloadFile(context, { url: imageURL, filePath: filePath }).then((data: request.DownloadTask) => {
        let downloadTask = data;
        let progressCallback = (receivedSize: number, totalSize: number) => {
          if (!this.isDownload) {
            this.isDownload = !this.isDownload
          }
          if (this.total === 0) {
            this.total = totalSize
          }
          this.value = receivedSize
          console.log('正在下载')
        };
        downloadTask.on('progress', progressCallback);

        downloadTask.on('complete', async () => {
          console.log('下载完成')

          let imageFile = fileIo.openSync(desFileUris[0], fileIo.OpenMode.CREATE | fileIo.OpenMode.READ_WRITE);
          await fileIo.copyFile(filePath, imageFile.fd, 0).then(() => {
            promptAction.showToast({
              message: "下载成功,已保存到相册"
            })
            console.log('保存成功')
          })
          await fileIo.close(imageFile.fd)
        })
      }).catch((err: BusinessError) => {
        console.error(`Failed to request the download. Code: ${err.code}, message: ${err.message}`);
      })
    } catch (err) {
      console.error('showAssetsCreationDialog failed, errCode is ' + err.code + ', errMsg is ' + err.message);
    }
  }
}