You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Flutter使用googleapis上传文件到Google Drive如何获取进度及取消上传

googleapis Drive 上传进度获取与取消方案

1. 上传进度百分比获取

你可以通过包装上传的字节流来统计已发送数据量,自行计算上传进度,无需依赖库的额外API:

  • 给上传方法增加进度回调参数
  • 对流做转换,每发送一段数据就累加已上传字节,除以总大小得到进度
    代码示例:
Future<File> uploadFile(
    GoogleAuthClient googleAuthClient,
    FileUpload fileUpload, {
    // 进度回调,返回0-1的小数,乘以100就是百分比
    Function(double progress)? onProgress,
  }) async {
    final DriveApi driveApi = driveDataProvider.getDriveApi(googleAuthClient);

    int uploadedBytes = 0;
    final originalStream = Future.value(fileUpload.data).asStream().asBroadcastStream();
    // 包装流用于统计进度
    final monitoredStream = originalStream.transform(
      StreamTransformer<List<int>, List<int>>.fromHandlers(
        handleData: (chunk, sink) {
          uploadedBytes += chunk.length;
          final progress = (uploadedBytes / fileUpload.size).clamp(0.0, 1.0);
          onProgress?.call(progress);
          sink.add(chunk);
        },
      )
    );

    Media media = Media(monitoredStream, fileUpload.size);

    File createdFile = await driveApi.files.create(fileUpload.file,
        uploadMedia: media, uploadOptions: const ResumableUploadOptions());

    return createdFile;
  }

使用的时候直接传入回调就能拿到进度:

uploadFile(authClient, fileUpload, onProgress: (progress) {
  print('当前上传进度:${(progress * 100).toStringAsFixed(1)}%');
});

2. 取消正在进行的上传

你可以通过终止上传流的方式实现取消操作,实现逻辑如下:

  • 给上传方法增加取消标记的监听,或者返回可取消的异步操作
  • 触发取消时,关闭上传流并抛出取消异常,终止上传流程

简单实现方案:

Future<File> uploadFile(
    GoogleAuthClient googleAuthClient,
    FileUpload fileUpload, {
    Function(double progress)? onProgress,
    // 取消监听回调,返回true表示需要取消上传
    bool Function()? shouldCancel,
  }) async {
    final DriveApi driveApi = driveDataProvider.getDriveApi(googleAuthClient);

    int uploadedBytes = 0;
    final originalStream = Future.value(fileUpload.data).asStream().asBroadcastStream();
    final monitoredStream = originalStream.transform(
      StreamTransformer<List<int>, List<int>>.fromHandlers(
        handleData: (chunk, sink) {
          // 每次发送前判断是否需要取消
          if (shouldCancel?.call() ?? false) {
            sink.addError(Exception('upload_canceled'));
            sink.close();
            return;
          }
          uploadedBytes += chunk.length;
          final progress = (uploadedBytes / fileUpload.size).clamp(0.0, 1.0);
          onProgress?.call(progress);
          sink.add(chunk);
        },
      )
    );

    Media media = Media(monitoredStream, fileUpload.size);
    try {
      File createdFile = await driveApi.files.create(fileUpload.file,
          uploadMedia: media, uploadOptions: const ResumableUploadOptions());
      return createdFile;
    } catch (e) {
      if (e.toString().contains('upload_canceled')) {
        // 处理取消逻辑
        rethrow;
      }
      rethrow;
    }
  }

使用的时候定义取消标记,需要取消时修改标记值即可:

bool isCancel = false;
// 发起上传
uploadFile(authClient, fileUpload,
  onProgress: (progress) => print('进度:${progress*100}%'),
  shouldCancel: () => isCancel,
).catchError((e) {
  if(e.toString().contains('upload_canceled')) {
    print('上传已取消');
  }
});

// 触发取消
// isCancel = true;

注意事项

  • 要保证传入的fileUpload.size值准确,否则进度计算会出现偏差
  • 取消上传后建议捕获对应的异常,避免未处理错误导致应用崩溃
  • 必须使用断点续传模式(ResumableUploadOptions),才能保证取消逻辑的可靠性,大文件场景下还支持后续续传

内容的提问来源于stack exchange,提问作者hayashi

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.04 01:06:03