yymtfk
yymtfk

Reputation: 1

How to download files from blob URLs and handle storage permissions?

I'm developing a Flutter application using flutter_inappwebview to display web pages. I need to download files from links within these web pages, but some of these files are served as blob URLs, which seem to require special handling for downloading.

import 'dart:developer';
import 'package:dio/dio.dart';
import 'package:file_picker/file_picker.dart';
import 'package:flutter/material.dart';
import 'package:flutter_inappwebview/flutter_inappwebview.dart';
import 'package:permission_handler/permission_handler.dart';

class WebViewPage extends StatefulWidget {
  final String url;
  const WebViewPage({super.key, required this.url});

  @override
  State<WebViewPage> createState() => _WebViewPageState();
}

class _WebViewPageState extends State<WebViewPage> {
  Future<void> downloadFile({required String url}) async {
    Map<Permission, PermissionStatus> statuses = await [Permission.storage].request();
    if (statuses[Permission.storage]!.isGranted) {
      String? path = await FilePicker.platform.getDirectoryPath();
      if (path != null && path.isNotEmpty) {
        String filename = url.split('/').last;
        String savePath = '$path/$filename';
        log('Save path: $savePath');

        try {
          await Dio().download(
            url,
            savePath,
            onReceiveProgress: (received, total) {
              if (total != -1) {
                log('${(received / total * 100).toStringAsFixed(0)}%');
              }
            },
          );
          log('File is saved to $savePath');
        } on DioError catch (e) {
          log('Download failed: ${e.message}');
        }
      }
    } else {
      log('Storage permission denied');
    }
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(),
      body: InAppWebView(
        initialUrlRequest: URLRequest(url: WebUri(widget.url)),
        onWebViewCreated: (InAppWebViewController controller) {},
        onLoadStart: (InAppWebViewController controller, Uri? url) {},
        onLoadStop: (InAppWebViewController controller, Uri? url) async {},
        onProgressChanged: (InAppWebViewController controller, int progress) {},
        onDownloadStartRequest: (controller, url) async {
          print(url);
          log(url.toString());
          if (url != null) {
            await downloadFile(url: url.toString());
          }
        },
      ),
    );
  }
}

I expected the file to download successfully and be saved to the selected directory

Upvotes: 0

Views: 58

Answers (0)

Related Questions