Adds iOS implementation, removes URI and isDirectory and adds withData optional property
This commit is contained in:
parent
ea601246fd
commit
1c0e471458
|
@ -6,38 +6,24 @@ import java.util.HashMap;
|
|||
|
||||
public class FileInfo {
|
||||
|
||||
final Uri uri;
|
||||
final String path;
|
||||
final String name;
|
||||
final int size;
|
||||
final byte[] bytes;
|
||||
final long lastModified;
|
||||
final boolean isDirectory;
|
||||
|
||||
public FileInfo(Uri uri, String path, String name, int size, byte[] bytes, boolean isDirectory, long lastModified) {
|
||||
this.uri = uri;
|
||||
public FileInfo(String path, String name, int size, byte[] bytes) {
|
||||
this.path = path;
|
||||
this.name = name;
|
||||
this.size = size;
|
||||
this.bytes = bytes;
|
||||
this.lastModified = lastModified;
|
||||
this.isDirectory = isDirectory;
|
||||
}
|
||||
|
||||
public static class Builder {
|
||||
|
||||
private Uri uri;
|
||||
private String path;
|
||||
private String name;
|
||||
private int size;
|
||||
private long lastModified;
|
||||
private byte[] bytes;
|
||||
private boolean isDirectory;
|
||||
|
||||
public Builder withUri(Uri uri){
|
||||
this.uri = uri;
|
||||
return this;
|
||||
}
|
||||
|
||||
public Builder withPath(String path){
|
||||
this.path = path;
|
||||
|
@ -59,32 +45,18 @@ public class FileInfo {
|
|||
return this;
|
||||
}
|
||||
|
||||
public Builder withDirectory(String path){
|
||||
this.path = path;
|
||||
this.isDirectory = path != null;
|
||||
return this;
|
||||
}
|
||||
|
||||
public Builder lastModifiedAt(long timeStamp){
|
||||
this.lastModified = timeStamp;
|
||||
return this;
|
||||
}
|
||||
|
||||
public FileInfo build() {
|
||||
return new FileInfo(this.uri, this.path, this.name, this.size, this.bytes, this.isDirectory, this.lastModified);
|
||||
return new FileInfo(this.path, this.name, this.size, this.bytes);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public HashMap<String, Object> toMap() {
|
||||
final HashMap<String, Object> data = new HashMap<>();
|
||||
data.put("uri", uri.toString());
|
||||
data.put("path", path);
|
||||
data.put("name", name);
|
||||
data.put("size", size);
|
||||
data.put("bytes", bytes);
|
||||
data.put("isDirectory", isDirectory);
|
||||
data.put("lastModified", lastModified);
|
||||
return data;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -17,10 +17,7 @@ import androidx.annotation.VisibleForTesting;
|
|||
import androidx.core.app.ActivityCompat;
|
||||
|
||||
import java.io.File;
|
||||
import java.lang.reflect.Array;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.Collections;
|
||||
import java.util.HashMap;
|
||||
|
||||
import io.flutter.plugin.common.EventChannel;
|
||||
|
@ -36,6 +33,7 @@ public class FilePickerDelegate implements PluginRegistry.ActivityResultListener
|
|||
private final PermissionManager permissionManager;
|
||||
private MethodChannel.Result pendingResult;
|
||||
private boolean isMultipleSelection = false;
|
||||
private boolean loadDataToMemory = false;
|
||||
private String type;
|
||||
private String[] allowedExtensions;
|
||||
private EventChannel.EventSink eventSink;
|
||||
|
@ -92,7 +90,7 @@ public class FilePickerDelegate implements PluginRegistry.ActivityResultListener
|
|||
int currentItem = 0;
|
||||
while (currentItem < count) {
|
||||
final Uri currentUri = data.getClipData().getItemAt(currentItem).getUri();
|
||||
final FileInfo file = FileUtils.openFileStream(FilePickerDelegate.this.activity, currentUri);
|
||||
final FileInfo file = FileUtils.openFileStream(FilePickerDelegate.this.activity, currentUri, loadDataToMemory);
|
||||
|
||||
if(file != null) {
|
||||
files.add(file);
|
||||
|
@ -121,7 +119,7 @@ public class FilePickerDelegate implements PluginRegistry.ActivityResultListener
|
|||
return;
|
||||
}
|
||||
|
||||
final FileInfo file = FileUtils.openFileStream(FilePickerDelegate.this.activity, uri);
|
||||
final FileInfo file = FileUtils.openFileStream(FilePickerDelegate.this.activity, uri, loadDataToMemory);
|
||||
|
||||
if(file != null) {
|
||||
files.add(file);
|
||||
|
@ -223,7 +221,7 @@ public class FilePickerDelegate implements PluginRegistry.ActivityResultListener
|
|||
}
|
||||
|
||||
@SuppressWarnings("deprecation")
|
||||
public void startFileExplorer(final String type, final boolean isMultipleSelection, final String[] allowedExtensions, final MethodChannel.Result result) {
|
||||
public void startFileExplorer(final String type, final boolean isMultipleSelection, final boolean withData, final String[] allowedExtensions, final MethodChannel.Result result) {
|
||||
|
||||
if (!this.setPendingMethodCallAndResult(result)) {
|
||||
finishWithAlreadyActiveError(result);
|
||||
|
@ -232,6 +230,7 @@ public class FilePickerDelegate implements PluginRegistry.ActivityResultListener
|
|||
|
||||
this.type = type;
|
||||
this.isMultipleSelection = isMultipleSelection;
|
||||
this.loadDataToMemory = withData;
|
||||
this.allowedExtensions = allowedExtensions;
|
||||
|
||||
if (!this.permissionManager.isPermissionGranted(Manifest.permission.READ_EXTERNAL_STORAGE)) {
|
||||
|
@ -242,6 +241,7 @@ public class FilePickerDelegate implements PluginRegistry.ActivityResultListener
|
|||
this.startFileExplorer();
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
private void finishWithSuccess(Object data) {
|
||||
if (eventSink != null) {
|
||||
this.dispatchEventStatus(false);
|
||||
|
|
|
@ -112,6 +112,7 @@ public class FilePickerPlugin implements MethodChannel.MethodCallHandler, Flutte
|
|||
private MethodChannel channel;
|
||||
private static String fileType;
|
||||
private static boolean isMultipleSelection = false;
|
||||
private static boolean withData = false;
|
||||
|
||||
/**
|
||||
* Plugin registration.
|
||||
|
@ -160,13 +161,14 @@ public class FilePickerPlugin implements MethodChannel.MethodCallHandler, Flutte
|
|||
result.notImplemented();
|
||||
} else if (fileType != "dir") {
|
||||
isMultipleSelection = (boolean) arguments.get("allowMultipleSelection");
|
||||
withData = (boolean) arguments.get("withData");
|
||||
allowedExtensions = FileUtils.getMimeTypes((ArrayList<String>) arguments.get("allowedExtensions"));
|
||||
}
|
||||
|
||||
if (fileType == "custom" && (allowedExtensions == null || allowedExtensions.length == 0)) {
|
||||
result.error(TAG, "Unsupported filter. Make sure that you are only using the extension without the dot, (ie., jpg instead of .jpg). This could also have happened because you are using an unsupported file extension. If the problem persists, you may want to consider using FileType.all instead.", null);
|
||||
} else {
|
||||
this.delegate.startFileExplorer(fileType, isMultipleSelection, allowedExtensions, result);
|
||||
this.delegate.startFileExplorer(fileType, isMultipleSelection, withData, allowedExtensions, result);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -116,7 +116,7 @@ public class FileUtils {
|
|||
return true;
|
||||
}
|
||||
|
||||
public static FileInfo openFileStream(final Context context, final Uri uri) {
|
||||
public static FileInfo openFileStream(final Context context, final Uri uri, boolean withData) {
|
||||
|
||||
Log.i(TAG, "Caching from URI: " + uri.toString());
|
||||
FileOutputStream fos = null;
|
||||
|
@ -126,7 +126,7 @@ public class FileUtils {
|
|||
|
||||
final File file = new File(path);
|
||||
|
||||
if(file.exists()) {
|
||||
if(file.exists() && withData) {
|
||||
int size = (int) file.length();
|
||||
byte[] bytes = new byte[size];
|
||||
|
||||
|
@ -156,7 +156,9 @@ public class FileUtils {
|
|||
out.write(buffer, 0, len);
|
||||
}
|
||||
|
||||
fileInfo.withData(out.toByteArray());
|
||||
if(withData) {
|
||||
fileInfo.withData(out.toByteArray());
|
||||
}
|
||||
out.writeTo(fos);
|
||||
out.flush();
|
||||
} finally {
|
||||
|
@ -177,11 +179,9 @@ public class FileUtils {
|
|||
Log.d(TAG, "File loaded and cached at:" + path);
|
||||
|
||||
fileInfo
|
||||
.lastModifiedAt(file.lastModified())
|
||||
.withPath(path)
|
||||
.withName(fileName)
|
||||
.withSize(Integer.parseInt(String.valueOf(file.length()/1024)))
|
||||
.withUri(uri);
|
||||
.withSize(Integer.parseInt(String.valueOf(file.length()/1024)));
|
||||
|
||||
return fileInfo.build();
|
||||
}
|
||||
|
@ -195,8 +195,6 @@ public class FileUtils {
|
|||
String volumePath = getVolumePath(getVolumeIdFromTreeUri(treeUri), con);
|
||||
FileInfo.Builder fileInfo = new FileInfo.Builder();
|
||||
|
||||
fileInfo.withUri(treeUri);
|
||||
|
||||
if (volumePath == null) {
|
||||
return File.separator;
|
||||
}
|
||||
|
|
|
@ -17,7 +17,7 @@ allprojects {
|
|||
gradle.projectsEvaluated {
|
||||
tasks.withType(JavaCompile) {
|
||||
options.encoding = 'UTF-8'
|
||||
options.compilerArgs << "-Xlint:deprecation"
|
||||
options.compilerArgs << "-Xlint:unchecked" << "-Xlint:deprecation"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -164,7 +164,7 @@
|
|||
97C146E61CF9000F007C117D /* Project object */ = {
|
||||
isa = PBXProject;
|
||||
attributes = {
|
||||
LastUpgradeCheck = 1010;
|
||||
LastUpgradeCheck = 1170;
|
||||
ORGANIZATIONNAME = "The Chromium Authors";
|
||||
TargetAttributes = {
|
||||
97C146ED1CF9000F007C117D = {
|
||||
|
@ -176,10 +176,9 @@
|
|||
};
|
||||
buildConfigurationList = 97C146E91CF9000F007C117D /* Build configuration list for PBXProject "Runner" */;
|
||||
compatibilityVersion = "Xcode 3.2";
|
||||
developmentRegion = English;
|
||||
developmentRegion = en;
|
||||
hasScannedForEncodings = 0;
|
||||
knownRegions = (
|
||||
English,
|
||||
en,
|
||||
Base,
|
||||
);
|
||||
|
@ -416,6 +415,7 @@
|
|||
isa = XCBuildConfiguration;
|
||||
baseConfigurationReference = 9740EEB21CF90195004384FC /* Debug.xcconfig */;
|
||||
buildSettings = {
|
||||
ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = YES;
|
||||
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
|
||||
CODE_SIGN_IDENTITY = "Apple Development";
|
||||
CODE_SIGN_STYLE = Automatic;
|
||||
|
@ -443,6 +443,7 @@
|
|||
isa = XCBuildConfiguration;
|
||||
baseConfigurationReference = 7AFA3C8E1D35360C0083082E /* Release.xcconfig */;
|
||||
buildSettings = {
|
||||
ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = YES;
|
||||
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
|
||||
CODE_SIGN_IDENTITY = "Apple Development";
|
||||
CODE_SIGN_STYLE = Automatic;
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<Scheme
|
||||
LastUpgradeVersion = "1010"
|
||||
LastUpgradeVersion = "1170"
|
||||
version = "1.3">
|
||||
<BuildAction
|
||||
parallelizeBuildables = "YES"
|
||||
|
|
|
@ -0,0 +1,21 @@
|
|||
//
|
||||
// FileInfo.h
|
||||
// file_picker
|
||||
//
|
||||
// Created by Miguel Ruivo on 11/09/2020.
|
||||
//
|
||||
|
||||
@interface FileInfo : NSObject
|
||||
|
||||
@property (nonatomic, strong) NSString * path;
|
||||
@property (nonatomic, strong) NSString * name;
|
||||
@property (nonatomic, strong) NSNumber * size;
|
||||
@property (nonatomic, strong) NSData * bytes;
|
||||
@property (nonatomic, strong) NSNumber * isDirectory;
|
||||
|
||||
- (instancetype) initWithPath: (NSString *)path andName: (NSString *)name andSize: (NSNumber *) size andData:(NSData*) data;
|
||||
|
||||
- (NSDictionary *) toData;
|
||||
|
||||
@end
|
||||
|
|
@ -0,0 +1,34 @@
|
|||
//
|
||||
// FileInfo.m
|
||||
// file_picker
|
||||
//
|
||||
// Created by Miguel Ruivo on 11/09/2020.
|
||||
//
|
||||
|
||||
#import "FileInfo.h"
|
||||
|
||||
@implementation FileInfo
|
||||
|
||||
- (instancetype) initWithPath: (NSString *)path andName: (NSString *)name andSize: (NSNumber *) size andData:(NSData*) data {
|
||||
|
||||
self = [super init];
|
||||
|
||||
if (self) {
|
||||
self.path = path;
|
||||
self.name = name;
|
||||
self.size = size;
|
||||
self.bytes = data;
|
||||
}
|
||||
return self;
|
||||
}
|
||||
|
||||
- (NSDictionary *)toData {
|
||||
NSMutableDictionary * data = [[NSMutableDictionary alloc] init];
|
||||
[data setValue:self.path forKey:@"path"];
|
||||
[data setValue:self.name forKey:@"name"];
|
||||
[data setValue:self.size forKey:@"size"];
|
||||
[data setValue:self.bytes forKey:@"bytes"];
|
||||
return data;
|
||||
}
|
||||
|
||||
@end
|
|
@ -13,6 +13,7 @@
|
|||
@property (nonatomic) UIDocumentInteractionController *interactionController;
|
||||
@property (nonatomic) MPMediaPickerController *audioPickerController;
|
||||
@property (nonatomic) NSArray<NSString *> * allowedExtensions;
|
||||
@property (nonatomic) BOOL loadDataToMemory;
|
||||
@end
|
||||
|
||||
@implementation FilePickerPlugin
|
||||
|
@ -76,6 +77,8 @@
|
|||
|
||||
NSDictionary * arguments = call.arguments;
|
||||
BOOL isMultiplePick = ((NSNumber*)[arguments valueForKey:@"allowMultipleSelection"]).boolValue;
|
||||
self.loadDataToMemory = ((NSNumber*)[arguments valueForKey:@"withData"]).boolValue;
|
||||
|
||||
if([call.method isEqualToString:@"any"] || [call.method containsString:@"custom"]) {
|
||||
self.allowedExtensions = [FileUtils resolveType:call.method withAllowedExtensions: [arguments valueForKey:@"allowedExtensions"]];
|
||||
if(self.allowedExtensions == nil) {
|
||||
|
@ -89,7 +92,7 @@
|
|||
} else if([call.method isEqualToString:@"video"] || [call.method isEqualToString:@"image"] || [call.method isEqualToString:@"media"]) {
|
||||
[self resolvePickMedia:[FileUtils resolveMediaType:call.method] withMultiPick:isMultiplePick withCompressionAllowed:[arguments valueForKey:@"allowCompression"]];
|
||||
} else if([call.method isEqualToString:@"audio"]) {
|
||||
[self resolvePickAudio];
|
||||
[self resolvePickAudioWithMultiPick: isMultiplePick];
|
||||
} else {
|
||||
result(FlutterMethodNotImplemented);
|
||||
_result = nil;
|
||||
|
@ -223,38 +226,40 @@
|
|||
|
||||
// Did select
|
||||
[dkImagePickerController setDidSelectAssets:^(NSArray<DKAsset*> * __nonnull DKAssets) {
|
||||
NSMutableArray<NSString*>* paths = [[NSMutableArray<NSString*> alloc] init];
|
||||
NSMutableArray<NSURL*>* paths = [[NSMutableArray<NSURL*> alloc] init];
|
||||
|
||||
for(DKAsset * asset in DKAssets){
|
||||
[paths addObject:asset.localTemporaryPath.path];
|
||||
[paths addObject:asset.localTemporaryPath.absoluteURL];
|
||||
}
|
||||
|
||||
self->_result([paths count] > 0 ? paths : nil);
|
||||
self->_result = nil;
|
||||
[self handleResult: paths];
|
||||
}];
|
||||
|
||||
[_viewController presentViewController:dkImagePickerController animated:YES completion:nil];
|
||||
}
|
||||
|
||||
- (void) resolvePickAudio {
|
||||
- (void) resolvePickAudioWithMultiPick:(BOOL)isMultiPick {
|
||||
|
||||
self.audioPickerController = [[MPMediaPickerController alloc] initWithMediaTypes:MPMediaTypeAnyAudio];
|
||||
self.audioPickerController.delegate = self;
|
||||
self.audioPickerController.showsCloudItems = NO;
|
||||
self.audioPickerController.allowsPickingMultipleItems = NO;
|
||||
self.audioPickerController.showsCloudItems = YES;
|
||||
self.audioPickerController.allowsPickingMultipleItems = isMultiPick;
|
||||
self.audioPickerController.modalPresentationStyle = UIModalPresentationCurrentContext;
|
||||
|
||||
[self.viewController presentViewController:self.audioPickerController animated:YES completion:nil];
|
||||
}
|
||||
|
||||
- (void) handleResult:(id) files {
|
||||
_result([FileUtils resolveFileInfo: [files isKindOfClass: [NSArray class]] ? files : @[files] withData:self.loadDataToMemory]);
|
||||
_result = nil;
|
||||
}
|
||||
|
||||
#pragma mark - Delegates
|
||||
|
||||
// DocumentPicker delegate - iOS 10 only
|
||||
- (void)documentPicker:(UIDocumentPickerViewController *)controller didPickDocumentAtURL:(NSURL *)url{
|
||||
[self.documentPickerController dismissViewControllerAnimated:YES completion:nil];
|
||||
NSString * path = (NSString *)[url path];
|
||||
_result(@[path]);
|
||||
_result = nil;
|
||||
[self handleResult:url];
|
||||
}
|
||||
|
||||
// DocumentPicker delegate
|
||||
|
@ -266,10 +271,14 @@ didPickDocumentsAtURLs:(NSArray<NSURL *> *)urls{
|
|||
}
|
||||
|
||||
[self.documentPickerController dismissViewControllerAnimated:YES completion:nil];
|
||||
NSArray * result = [FileUtils resolvePath:urls];
|
||||
_result(result);
|
||||
_result = nil;
|
||||
|
||||
if(controller.documentPickerMode == UIDocumentPickerModeOpen) {
|
||||
_result([urls objectAtIndex:0].path);
|
||||
_result = nil;
|
||||
return;
|
||||
}
|
||||
|
||||
[self handleResult: urls];
|
||||
}
|
||||
|
||||
|
||||
|
@ -318,8 +327,7 @@ didPickDocumentsAtURLs:(NSArray<NSURL *> *)urls{
|
|||
return;
|
||||
}
|
||||
|
||||
_result(@[[pickedVideoUrl != nil ? pickedVideoUrl : pickedImageUrl path]]);
|
||||
_result = nil;
|
||||
[self handleResult: pickedVideoUrl != nil ? pickedVideoUrl : pickedImageUrl];
|
||||
}
|
||||
|
||||
|
||||
|
@ -327,12 +335,16 @@ didPickDocumentsAtURLs:(NSArray<NSURL *> *)urls{
|
|||
- (void)mediaPicker: (MPMediaPickerController *)mediaPicker didPickMediaItems:(MPMediaItemCollection *)mediaItemCollection
|
||||
{
|
||||
[mediaPicker dismissViewControllerAnimated:YES completion:NULL];
|
||||
NSURL *url = [[[mediaItemCollection items] objectAtIndex:0] valueForKey:MPMediaItemPropertyAssetURL];
|
||||
if(url == nil) {
|
||||
NSMutableArray<NSURL *> * urls = [[NSMutableArray alloc] initWithCapacity:[mediaItemCollection items].count];
|
||||
|
||||
for(MPMediaItemCollection * item in [mediaItemCollection items]) {
|
||||
[urls addObject: [item valueForKey:MPMediaItemPropertyAssetURL]];
|
||||
}
|
||||
|
||||
if(urls.count == 0) {
|
||||
Log(@"Couldn't retrieve the audio file path, either is not locally downloaded or the file is DRM protected.");
|
||||
}
|
||||
_result([url absoluteString]);
|
||||
_result = nil;
|
||||
[self handleResult:urls];
|
||||
}
|
||||
|
||||
#pragma mark - Actions canceled
|
||||
|
|
|
@ -23,7 +23,7 @@ typedef NS_ENUM(NSInteger, MediaType) {
|
|||
+ (BOOL) clearTemporaryFiles;
|
||||
+ (NSArray<NSString*>*) resolveType:(NSString*)type withAllowedExtensions:(NSArray<NSString*>*)allowedExtensions;
|
||||
+ (MediaType) resolveMediaType:(NSString*)type;
|
||||
+ (NSArray*) resolvePath:(NSArray<NSURL *> *)urls;
|
||||
+ (NSArray<NSDictionary*>*) resolveFileInfo:(NSArray<NSURL *> *)urls withData:(BOOL)loadData;
|
||||
@end
|
||||
|
||||
|
||||
|
|
|
@ -6,11 +6,12 @@
|
|||
//
|
||||
|
||||
#import "FileUtils.h"
|
||||
#import "FileInfo.h"
|
||||
|
||||
@implementation FileUtils
|
||||
|
||||
+ (BOOL) clearTemporaryFiles {
|
||||
NSString *tmpDirectory = NSTemporaryDirectory();
|
||||
NSString *tmpDirectory = NSTemporaryDirectory();
|
||||
NSFileManager *fileManager = [NSFileManager defaultManager];
|
||||
NSError *error;
|
||||
NSArray *cacheFiles = [fileManager contentsOfDirectoryAtPath:tmpDirectory error:&error];
|
||||
|
@ -75,16 +76,25 @@
|
|||
}
|
||||
}
|
||||
|
||||
+ (NSMutableArray*) resolvePath:(NSArray<NSURL *> *)urls{
|
||||
NSString * uri;
|
||||
NSMutableArray * paths = [[NSMutableArray alloc] init];
|
||||
+ (NSArray<NSDictionary *> *)resolveFileInfo:(NSArray<NSURL *> *)urls withData: (BOOL)loadData {
|
||||
|
||||
for (NSURL *url in urls) {
|
||||
uri = (NSString *)[url path];
|
||||
[paths addObject:uri];
|
||||
if(urls == nil) {
|
||||
return nil;
|
||||
}
|
||||
|
||||
return paths;
|
||||
NSMutableArray * files = [[NSMutableArray alloc] initWithCapacity:urls.count];
|
||||
|
||||
for(NSURL * url in urls) {
|
||||
NSString * path = (NSString *)[url path];
|
||||
NSDictionary<NSFileAttributeKey, id> * fileAttributes = [[NSFileManager defaultManager] attributesOfItemAtPath:path error:nil];
|
||||
|
||||
[files addObject: [[[FileInfo alloc] initWithPath: path
|
||||
andName: [[path lastPathComponent] stringByDeletingPathExtension]
|
||||
andSize: [NSNumber numberWithLongLong: [@(fileAttributes.fileSize) longLongValue] / 1024]
|
||||
andData: loadData ? [NSData dataWithContentsOfFile:path options: 0 error:nil] : nil] toData]];
|
||||
}
|
||||
|
||||
return files;
|
||||
}
|
||||
|
||||
@end
|
||||
|
|
|
@ -55,6 +55,7 @@ abstract class FilePicker extends PlatformInterface {
|
|||
Function(FilePickerStatus) onFileLoading,
|
||||
bool allowCompression,
|
||||
bool allowMultiple = false,
|
||||
bool withData,
|
||||
}) async =>
|
||||
throw UnimplementedError('pickFiles() has not been implemented.');
|
||||
|
||||
|
|
|
@ -20,10 +20,18 @@ class FilePickerIO extends FilePicker {
|
|||
FileType type = FileType.any,
|
||||
List<String> allowedExtensions,
|
||||
Function(FilePickerStatus) onFileLoading,
|
||||
bool allowCompression,
|
||||
bool allowCompression = true,
|
||||
bool allowMultiple = false,
|
||||
bool withData = false,
|
||||
}) =>
|
||||
_getPath(type, allowMultiple, allowCompression, allowedExtensions, onFileLoading);
|
||||
_getPath(
|
||||
type,
|
||||
allowMultiple,
|
||||
allowCompression,
|
||||
allowedExtensions,
|
||||
onFileLoading,
|
||||
withData,
|
||||
);
|
||||
|
||||
@override
|
||||
Future<bool> clearTemporaryFiles() async => _channel.invokeMethod<bool>('clear');
|
||||
|
@ -47,6 +55,7 @@ class FilePickerIO extends FilePicker {
|
|||
bool allowCompression,
|
||||
List<String> allowedExtensions,
|
||||
Function(FilePickerStatus) onFileLoading,
|
||||
bool withData,
|
||||
) async {
|
||||
final String type = describeEnum(fileType);
|
||||
if (type != 'custom' && (allowedExtensions?.isNotEmpty ?? false)) {
|
||||
|
@ -65,6 +74,7 @@ class FilePickerIO extends FilePicker {
|
|||
'allowMultipleSelection': allowMultipleSelection,
|
||||
'allowedExtensions': allowedExtensions,
|
||||
'allowCompression': allowCompression,
|
||||
'withData': withData,
|
||||
});
|
||||
|
||||
if (result == null) {
|
||||
|
|
|
@ -24,6 +24,7 @@ class FilePickerWeb extends FilePicker {
|
|||
bool allowMultiple = false,
|
||||
Function(FilePickerStatus) onFileLoading,
|
||||
bool allowCompression,
|
||||
bool withData = true,
|
||||
}) async {
|
||||
final Completer<List<PlatformFile>> filesCompleter = Completer<List<PlatformFile>>();
|
||||
|
||||
|
@ -48,7 +49,7 @@ class FilePickerWeb extends FilePicker {
|
|||
name: uploadInput.value.replaceAll('\\', '/'),
|
||||
path: uploadInput.value,
|
||||
size: bytes.length ~/ 1024,
|
||||
bytes: bytes,
|
||||
bytes: withData ? bytes : null,
|
||||
),
|
||||
);
|
||||
|
||||
|
|
|
@ -3,7 +3,6 @@ import 'dart:typed_data';
|
|||
class PlatformFile {
|
||||
const PlatformFile({
|
||||
this.path,
|
||||
this.uri,
|
||||
this.name,
|
||||
this.bytes,
|
||||
this.size,
|
||||
|
@ -12,28 +11,18 @@ class PlatformFile {
|
|||
|
||||
PlatformFile.fromMap(Map data)
|
||||
: this.path = data['path'],
|
||||
this.uri = data['uri'],
|
||||
this.name = data['name'],
|
||||
this.bytes = data['bytes'],
|
||||
this.size = data['size'],
|
||||
this.isDirectory = data['isDirectory'];
|
||||
|
||||
/// The absolute path for a cached copy of this file.
|
||||
/// If you want to access the original file identifier use [uri] property instead.
|
||||
/// The absolute path for a cached copy of this file. It can be used to create a
|
||||
/// a file instance with a descriptor for the given path.
|
||||
/// ```
|
||||
/// final File myFile = File(platformFile.path);
|
||||
/// ```
|
||||
final String path;
|
||||
|
||||
/// The URI (Universal Resource Identifier) for this file.
|
||||
///
|
||||
/// This is the identifier of original resource and can be used to
|
||||
/// manipulate the original file (read, write, delete).
|
||||
///
|
||||
/// Android: it can be either content:// or file:// url.
|
||||
///
|
||||
/// iOS: a file:// URL below a document provider (like iCloud).
|
||||
///
|
||||
/// Web: Not supported, will be always `null`.
|
||||
final String uri;
|
||||
|
||||
/// File name including its extension.
|
||||
final String name;
|
||||
|
||||
|
@ -48,5 +37,5 @@ class PlatformFile {
|
|||
final bool isDirectory;
|
||||
|
||||
/// File extension for this file.
|
||||
String get extension => name?.split('/')?.last;
|
||||
String get extension => path?.split('.')?.last;
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue