How to cancel downloading file?

Viewed 31

I have the method which downloads my File to local storage on Android. I have to give the opportunity to cancel this loading process. How can I do it? I use bloc with events. Here is my function for event:

Future saveFile(Emitter<FileState> emit, FileModel fileToDownload) async {
emit(_loadingState());
final dir = await getApplicationDocumentsDirectory();
final file = File('${dir.path}/${fileToDownload.name}');
final ref = FirebaseStorage.instance.ref('uploads/${fileToDownload.name}');
final task = ref.writeToFile(file);
final exists = await file.exists();
emit(
  FileState(
    status: BlocStatus.loaded,
    exists: exists,
    task: task,
  ),
);

}

I know that there exists a method that can cancel this process - task.cancel();

But where do I have to write it? And how can I have to implement it? In the UI part I have button (GestureDetector - onTap - in CircularPercentIndicator), where should be Cancel functionality. Here is the code:

return BlocBuilder<FileBloc, FileState>(
  bloc: fileBloc,
  builder: (context, state) {
    return Container(
      padding: EdgeInsets.symmetric(horizontal: 16.w),
      alignment: Alignment.centerLeft,
      child: Container(
        padding: EdgeInsets.symmetric(
          horizontal: 12.w,
          vertical: 8.h,
        ),
        decoration: BoxDecoration(
          color: Palette.lightGray,
          borderRadius: BorderRadius.only(
            topLeft: Radius.circular(10.r),
            topRight: Radius.circular(10.r),
            bottomRight: Radius.circular(10.r),
          ),
        ),
        width: 263.w,
        height: 56.h,
        child: Row(
          children: [
            GestureDetector(
              onTap: () async {
                if (!state.exists) {
                  fileBloc.add(SaveFileEvent(widget.message.file!));
                }
              },
              child: SizedBox(
                height: 40.h,
                width: 32.w,
                child: state.status == BlocStatus.loading
                    ? CircularPercentIndicator(
                        radius: 16.r,
                        animation: true,
                        lineWidth: 2.w,
                        percent: 1,
                        circularStrokeCap: CircularStrokeCap.round,
                        progressColor: Palette.green,
                        center: GestureDetector(
                          onTap: () {
                            //here should be cancel functionality
                          },
                          child: SizedBox(
                            height: 10.5.h,
                            width: 10.5.w,
                            child: SvgPicture.asset(
                              'assets/icons/cancel.svg',
                              color: Palette.white,
                            ),
                          ),
                        ),
                      )
                    : state.exists
                        ? Image.asset('assets/images/saved-file.png')
                        : Image.asset('assets/images/non-saved-file.png'),
              ),
            ),
1 Answers

Yes, it works. I added a new field to bloc: late DownloadTask? task; Initialize it while loading was in process in the save method and then use it in the cancel method. Here is the methods:

 Future saveFile(FileModel fileToDownload) async {
emit(_loadingState());
final dir = await getApplicationDocumentsDirectory();
final file = File('${dir.path}/${fileToDownload.name}');
final ref = FirebaseStorage.instance.ref('uploads/${fileToDownload.name}');
task = ref.writeToFile(file);
emit(
  const FileState(
    status: BlocStatus.loaded,
  ),
);

}

 Future cancelSaving() async {
    if (task != null) {
      await task!.cancel();
    }
    emit(
      const FileState(
        status: BlocStatus.loaded,
      ),
    );
  }
Related