🗄️Salvar arquivos da internet localmente

Save file helper

Esse arquivo contém uma função que faz o salvamento local de arquivos baixados no dispositivo.

É importante notar que é feito uso dos packages:

  • Media Store

  • Flutter File Dialog

  • Path Provider

Caso a plataforma seja android e a versão do android seja 29 para cima, não é preciso lidar com as permissões diretamente então o package já faz o salvamento no diretório de downloads, caso seja menor é preciso lidar com a permissão storage. Caso seja iOS ele usa do Flutter file dialog pra fazer o salvamento onde o usuário preferir

Future<void> saveFile({
  required File file,
  required String fileName,
  String fileExtension = 'pdf',
  String? customDirectory,
  Function(String)? onSuccess,
  Function(String)? onError,
}) async {
  late final MediaStore mediaStorePlugin;

  try {
    // Ensure file has proper extension
    String finalFileName = fileName;
    if (!finalFileName.toLowerCase().endsWith('.$fileExtension')) {
      finalFileName = '$finalFileName.$fileExtension';
    }

    if (Platform.isAndroid) {
      mediaStorePlugin = MediaStore();
      await MediaStore.ensureInitialized();
      MediaStore.appFolder = customDirectory ?? 'Download';
      final androidVersion = await mediaStorePlugin.getPlatformSDKInt();

      if (androidVersion >= 29) {
        final fileUri = await mediaStorePlugin.saveFile(
          tempFilePath: file.path,
          dirType: DirType.download,
          dirName: DirName.download,
        );
        debugPrint("File saved successfully: $fileUri");
        onSuccess?.call(fileUri);
      } else {
        if (!await _requestStoragePermission()) {
          debugPrint("Storage permission denied");
          onError?.call("Storage permission denied");
          return;
        }

        final dir = Directory('/storage/emulated/0/${customDirectory ?? "Download"}');
        if (!await dir.exists()) await dir.create(recursive: true);
        final saveFile = File('${dir.path}/$finalFileName');
        await saveFile.writeAsBytes(file.readAsBytesSync());
        debugPrint("File saved successfully: ${saveFile.path}");
        onSuccess?.call(saveFile.path);
      }
    } else if (Platform.isIOS) {
      var params = SaveFileDialogParams(sourceFilePath: file.path);
      String? path = await FlutterFileDialog.saveFile(params: params);
      if (path != null) {
        debugPrint("File saved successfully: $path");
        onSuccess?.call(path);
      } else {
        debugPrint("Failed to save file");
        onError?.call("Failed to save file");
        throw Exception("Failed to save file");
      }
    }
  } catch (e) {
    onError?.call(e.toString());
    throw Exception(e);
  }
}

Future<bool> _requestStoragePermission() async {
  final status = await Permission.storage.status;
  if (status.isGranted) return true;
  final result = await Permission.storage.request();
  return result.isGranted;
}

Last updated