Flutter文件上传管理插件upload_flow_manager的使用

Flutter文件上传管理插件upload_flow_manager的使用

Upload Flow Manager

该软件包旨在通过提供一个顶级小部件简化从本地设备向服务器上传文件的过程。

特性

一个顶级小部件处理完整的上传流程,包括以下步骤:

  • 使用您选择的任何拾取器选择一个或多个文件。 (picker)
  • 查看所选文件,并通过预览来选择或取消选择项目(避免意外上传)。 (preview generator)
  • 使用默认的基于HTTP的上传器或使用您喜欢的上传器实现上传器接口。(upload handler)
  • 监控并获取每个上传的状态。

可以通过自定义配置上述任一步骤。

该软件包使用Riverpod管理状态,并使用sqlite3进行持久化状态以在会话之间甚至应用程序重启后保留待处理的下载。

开始使用

  1. 将软件包添加到您的 pubspec.yaml 文件中:
flutter pub add upload_flow_manager
  1. 添加riverpod
flutter pub add flutter_riverpod
  1. 将整个应用程序包装在一个 “ProviderScope” 小部件中。
void main() {
  runApp(
    ProviderScope(
      child: MyApp(),
    ),
  );
}
  1. 导入软件包
import 'package:upload_flow_manager/upload_flow_manager.dart';
  1. 使用小部件
// 替换为您的上传URL
Uploader(url: "<Your Upload URL>");

对于简单的用例,以上操作必须在没有任何自定义/修改的情况下工作。调整小部件的大小(宽度、高度)以便清楚地查看上传器。

URL 必须接受 HTTP POST 方法,并接受以 FileField 或默认为 ‘file’ 的文件形式的多部分上传。

使用

Uploader 小部件提供了用于自定义的参数。

  • 若要替换 gpicker,请使用 pickItems
  • 若要替换预览生成器,请使用 previewGenerator
  • 若要替换使用 http 实现的上传器(如果您希望扩展 UploadHandler 类并实现不同的上传功能,请传递一个 UploadHandler 实例 uploadHandler。在这种情况下,您不需要传递 URL。
    • 如果仅需要更改文件字段名称,则可以使用 fileField 进行传递。
  • 若要更改界面中使用的语言/文本,请通过 uiLabels 参数覆盖必要的 LabeledIcons
Uploader({
    url: /*<url, required if uploadHandler is null>*/,
    fileField /* default to 'file' */,
    this.uploadHandler /* Extending UploadHandler class with differnt upload functionality */,
    this.pickItems /* Default to image picker */,
    this.previewGenerator /* Default to image preview */,
    this.uiLabels /*Default text internally generated*/,
  })

待办事项

  • sqlite3 open.overrideFor 应在回调中完成。

HTTP 上传器

  • ✅ 将 HTTP 实现作为内部默认上传处理器
    • ❌ 重试失败的情况
    • ❌ 重新启动时重试所有待处理的请求
    • ❌ 实现即使在应用程序关闭后也能运行的后台任务

界面

  • ❌ 提供替代的基于列表的界面以及当前基于网格的界面
  • ❌ 允许应用程序添加辅助信息以供上传
  • ❌ 在每次上传完成后提供回调以更新应用程序其他部分的状态
  • ❌ 实现通过意图共享文件的上传(在移动设备上)
  • ❌ 允许拖放文件以进行上传
  • ❌ 部分文本和标签尚未可配置

示例

手动提供 sqlite3 库

在某些设备上,sqlite3 可能不在默认位置,或者您可能需要将 sqlite3 库与应用程序一起分发。在这种情况下,sqlite3 提供了一个选项来自定义库查找方式。

在此情况下,此软件包提供了一个 sqlite3 库的传递方法。

这是一个针对 Linux 的示例。

安装 pathsqlite3 包。

实现覆盖并将它传递给 Uploader。

import 'package:path/path.dart';
import 'package:sqlite3/open.dart';

sqlite3LibOverrider() {
  final libraryNextToScript =
      File(join('/lib/x86_64-linux-gnu/', 'libsqlite3.so.0'));

  open.overrideFor(OperatingSystem.linux,
      () => DynamicLibrary.open(libraryNextToScript.path));
}
Uploader(
  ...
  sqlite3LibOverrider: sqlite3LibOverrider,
)

测试服务器

如果您的服务器在实现应用程序时还未准备好,或者不能用于测试,您可以使用此软件包中提供的基于Python Flask的示例服务器。 请参阅 example/server/README.md 以启动它。 上传文件到此服务器的API是 http://127.0.0.1:5000/upload

完整示例代码

import 'package:flutter/material.dart';

import 'package:flutter_riverpod/flutter_riverpod.dart';
import 'package:upload_flow_manager/upload_flow_manager.dart';
import 'dart:ffi';
import 'dart:io';

import 'package:path/path.dart';
import 'package:sqlite3/open.dart';

void main() {
  runApp(const ProviderScope(child: MyApp()));
}

class MyApp extends StatelessWidget {
  const MyApp({super.key});

  // This widget is the root of your application.
  [@override](/user/override)
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'Files Uploader Demo',
      theme: ThemeData(
        colorScheme: ColorScheme.fromSeed(seedColor: Colors.deepPurple),
        useMaterial3: true,
      ),
      home: Scaffold(
          appBar: AppBar(title: const Text("Files Uploader Demo")),
          body: Column(
            children: [
              const Expanded(
                child: Center(
                  child: Text("Your Other widget"),
                ),
              ),
              Expanded(
                child: Row(
                  children: [
                    const Expanded(
                      child: Center(
                        child: Text("Your Other widget"),
                      ),
                    ),
                    Expanded(
                      child: Container(
                        margin: const EdgeInsets.all(8),
                        padding: const EdgeInsets.all(8),
                        decoration: BoxDecoration(border: Border.all()),
                        child: Uploader(
                          url: "http://127.0.0.1:5000/upload",
                          sqlite3LibOverrider: sqlite3LibOverrider,
                        ),
                      ),
                    ),
                  ],
                ),
              ),
              const Expanded(
                child: Center(
                  child: Text("Your Other widget"),
                ),
              ),
            ],
          )),
    );
  }
}

sqlite3LibOverrider() {
  final libraryNextToScript =
      File(join('/lib/x86_64-linux-gnu/', 'libsqlite3.so.0'));

  open.overrideFor(OperatingSystem.linux,
      () => DynamicLibrary.open(libraryNextToScript.path));
}

更多关于Flutter文件上传管理插件upload_flow_manager的使用的实战教程也可以访问 https://www.itying.com/category-92-b0.html

1 回复

更多关于Flutter文件上传管理插件upload_flow_manager的使用的实战系列教程也可以访问 https://www.itying.com/category-92-b0.html


upload_flow_manager 是一个用于管理文件上传流程的 Flutter 插件。它提供了文件上传的管理和控制功能,包括文件选择、上传进度监控、失败重试等。以下是如何使用 upload_flow_manager 插件的基本步骤:

1. 添加依赖

首先,在 pubspec.yaml 文件中添加 upload_flow_manager 插件的依赖:

dependencies:
  flutter:
    sdk: flutter
  upload_flow_manager: ^0.1.0  # 请使用最新版本

然后运行 flutter pub get 来安装依赖。

2. 导入插件

在需要使用 upload_flow_manager 的 Dart 文件中导入插件:

import 'package:upload_flow_manager/upload_flow_manager.dart';

3. 初始化上传管理器

创建一个 UploadFlowManager 实例来管理文件上传流程。

final uploadManager = UploadFlowManager();

4. 选择文件

使用 uploadManager.pickFiles() 方法来选择文件。该方法返回一个 List<UploadFile>,其中包含选择的文件信息。

Future<void> pickFiles() async {
  List<UploadFile> files = await uploadManager.pickFiles();
  if (files.isNotEmpty) {
    // 处理选择的文件
    for (var file in files) {
      print('Selected file: ${file.name}');
    }
  }
}

5. 上传文件

使用 uploadManager.uploadFiles() 方法来上传文件。你可以指定上传的 URL 和其他配置。

Future<void> uploadFiles(List<UploadFile> files) async {
  final uploadUrl = 'https://your-upload-endpoint.com/upload';
  
  try {
    await uploadManager.uploadFiles(
      files: files,
      url: uploadUrl,
      onProgress: (int progress) {
        print('Upload progress: $progress%');
      },
      onComplete: () {
        print('Upload complete');
      },
      onError: (String error) {
        print('Upload error: $error');
      },
    );
  } catch (e) {
    print('Error uploading files: $e');
  }
}

6. 处理上传进度和结果

在上传过程中,你可以通过 onProgress 回调来监控上传进度。上传完成后,onComplete 回调会被调用。如果上传过程中发生错误,onError 回调会被触发。

7. 其他功能

upload_flow_manager 还提供了其他功能,如取消上传、重试失败的上传等。你可以根据需要使用这些功能。

// 取消上传
uploadManager.cancelUpload();

// 重试失败的上传
uploadManager.retryFailedUploads();

8. 示例代码

以下是一个完整的示例代码,展示了如何使用 upload_flow_manager 插件来选择文件并上传:

import 'package:flutter/material.dart';
import 'package:upload_flow_manager/upload_flow_manager.dart';

void main() {
  runApp(MyApp());
}

class MyApp extends StatelessWidget {
  [@override](/user/override)
  Widget build(BuildContext context) {
    return MaterialApp(
      home: UploadPage(),
    );
  }
}

class UploadPage extends StatefulWidget {
  [@override](/user/override)
  _UploadPageState createState() => _UploadPageState();
}

class _UploadPageState extends State<UploadPage> {
  final uploadManager = UploadFlowManager();
  List<UploadFile> selectedFiles = [];

  Future<void> pickFiles() async {
    List<UploadFile> files = await uploadManager.pickFiles();
    setState(() {
      selectedFiles = files;
    });
  }

  Future<void> uploadFiles() async {
    final uploadUrl = 'https://your-upload-endpoint.com/upload';
    
    try {
      await uploadManager.uploadFiles(
        files: selectedFiles,
        url: uploadUrl,
        onProgress: (int progress) {
          print('Upload progress: $progress%');
        },
        onComplete: () {
          print('Upload complete');
        },
        onError: (String error) {
          print('Upload error: $error');
        },
      );
    } catch (e) {
      print('Error uploading files: $e');
    }
  }

  [@override](/user/override)
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text('File Upload Example'),
      ),
      body: Center(
        child: Column(
          mainAxisAlignment: MainAxisAlignment.center,
          children: <Widget>[
            ElevatedButton(
              onPressed: pickFiles,
              child: Text('Pick Files'),
            ),
            SizedBox(height: 20),
            ElevatedButton(
              onPressed: uploadFiles,
              child: Text('Upload Files'),
            ),
          ],
        ),
      ),
    );
  }
}
回到顶部