2020-09-07 19:06:18 +00:00
import ' dart:async ' ;
2020-11-12 17:28:57 +00:00
import ' dart:io ' ;
2020-09-07 19:06:18 +00:00
import ' package:file_picker/file_picker.dart ' ;
import ' package:file_picker/src/platform_file.dart ' ;
import ' package:flutter/foundation.dart ' ;
import ' package:flutter/services.dart ' ;
2020-12-10 19:09:13 +00:00
final MethodChannel _channel = MethodChannel (
' miguelruivo.flutter.plugins.filepicker ' ,
Platform . isLinux | | Platform . isWindows | | Platform . isMacOS
? const JSONMethodCodec ( )
: const StandardMethodCodec ( ) ,
) ;
2020-09-11 17:37:45 +00:00
const EventChannel _eventChannel =
EventChannel ( ' miguelruivo.flutter.plugins.filepickerevent ' ) ;
2020-09-07 19:06:18 +00:00
/// An implementation of [FilePicker] that uses method channels.
class FilePickerIO extends FilePicker {
static const String _tag = ' MethodChannelFilePicker ' ;
2020-11-21 21:26:32 +00:00
static StreamSubscription ? _eventSubscription ;
2020-09-07 19:06:18 +00:00
@ override
2020-11-21 21:26:32 +00:00
Future < FilePickerResult ? > pickFiles ( {
2020-09-07 19:06:18 +00:00
FileType type = FileType . any ,
2020-11-21 21:26:32 +00:00
List < String > ? allowedExtensions ,
2021-08-10 16:54:23 +00:00
String ? dialogTitle ,
2020-11-21 21:26:32 +00:00
Function ( FilePickerStatus ) ? onFileLoading ,
bool ? allowCompression = true ,
2020-09-07 19:06:18 +00:00
bool allowMultiple = false ,
2020-11-21 21:26:32 +00:00
bool ? withData = false ,
bool ? withReadStream = false ,
2020-09-07 19:06:18 +00:00
} ) = >
2020-09-11 17:01:34 +00:00
_getPath (
type ,
allowMultiple ,
allowCompression ,
allowedExtensions ,
onFileLoading ,
withData ,
2020-11-12 17:28:57 +00:00
withReadStream ,
2020-09-11 17:01:34 +00:00
) ;
2020-09-07 19:06:18 +00:00
@ override
2020-11-21 21:26:32 +00:00
Future < bool ? > clearTemporaryFiles ( ) async = >
2020-09-11 17:37:45 +00:00
_channel . invokeMethod < bool > ( ' clear ' ) ;
2020-09-07 19:06:18 +00:00
@ override
2021-08-10 16:54:23 +00:00
Future < String ? > getDirectoryPath ( { String ? dialogTitle } ) async {
2020-09-07 19:06:18 +00:00
try {
2020-09-11 13:53:18 +00:00
return await _channel . invokeMethod ( ' dir ' , { } ) ;
2020-09-07 19:06:18 +00:00
} on PlatformException catch ( ex ) {
if ( ex . code = = " unknown_path " ) {
print (
' [ $ _tag ] Could not resolve directory path. Maybe it \' s a protected one or unsupported (such as Downloads folder). If you are on Android, make sure that you are on SDK 21 or above. ' ) ;
}
}
return null ;
}
2020-11-21 21:26:32 +00:00
Future < FilePickerResult ? > _getPath (
2020-09-07 19:06:18 +00:00
FileType fileType ,
bool allowMultipleSelection ,
2020-11-21 21:26:32 +00:00
bool ? allowCompression ,
List < String > ? allowedExtensions ,
Function ( FilePickerStatus ) ? onFileLoading ,
bool ? withData ,
bool ? withReadStream ,
2020-09-07 19:06:18 +00:00
) async {
final String type = describeEnum ( fileType ) ;
2021-05-26 10:51:41 +00:00
if ( type ! = ' custom ' & & ( allowedExtensions ? . isNotEmpty ? ? false ) ) {
2020-09-11 17:37:45 +00:00
throw Exception (
2021-05-26 00:00:48 +00:00
' You are setting a type [ $ fileType ]. Custom extension filters are only allowed with FileType.custom, please change it or remove filters. ' ) ;
2020-09-07 19:06:18 +00:00
}
try {
_eventSubscription ? . cancel ( ) ;
if ( onFileLoading ! = null ) {
_eventSubscription = _eventChannel . receiveBroadcastStream ( ) . listen (
2020-09-11 17:37:45 +00:00
( data ) = > onFileLoading ( ( data as bool )
? FilePickerStatus . picking
: FilePickerStatus . done ) ,
2020-09-07 19:06:18 +00:00
onError: ( error ) = > throw Exception ( error ) ,
) ;
}
2020-11-21 21:26:32 +00:00
final List < Map > ? result = await _channel . invokeListMethod ( type , {
2020-09-07 19:06:18 +00:00
' allowMultipleSelection ' : allowMultipleSelection ,
' allowedExtensions ' : allowedExtensions ,
' allowCompression ' : allowCompression ,
2020-09-11 17:01:34 +00:00
' withData ' : withData ,
2020-09-07 19:06:18 +00:00
} ) ;
if ( result = = null ) {
return null ;
}
2020-11-12 17:28:57 +00:00
final List < PlatformFile > platformFiles = < PlatformFile > [ ] ;
2021-05-26 00:00:48 +00:00
for ( final Map platformFileMap in result ) {
2020-11-12 17:28:57 +00:00
platformFiles . add (
PlatformFile . fromMap (
platformFileMap ,
2020-11-21 21:26:32 +00:00
readStream: withReadStream !
2020-11-12 17:28:57 +00:00
? File ( platformFileMap [ ' path ' ] ) . openRead ( )
: null ,
) ,
) ;
}
return FilePickerResult ( platformFiles ) ;
2020-09-07 19:06:18 +00:00
} on PlatformException catch ( e ) {
print ( ' [ $ _tag ] Platform exception: $ e ' ) ;
rethrow ;
} catch ( e ) {
2020-09-11 17:37:45 +00:00
print (
' [ $ _tag ] Unsupported operation. Method not found. The exception thrown was: $ e ' ) ;
2020-09-07 19:06:18 +00:00
rethrow ;
}
}
}