HarmonyOS鸿蒙Next中Flutter应用如何实现文件选择器的双包适配方案?

HarmonyOS鸿蒙Next中Flutter应用如何实现文件选择器的双包适配方案? Flutter 生态中常用的file_picker插件暂无同名,只有file_picker_ohos,导入的时候怎么做区分,不能Dart 的条件导入(Conditional Imports)机制吗

3 回复

Dart 支持条件导入,但有局限性

提供了 if 条件导入语法,可以根据环境选择性导入:

//判断是否在 Web 环境
import 'package:xxx/mobile.dart'
  if (dart.library.html) 'package:xxx/web.dart';
//判断是否有 dart:io 库(原生平台)
import 'package:xxx/web.dart'
  if (dart.library.io) 'package:xxx/mobile.dart';
//判断是否有 dart:mirrors 库
import 'package:xxx/default.dart'
  if (dart.library.mirrors) 'package:xxx/reflection.dart';

但不能用于区分鸿蒙平台

没有 dart.library.ohos 这样的条件

// 这样写是无效的,Dart 不支持
import 'package:file_picker/file_picker.dart'
  if (dart.library.ohos) 'package:file_picker_ohos/file_picker_ohos.dart';

Dart 只提供了以下几个内置条件:

条件 说明
dart.library.io 是否支持 dart:io(原生平台)
dart.library.html 是否支持 dart:html(Web 平台)
dart.library.js 是否支持 dart:js(Web 平台)
dart.library.mirrors 是否支持 dart:mirrors
dart.library.isolate 是否支持 dart:isolate

关键是没有 dart.library.ohos 的判断,在我们处理的时候 让 ai 辅助开发很容易出错!

解决方案:双包导入 + 运行时判断

// 导入两个包
import 'package:file_picker/file_picker.dart' as standard_picker;
import 'package:file_picker_ohos/file_picker_ohos.dart' as ohos_picker;

// 运行时判断
if (Platform.operatingSystem == 'ohos') {
    result = await ohos_picker.FilePicker.platform.pickFiles();

} else {
    result = await standard_picker.FilePicker.platform.pickFiles();
}

在 pubspec.yaml 中,不用 dependency_overrides 重写依赖,直接在 dependencies 中声明两个包:

dependencies:
  flutter:
  sdk: flutter
  # 文件选择
  file_picker: ^6.1.1
  # 鸿蒙平台文件选择
  file_picker_ohos:
    git:
    url: https://gitcode.com/openharmony-sig/fluttertpc_file_picker.git
    path: ohos

更多关于HarmonyOS鸿蒙Next中Flutter应用如何实现文件选择器的双包适配方案?的实战系列教程也可以访问 https://www.itying.com/category-92-b0.html


鸿蒙Next中Flutter应用实现文件选择器双包适配,需通过条件编译或动态导入区分鸿蒙与Android/iOS平台。在鸿蒙侧,使用@ohos.file.picker模块的PhotoViewPickerDocumentViewPicker实现文件选择功能。在Flutter层封装统一接口,在鸿蒙平台调用ArkTS/JS的FFI桥接(如通过ffijs插件)来调用上述鸿蒙API,在其他平台则调用原有插件(如file_picker)。需注意鸿蒙Next的Stage模型与API 10+的权限声明与沙箱路径访问规则。

在HarmonyOS Next中,Flutter应用适配文件选择器时,由于平台生态差异,确实需要处理不同插件包的兼容问题。针对file_pickerfile_picker_ohos的区分导入,Dart的条件导入机制无法直接用于插件包选择,因为该机制主要用于同一项目内不同Dart文件的平台条件编译,而插件包依赖是在pubspec.yaml中声明的。

推荐的双包适配方案如下:

  1. 使用条件依赖声明pubspec.yaml中通过平台判断分别声明依赖:

    dependencies:
      file_picker:
        git:
          url: https://gitee.com/openharmony-sig/flutter_file_picker
          ref: master
        when:
          platform: ohos
      file_picker_ohos:
        git:
          url: https://gitee.com/openharmony-sig/file_picker_ohos
          ref: master
        when:
          platform: ohos
    
  2. 统一接口封装 创建自定义文件选择器封装类,通过Platform.isOHOSkIsWeb等条件判断调用对应插件:

    import 'package:flutter/foundation.dart';
    
    class FilePickerAdapter {
      static Future<FilePickerResult?> pickFiles({
        FileType type = FileType.any,
        List<String>? allowedExtensions,
      }) async {
        if (defaultTargetPlatform == TargetPlatform.ohos) {
          return await FilePickerOHOS.pickFiles(
            type: _convertType(type),
            allowedExtensions: allowedExtensions,
          );
        } else {
          return await FilePicker.platform.pickFiles(
            type: type,
            allowedExtensions: allowedExtensions,
          );
        }
      }
      
      static FileTypeOHOS _convertType(FileType type) {
        // 类型转换逻辑
      }
    }
    
  3. 平台接口抽象 定义平台无关的抽象接口,通过MethodChannelPluginRegistry动态注册不同实现:

    abstract class FilePickerBridge {
      Future<List<String>> pickFiles();
    }
    
    class OHOSFilePicker implements FilePickerBridge {
      // 调用file_picker_ohos原生能力
    }
    
    class DefaultFilePicker implements FilePickerBridge {
      // 调用原file_picker
    }
    
  4. 构建配置隔离 在HarmonyOS Next专属构建变体中配置依赖替换:

    // ohos/build.gradle
    configurations.all {
      resolutionStrategy {
        dependencySubstitution {
          substitute module('io.flutter.plugins:file_picker')
            .using module('io.flutter.plugins:file_picker_ohos')
        }
      }
    }
    

关键注意事项:

  • 需要确保file_picker_ohos插件已实现与原插件一致的API接口
  • 平台判断建议使用defaultTargetPlatform == TargetPlatform.ohos作为主条件
  • 若涉及原生代码交互,需分别实现Android/HarmonyOS双端的Channel通信

这种方案通过构建层依赖隔离和运行时平台检测,实现了同一套Dart代码对双插件包的透明适配,无需修改业务层调用逻辑。

回到顶部