插件介绍

fluttertpc_flutter_downloader 是一个为鸿蒙平台适配的 Flutter 下载管理插件,基于开源的 flutter_downloader 项目进行自定义修改。该插件允许开发者在鸿蒙应用中轻松实现后台下载任务的创建和管理功能,支持多任务下载、任务状态跟踪、断点续传等高级特性。

主要功能特点:

  • 支持创建和管理后台下载任务
  • 提供丰富的任务管理 API(取消、暂停、恢复、重试等)
  • 支持下载进度和状态的实时回调
  • 所有任务信息保存在 SQLite 数据库中,便于查询和管理
  • 支持文件下载完成后的自动打开
  • 支持配置是否允许使用蜂窝网络下载
  • 完全适配鸿蒙平台

如何在鸿蒙应用中使用该插件

1. 包的引入

由于这是一个自定义修改版本的三方库,需要以 git 形式引入。在项目的 pubspec.yaml 文件中,添加以下依赖配置:

dependencies:
  fluttertpc_flutter_downloader:
    git:
      url: "https://atomgit.com/openharmony-sig/fluttertpc_flutter_downloader.git"

然后执行以下命令获取依赖:

flutter pub get

2. API 的调用

初始化插件

在使用任何下载功能之前,必须先初始化插件。建议在应用启动时进行初始化:

import 'package:flutter_downloader/flutter_downloader.dart';

void main() async {
  WidgetsFlutterBinding.ensureInitialized();

  // 初始化下载插件
  await FlutterDownloader.initialize(
    debug: true, // 调试模式,发布时建议关闭
    ignoreSsl: false, // 是否忽略 SSL 错误,建议生产环境关闭
  );

  runApp(MyApp());
}
创建下载任务

使用 enqueue 方法创建新的下载任务:

Future<String?> createDownloadTask() async {
  String url = 'https://example.com/file.pdf';
  String savedDir = '/storage/emulated/0/Download';

  try {
    String? taskId = await FlutterDownloader.enqueue(
      url: url,
      savedDir: savedDir,
      fileName: 'example.pdf', // 可选,指定文件名
      headers: {}, // 可选,HTTP 请求头
      showNotification: true, // 是否显示通知
      openFileFromNotification: true, // 是否允许从通知打开文件
      requiresStorageNotLow: true, // 是否需要存储空间充足
      saveInPublicStorage: false, // 是否保存到公共存储
      allowCellular: true, // 是否允许使用蜂窝网络
      timeout: 15000, // 超时时间
    );

    return taskId;
  } catch (e) {
    print('创建下载任务失败: $e');
    return null;
  }
}
监听下载状态

通过注册回调函数来监听下载进度和状态变化:

import 'dart:isolate';
import 'dart:ui';

class MyDownloadPage extends StatefulWidget {
  
  _MyDownloadPageState createState() => _MyDownloadPageState();
}

class _MyDownloadPageState extends State<MyDownloadPage> {
  ReceivePort _port = ReceivePort();
  Map<String, DownloadTask> _tasks = {};

  
  void initState() {
    super.initState();

    // 注册端口用于接收下载回调
    IsolateNameServer.registerPortWithName(
        _port.sendPort, 'downloader_send_port');

    // 监听下载状态变化
    _port.listen((dynamic data) {
      String taskId = data[0];
      DownloadTaskStatus status = DownloadTaskStatus(data[1]);
      int progress = data[2];

      setState(() {
        if (_tasks.containsKey(taskId)) {
          _tasks[taskId]!.status = status;
          _tasks[taskId]!.progress = progress;
        }
      });
    });

    // 注册下载回调
    FlutterDownloader.registerCallback(downloadCallback);

    // 加载已有的下载任务
    _loadTasks();
  }

  static void downloadCallback(
      String id,
      int status,
      int progress,
      ) {
    // 从后台 isolate 发送消息到主 isolate
    final SendPort send = IsolateNameServer.lookupPortByName(
      'downloader_send_port',
    )!;
    send.send([id, status, progress]);
  }

  Future<void> _loadTasks() async {
    List<DownloadTask>? tasks = await FlutterDownloader.loadTasks();
    if (tasks != null) {
      setState(() {
        _tasks = {for (var task in tasks) task.taskId: task};
      });
    }
  }

  
  Widget build(BuildContext context) {
    // 构建 UI 部分
    return Scaffold(
      appBar: AppBar(title: Text('下载管理')),
      body: ListView.builder(
        itemCount: _tasks.length,
        itemBuilder: (context, index) {
          DownloadTask task = _tasks.values.elementAt(index);
          return ListTile(
            title: Text(task.filename ?? '未知文件'),
            subtitle: Text('进度: ${task.progress}%'),
            trailing: _buildTaskActions(task),
          );
        },
      ),
      floatingActionButton: FloatingActionButton(
        onPressed: () {
          // 创建新下载任务
          createDownloadTask().then((taskId) {
            if (taskId != null) {
              print('创建下载任务成功,ID: $taskId');
            }
          });
        },
        child: Icon(Icons.download),
      ),
    );
  }

  Widget _buildTaskActions(DownloadTask task) {
    switch (task.status) {
      case DownloadTaskStatus.running:
        return Row(
          mainAxisSize: MainAxisSize.min,
          children: [
            IconButton(
              icon: Icon(Icons.pause),
              onPressed: () {
                FlutterDownloader.pause(taskId: task.taskId);
              },
            ),
            IconButton(
              icon: Icon(Icons.cancel),
              onPressed: () {
                FlutterDownloader.cancel(taskId: task.taskId);
              },
            ),
          ],
        );
      case DownloadTaskStatus.paused:
        return Row(
          mainAxisSize: MainAxisSize.min,
          children: [
            IconButton(
              icon: Icon(Icons.play_arrow),
              onPressed: () {
                FlutterDownloader.resume(taskId: task.taskId);
              },
            ),
            IconButton(
              icon: Icon(Icons.cancel),
              onPressed: () {
                FlutterDownloader.cancel(taskId: task.taskId);
              },
            ),
          ],
        );
      case DownloadTaskStatus.complete:
        return IconButton(
          icon: Icon(Icons.open_in_new),
          onPressed: () {
            FlutterDownloader.open(taskId: task.taskId);
          },
        );
      case DownloadTaskStatus.failed:
        return IconButton(
          icon: Icon(Icons.refresh),
          onPressed: () {
            FlutterDownloader.retry(taskId: task.taskId);
          },
        );
      default:
        return IconButton(
          icon: Icon(Icons.delete),
          onPressed: () {
            FlutterDownloader.remove(
              taskId: task.taskId,
              shouldDeleteContent: true,
            ).then((_) {
              setState(() {
                _tasks.remove(task.taskId);
              });
            });
          },
        );
    }
  }

  
  void dispose() {
    IsolateNameServer.removePortNameMapping('downloader_send_port');
    super.dispose();
  }
}
其他常用 API
加载任务
// 加载所有任务
List<DownloadTask>? allTasks = await FlutterDownloader.loadTasks();

// 使用 SQL 查询加载特定任务
List<DownloadTask>? completedTasks = await FlutterDownloader.loadTasksWithRawQuery(
  query: 'SELECT * FROM task WHERE status=3',
);
任务管理
// 取消指定任务
await FlutterDownloader.cancel(taskId: taskId);

// 取消所有任务
await FlutterDownloader.cancelAll();

// 暂停任务
await FlutterDownloader.pause(taskId: taskId);

// 恢复任务
String? newTaskId = await FlutterDownloader.resume(taskId: taskId);

// 重试失败的任务
String? newTaskId = await FlutterDownloader.retry(taskId: taskId);

// 移除任务
await FlutterDownloader.remove(
  taskId: taskId,
  shouldDeleteContent: true, // 是否删除下载的文件
);

// 打开下载的文件
bool success = await FlutterDownloader.open(taskId: taskId);

任务状态说明

下载任务有以下几种状态:

状态 说明
undefined 任务状态未知或已损坏
enqueued 任务已排队但尚未运行
running 任务正在执行中
complete 任务已成功完成
failed 任务执行失败
canceled 任务已取消且无法恢复
paused 任务已暂停且可恢复

约束与限制

兼容性

该插件已在以下环境中测试通过:

  1. Flutter: 3.7.12-ohos-1.1.3; SDK: 5.0.0(12); IDE: DevEco Studio: 5.1.0.828; ROM: 5.1.0.130 SP8;
  2. Flutter: 3.22.1-ohos-1.0.3; SDK: 5.0.0(12); IDE: DevEco Studio: 5.1.0.828; ROM: 5.1.0.130 SP8;

注意事项

  • enqueue 方法在鸿蒙平台上部分支持
  • 使用前必须先初始化插件
  • 下载回调函数必须是顶层函数或静态方法
  • 需要适当的存储权限才能保存和访问下载的文件

总结

fluttertpc_flutter_downloader 是一个功能强大且易于使用的下载管理插件,专为鸿蒙平台进行了适配。它提供了完整的下载任务管理功能,支持多任务下载、进度跟踪、断点续传等高级特性,能够满足大多数应用的下载需求。

该插件的主要优势在于:

  • 完全适配鸿蒙平台
  • 提供了丰富的任务管理 API
  • 支持后台下载和状态回调
  • 任务信息持久化存储在 SQLite 数据库中
  • 支持文件下载完成后的自动打开

通过本指南,开发者可以快速了解并集成 fluttertpc_flutter_downloader 插件,为鸿蒙应用添加强大的下载功能。

欢迎加入开源鸿蒙跨平台社区:https://openharmonycrossplatform.csdn.net

Logo

开源鸿蒙跨平台开发社区汇聚开发者与厂商,共建“一次开发,多端部署”的开源生态,致力于降低跨端开发门槛,推动万物智联创新。

更多推荐