HarmonyOS鸿蒙Next中使用photoAccessHelper.PhotoViewPicker选取图片后无法把选取的图片保存到沙箱路径下

发布于 1周前 作者 phonegap100 来自 鸿蒙OS

HarmonyOS鸿蒙Next中使用photoAccessHelper.PhotoViewPicker选取图片后无法把选取的图片保存到沙箱路径下

class MediaDataHandler implements photoAccessHelper.MediaAssetDataHandler<ArrayBuffer> {
  private toPath: string;

  constructor(toPath: string) {
    this.toPath = toPath;
  }

  onDataPrepared(data: ArrayBuffer, map?: Map<string, string>) {
    if (data === undefined) {
      console.error('Error occurred when preparing data');
      return;
    }
    console.info('on image data prepared'); // 应用自定义对资源数据的处理逻辑 // 这里this是undefined IO
      .writeContentsSync(this.toPath, data);
  }
}

更多关于HarmonyOS鸿蒙Next中使用photoAccessHelper.PhotoViewPicker选取图片后无法把选取的图片保存到沙箱路径下的实战系列教程也可以访问 https://www.itying.com/category-93-b0.html

3 回复

在类最外层定义目标路径destPath赋值可以正常保存文件

const context = this.getContext();
let phAccessHelper = photoAccessHelper.getPhotoAccessHelper(context);
let destPath: string;

class MediaDataHandler implements photoAccessHelper.MediaAssetDataHandler<ArrayBuffer> {
  onDataPrepared(data: ArrayBuffer, map?: Map<string, string>) {
    if (data === undefined) {
      console.error('Error occurred when preparing data');
      return;
    }
    // 应用自定义对资源数据的处理逻辑
    // this undefined???
    const file = fs.openSync(destPath, fs.OpenMode.CREATE | fs.OpenMode.READ_WRITE);
    fs.writeSync(file.fd, data);
    fs.fsyncSync(file.fd);
    fs.closeSync(file.fd);
  }
}

export class PhotoAccessPicker {
  static pickFile(saveDir: string, acceptTypes: photoAccessHelper.PhotoViewMIMETypes, resultHandler: (error?: BusinessError, fileName?: string|null) => void) {
    if (fs.accessSync(saveDir) === false || fs.statSync(saveDir).isDirectory() === false) {
      fs.mkdirSync(saveDir, true);
    }
    const photoSelectOptions = new photoAccessHelper.PhotoSelectOptions();
    photoSelectOptions.MIMEType = acceptTypes; // 过滤选择媒体文件类型
    photoSelectOptions.maxSelectNumber = 1; // 选择媒体文件的最大数目

    let uris: Array<string> = [];
    const photoViewPicker = new photoAccessHelper.PhotoViewPicker();
    photoViewPicker.select(photoSelectOptions).then((photoSelectResult: photoAccessHelper.PhotoSelectResult) => {
      uris = photoSelectResult.photoUris;
      console.info('photoViewPicker.select to file succeed and uris are:' + uris);
      if (uris.length === 0) {
        resultHandler(undefined, null);
        return
      }

      const uri = uris[0];
      const fileName = new Uri.URI(uri).getLastSegment();
      const dstPath = `${saveDir}/${fileName}`;
      PhotoAccessPicker.readFromUriToPath(uri, dstPath)
        .then(() => {
          resultHandler(undefined, fileName);
        })
        .catch((err: BusinessError) => {
          resultHandler(err, undefined)
        })
    }).catch((err: BusinessError) => {
      // console.error(`Invoke photoViewPicker.select failed, code is ${err.code}, message is ${err.message}`);
      resultHandler(err, undefined);
    })
  }

  /**
   * 需保证此uri已存在
   * @param uri
   */
  private static async readFromUriToPath(uri: string, toPath: string) {
    destPath= toPath;
    let predicates: dataSharePredicates.DataSharePredicates = new dataSharePredicates.DataSharePredicates();
    predicates.equalTo(photoAccessHelper.PhotoKeys.URI, uri.toString());
    let fetchOptions: photoAccessHelper.FetchOptions = {
      fetchColumns: [photoAccessHelper.PhotoKeys.TITLE],
      predicates: predicates
    };

    try {
      let fetchResult: photoAccessHelper.FetchResult<photoAccessHelper.PhotoAsset> = await phAccessHelper.getAssets(fetchOptions);
      let photoAsset: photoAccessHelper.PhotoAsset = await fetchResult.getFirstObject();
      console.info('getAssets photoAsset.uri : ' + photoAsset.uri);
      // 获取属性值,以标题为例;对于非默认查询的属性,get前需要在fetchColumns中添加对应列名
      console.info('title : ' + photoAsset.get(photoAccessHelper.PhotoKeys.TITLE));
      // 请求图片资源数据
      let requestOptions: photoAccessHelper.RequestOptions = {
        deliveryMode: photoAccessHelper.DeliveryMode.HIGH_QUALITY_MODE,
      }
      const a = await photoAccessHelper.MediaAssetManager.requestImageData(context, photoAsset, requestOptions, new MediaDataHandler());
      console.info('requestImageData successfully');
      fetchResult.close();
    } catch (err) {
      console.error('getAssets failed with err: ' + err);
    }
  }
}

更多关于HarmonyOS鸿蒙Next中使用photoAccessHelper.PhotoViewPicker选取图片后无法把选取的图片保存到沙箱路径下的实战系列教程也可以访问 https://www.itying.com/category-93-b0.html


在HarmonyOS鸿蒙Next中,使用photoAccessHelper.PhotoViewPicker选取图片后,无法直接将图片保存到沙箱路径下,这是因为PhotoViewPicker返回的是一个PhotoViewPickerResult对象,而不是直接的图片文件路径。PhotoViewPickerResult包含了图片的URI,需要通过PhotoAccessHelpergetFileAssets方法来获取图片的FileAsset对象,然后使用FileAssetopen方法读取文件内容并保存到沙箱路径。

具体步骤如下:

  1. 使用PhotoViewPicker选取图片后,获取PhotoViewPickerResult对象。
  2. 通过PhotoViewPickerResultgetPhotoViewPickerResult方法获取图片的URI。
  3. 使用PhotoAccessHelpergetFileAssets方法,传入URI获取FileAsset对象。
  4. 使用FileAssetopen方法读取文件内容。
  5. 将读取到的文件内容写入到沙箱路径下的文件中。

需要注意的是,沙箱路径的访问权限需要在config.json中配置相应的权限声明,确保应用有权限读写沙箱路径。

在HarmonyOS鸿蒙Next中,使用photoAccessHelper.PhotoViewPicker选取图片后,需通过PhotoAsset对象获取图片数据并保存到沙箱路径。首先,确保已获取PhotoAsset对象,然后使用PhotoAsset.getReadStream()方法读取图片数据流。接着,使用fs模块将数据流写入沙箱路径。具体代码如下:

const fs = require('fs');
const photoAccessHelper = require('@ohos.file.photoAccessHelper');

let photoViewPicker = new photoAccessHelper.PhotoViewPicker();
photoViewPicker.select().then(async (photoAssets) => {
    let photoAsset = photoAssets[0];
    let readStream = await photoAsset.getReadStream();
    let writeStream = fs.createWriteStream('/沙箱路径/文件名.jpg');
    readStream.pipe(writeStream);
}).catch((err) => {
    console.error('Failed to select photo:', err);
});

确保沙箱路径存在且具有写入权限。

回到顶部
AI 助手
你好,我是IT营的 AI 助手
您可以尝试点击下方的快捷入口开启体验!