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
相关产品推荐
相关产品推荐

