import 'package:file_picker/file_picker.dart'; import 'package:flutter/services.dart'; import '../utils/app_logger.dart'; /// Serializes file_picker invocations to avoid /// `PlatformException(already_active, File picker is already active)`. class FilePickerService { static final FilePickerService _instance = FilePickerService._(); static FilePickerService get instance => _instance; FilePickerService._(); bool _active = false; Future _guard(String opName, Future Function() body) async { if (_active) return null; _active = true; try { return await body(); } on PlatformException catch (e, st) { if (e.code == 'already_active') return null; appLogger.e('FilePicker.$opName failed', error: e, stackTrace: st); rethrow; } finally { _active = false; } } Future pickFiles({ FileType type = FileType.any, List? allowedExtensions, bool withData = false, }) { return _guard( 'pickFiles', () => FilePicker.platform.pickFiles(type: type, allowedExtensions: allowedExtensions, withData: withData), ); } Future getDirectoryPath({String? dialogTitle}) { return _guard('getDirectoryPath', () => FilePicker.platform.getDirectoryPath(dialogTitle: dialogTitle)); } Future saveFile({ String? dialogTitle, String? fileName, Uint8List? bytes, FileType type = FileType.any, List? allowedExtensions, }) { return _guard( 'saveFile', () => FilePicker.platform.saveFile( dialogTitle: dialogTitle, fileName: fileName, bytes: bytes, type: type, allowedExtensions: allowedExtensions, ), ); } }