鸿蒙系统下适配wechat_assets_picker无法选择以及上传问题

在HarmonyOS(鸿蒙系统)环境下,flutter开发者使用wechat_assets_picker插件进行图片/视频选择时,可能会遇到以下问题:

  1. 无法正常弹出媒体选择界面
  2. 选择后无法正确返回文件路径
  3. 上传功能失效或报错

经过调试每一个环境发现问题处在通过路径访问图片的问题上,鸿蒙不能直接通过uri来读取相册里面的数据,接口返回的uri是一个虚拟的地址。官方文档也有说明。

日志错误信息

然后通过了解wechat_assets_picker的代码结构发现里面和平台相关的一个库flutter_photo_manager,把这库下载到本地,找到ohos平台对应的代码块

这里看到是直接把uri返回了,我们为了能让外界访问path,我们需要做个临时存储空间,为此,特意写了一个文件工具类-FileUtils.ets


import common from '@ohos.app.ability.common';
import fs from '@ohos.file.fs';
import util from '@ohos.util';
import Log from '@ohos/flutter_ohos/src/main/ets/util/Log';

const TAG = "FileUtils";

export default class FileUtils {
  static getPathFromUri(context: common.Context | null, uri: string, defExtension?: string) {
    Log.i(TAG, "getPathFromUri : " + uri);
    let inputFile: fs.File;
    try {
      inputFile = fs.openSync(uri);
    } catch (err) {
      Log.e(TAG, "open uri file failed err:" + err)
      return null;
    }
    if (inputFile == null) {
      return null;
    }
    const uuid = util.generateRandomUUID();
    if (!context) {
      return
    }
    {
      const targetDirectoryPath = context.cacheDir + "/" + uuid;
      try {
        fs.mkdirSync(targetDirectoryPath);
        let targetDir = fs.openSync(targetDirectoryPath);
        Log.i(TAG, "mkdirSync success targetDirectoryPath:" + targetDirectoryPath + " fd: " + targetDir.fd);
        fs.closeSync(targetDir);
      } catch (err) {
        Log.e(TAG, "mkdirSync failed err:" + err);
        return null;
      }

      const inputFilePath = uri.substring(uri.lastIndexOf("/") + 1);
      const inputFilePathSplits = inputFilePath.split(".");
      Log.i(TAG, "getPathFromUri inputFilePath: " + inputFilePath);
      const outputFileName = inputFilePathSplits[0];
      let extension: string;
      if (inputFilePathSplits.length == 2) {
        extension = "." + inputFilePathSplits[1];
      } else {
        if (defExtension) {
          extension = defExtension;
        } else {
          extension = ".jpg";
        }
      }
      const outputFilePath = targetDirectoryPath + "/" + outputFileName + extension;
      const outputFile = fs.openSync(outputFilePath, fs.OpenMode.CREATE);
      try {
        Log.i(TAG, "copyFileSync inputFile fd:" + inputFile.fd + " outputFile fd:" + outputFile.fd);
        fs.copyFileSync(inputFile.fd, outputFilePath);
      } catch (err) {
        Log.e(TAG, "copyFileSync failed err:" + err);
        return null;
      } finally {
        fs.closeSync(inputFile);
        fs.closeSync(outputFile);
      }
      return outputFilePath;
    }
  }
}

然后引入工具类,把uri转换成缓存路径,返回给dart层

if (photoAsset != null) {
  let realPath = FileUtils.getPathFromUri(this.uiContext, photoAsset.uri);
  result.success(realPath);
}

引入自己修改后的插件包

先flutter clean 在flutter pub get一下,然后重新运行项目

预览和上传都可以用了,修改后的代码已经开放,地址如下

https://gitcode.com/astevencui/flutter_photo_manager

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值