From 4b1c047581042ac8fcbc16782f992138b0b7fed9 Mon Sep 17 00:00:00 2001 From: Miguel Ruivo Date: Mon, 27 Apr 2020 22:25:57 +0100 Subject: [PATCH] Adds FileType.media for picking both images & video at same time --- CHANGELOG.md | 3 + README.md | 7 +- .../plugin/filepicker/FilePickerDelegate.java | 11 ++- .../plugin/filepicker/FilePickerPlugin.java | 14 ++-- example/ios/Podfile | 2 +- example/ios/Runner.xcodeproj/project.pbxproj | 82 +++++++++---------- example/lib/src/file_picker_demo.dart | 4 + go/file_darwin.go | 15 ++-- go/file_linux.go | 12 +-- go/file_windows.go | 16 ++-- ios/Classes/FilePickerPlugin.m | 56 ++++++------- ios/Classes/FileUtils.h | 7 ++ ios/Classes/FileUtils.m | 22 +++-- lib/file_picker.dart | 27 ++---- pubspec.yaml | 2 +- 15 files changed, 152 insertions(+), 128 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 236e747..07c4d72 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,6 @@ +## 1.8.0 +Adds `FileType.media` that will allow you to pick video and images at the same time. On iOS, this will let you pick directly from Photos app (gallery), if you want to use Files app, you _must_ use `FileType.custom` with desired extensions. + ## 1.7.1 Updates iOS multi gallery picker dependency and adds a modal loading while fetching exporting assets. diff --git a/README.md b/README.md index fc76c6c..d425af3 100644 --- a/README.md +++ b/README.md @@ -21,9 +21,10 @@ A package that allows you to use a native file explorer to pick single or multip * Load paths from **cloud files** (GDrive, Dropbox, iCloud) * Load path from a **custom format** by providing a list of file extensions (pdf, svg, zip, etc.) * Load path from **multiple files** optionally, supplying file extensions -* Load path from **gallery** -* Load path from **audio** -* Load path from **video** +* Load path from **media** (video & image only) +* Load path from **audio** only +* Load path from **image** only +* Load path from **video** only * Load path from **any** * Create a `File` or `List` objects from **any** selected file(s) * Supports desktop through **go-flutter** (MacOS, Windows, Linux) diff --git a/android/src/main/java/com/mr/flutter/plugin/filepicker/FilePickerDelegate.java b/android/src/main/java/com/mr/flutter/plugin/filepicker/FilePickerDelegate.java index 88bfa4d..6b61dfa 100644 --- a/android/src/main/java/com/mr/flutter/plugin/filepicker/FilePickerDelegate.java +++ b/android/src/main/java/com/mr/flutter/plugin/filepicker/FilePickerDelegate.java @@ -123,10 +123,10 @@ public class FilePickerDelegate implements PluginRegistry.ActivityResultListener @Override public boolean onRequestPermissionsResult(final int requestCode, final String[] permissions, final int[] grantResults) { - if(REQUEST_CODE != requestCode) { + if (REQUEST_CODE != requestCode) { return false; } - + final boolean permissionGranted = grantResults.length > 0 && grantResults[0] == PackageManager.PERMISSION_GRANTED; @@ -151,17 +151,22 @@ public class FilePickerDelegate implements PluginRegistry.ActivityResultListener result.error("already_active", "File picker is already active", null); } + @SuppressWarnings("deprecation") private void startFileExplorer() { final Intent intent; intent = new Intent(Intent.ACTION_GET_CONTENT); final Uri uri = Uri.parse(Environment.getExternalStorageDirectory().getPath() + File.separator); - + Log.d(TAG, "Type" + type); intent.setDataAndType(uri, this.type); intent.setType(this.type); intent.putExtra(Intent.EXTRA_ALLOW_MULTIPLE, this.isMultipleSelection); intent.addCategory(Intent.CATEGORY_OPENABLE); + if (type.contains(",")) { + allowedExtensions = type.split(","); + } + if (allowedExtensions != null) { intent.putExtra(Intent.EXTRA_MIME_TYPES, allowedExtensions); } diff --git a/android/src/main/java/com/mr/flutter/plugin/filepicker/FilePickerPlugin.java b/android/src/main/java/com/mr/flutter/plugin/filepicker/FilePickerPlugin.java index 292d579..d63492e 100644 --- a/android/src/main/java/com/mr/flutter/plugin/filepicker/FilePickerPlugin.java +++ b/android/src/main/java/com/mr/flutter/plugin/filepicker/FilePickerPlugin.java @@ -153,7 +153,7 @@ public class FilePickerPlugin implements MethodChannel.MethodCallHandler, Flutte if (fileType == null) { result.notImplemented(); - } else if (fileType == "CUSTOM" && (allowedExtensions == null || allowedExtensions.length == 0)) { + } else 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); @@ -165,14 +165,16 @@ public class FilePickerPlugin implements MethodChannel.MethodCallHandler, Flutte switch (type) { - case "AUDIO": + case "audio": return "audio/*"; - case "IMAGE": + case "image": return "image/*"; - case "VIDEO": + case "video": return "video/*"; - case "ANY": - case "CUSTOM": + case "media": + return "image/*,video/*"; + case "any": + case "custom": return "*/*"; default: return null; diff --git a/example/ios/Podfile b/example/ios/Podfile index 5b51f56..97e4d2c 100644 --- a/example/ios/Podfile +++ b/example/ios/Podfile @@ -1,5 +1,5 @@ # Uncomment this line to define a global platform for your project -# platform :ios, '9.0' +platform :ios, '8.0' # CocoaPods analytics sends network stats synchronously affecting flutter build latency. ENV['COCOAPODS_DISABLE_STATS'] = 'true' diff --git a/example/ios/Runner.xcodeproj/project.pbxproj b/example/ios/Runner.xcodeproj/project.pbxproj index 879e3e3..7dd7764 100644 --- a/example/ios/Runner.xcodeproj/project.pbxproj +++ b/example/ios/Runner.xcodeproj/project.pbxproj @@ -9,12 +9,12 @@ /* Begin PBXBuildFile section */ 1498D2341E8E89220040F4C2 /* GeneratedPluginRegistrant.m in Sources */ = {isa = PBXBuildFile; fileRef = 1498D2331E8E89220040F4C2 /* GeneratedPluginRegistrant.m */; }; 3B3967161E833CAA004F5970 /* AppFrameworkInfo.plist in Resources */ = {isa = PBXBuildFile; fileRef = 3B3967151E833CAA004F5970 /* AppFrameworkInfo.plist */; }; + 78EB448BD5060711D7E3FCEC /* Pods_Runner.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 4FE42FA345519DC2CF8F7CAB /* Pods_Runner.framework */; }; 978B8F6F1D3862AE00F588F7 /* AppDelegate.m in Sources */ = {isa = PBXBuildFile; fileRef = 7AFFD8EE1D35381100E5BB4D /* AppDelegate.m */; }; 97C146F31CF9000F007C117D /* main.m in Sources */ = {isa = PBXBuildFile; fileRef = 97C146F21CF9000F007C117D /* main.m */; }; 97C146FC1CF9000F007C117D /* Main.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 97C146FA1CF9000F007C117D /* Main.storyboard */; }; 97C146FE1CF9000F007C117D /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 97C146FD1CF9000F007C117D /* Assets.xcassets */; }; 97C147011CF9000F007C117D /* LaunchScreen.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 97C146FF1CF9000F007C117D /* LaunchScreen.storyboard */; }; - F4241881D42A79991D987032 /* Pods_Runner.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = E093F13416E116B41F70DC9A /* Pods_Runner.framework */; }; /* End PBXBuildFile section */ /* Begin PBXCopyFilesBuildPhase section */ @@ -31,14 +31,16 @@ /* End PBXCopyFilesBuildPhase section */ /* Begin PBXFileReference section */ + 12526927AA724E8A8C5BA965 /* Pods-Runner.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-Runner.release.xcconfig"; path = "Target Support Files/Pods-Runner/Pods-Runner.release.xcconfig"; sourceTree = ""; }; 1498D2321E8E86230040F4C2 /* GeneratedPluginRegistrant.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = GeneratedPluginRegistrant.h; sourceTree = ""; }; 1498D2331E8E89220040F4C2 /* GeneratedPluginRegistrant.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = GeneratedPluginRegistrant.m; sourceTree = ""; }; 3B3967151E833CAA004F5970 /* AppFrameworkInfo.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; name = AppFrameworkInfo.plist; path = Flutter/AppFrameworkInfo.plist; sourceTree = ""; }; 3B80C3931E831B6300D905FE /* App.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = App.framework; path = Flutter/App.framework; sourceTree = ""; }; + 4FE42FA345519DC2CF8F7CAB /* Pods_Runner.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Pods_Runner.framework; sourceTree = BUILT_PRODUCTS_DIR; }; + 620D3249E16C66CF31F39A1D /* Pods-Runner.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-Runner.debug.xcconfig"; path = "Target Support Files/Pods-Runner/Pods-Runner.debug.xcconfig"; sourceTree = ""; }; 7AFA3C8E1D35360C0083082E /* Release.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; name = Release.xcconfig; path = Flutter/Release.xcconfig; sourceTree = ""; }; 7AFFD8ED1D35381100E5BB4D /* AppDelegate.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = AppDelegate.h; sourceTree = ""; }; 7AFFD8EE1D35381100E5BB4D /* AppDelegate.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = AppDelegate.m; sourceTree = ""; }; - 92150FFEDED79AD7268B2247 /* Pods-Runner.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-Runner.release.xcconfig"; path = "Target Support Files/Pods-Runner/Pods-Runner.release.xcconfig"; sourceTree = ""; }; 9740EEB21CF90195004384FC /* Debug.xcconfig */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.xcconfig; name = Debug.xcconfig; path = Flutter/Debug.xcconfig; sourceTree = ""; }; 9740EEB31CF90195004384FC /* Generated.xcconfig */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.xcconfig; name = Generated.xcconfig; path = Flutter/Generated.xcconfig; sourceTree = ""; }; 9740EEBA1CF902C7004384FC /* Flutter.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Flutter.framework; path = Flutter/Flutter.framework; sourceTree = ""; }; @@ -48,8 +50,6 @@ 97C146FD1CF9000F007C117D /* Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Assets.xcassets; sourceTree = ""; }; 97C147001CF9000F007C117D /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/LaunchScreen.storyboard; sourceTree = ""; }; 97C147021CF9000F007C117D /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; - A20269E5E72E5C7764E96D49 /* Pods-Runner.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-Runner.debug.xcconfig"; path = "Target Support Files/Pods-Runner/Pods-Runner.debug.xcconfig"; sourceTree = ""; }; - E093F13416E116B41F70DC9A /* Pods_Runner.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Pods_Runner.framework; sourceTree = BUILT_PRODUCTS_DIR; }; /* End PBXFileReference section */ /* Begin PBXFrameworksBuildPhase section */ @@ -57,7 +57,7 @@ isa = PBXFrameworksBuildPhase; buildActionMask = 2147483647; files = ( - F4241881D42A79991D987032 /* Pods_Runner.framework in Frameworks */, + 78EB448BD5060711D7E3FCEC /* Pods_Runner.framework in Frameworks */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -84,7 +84,7 @@ 97C146F01CF9000F007C117D /* Runner */, 97C146EF1CF9000F007C117D /* Products */, E62393F6B8A7F2BF56A0B62D /* Pods */, - EF8FB2B5878597859ACDA5F4 /* Frameworks */, + D2A1DF9F69FF1E54F4223294 /* Frameworks */, ); sourceTree = ""; }; @@ -120,23 +120,23 @@ name = "Supporting Files"; sourceTree = ""; }; + D2A1DF9F69FF1E54F4223294 /* Frameworks */ = { + isa = PBXGroup; + children = ( + 4FE42FA345519DC2CF8F7CAB /* Pods_Runner.framework */, + ); + name = Frameworks; + sourceTree = ""; + }; E62393F6B8A7F2BF56A0B62D /* Pods */ = { isa = PBXGroup; children = ( - A20269E5E72E5C7764E96D49 /* Pods-Runner.debug.xcconfig */, - 92150FFEDED79AD7268B2247 /* Pods-Runner.release.xcconfig */, + 620D3249E16C66CF31F39A1D /* Pods-Runner.debug.xcconfig */, + 12526927AA724E8A8C5BA965 /* Pods-Runner.release.xcconfig */, ); path = Pods; sourceTree = ""; }; - EF8FB2B5878597859ACDA5F4 /* Frameworks */ = { - isa = PBXGroup; - children = ( - E093F13416E116B41F70DC9A /* Pods_Runner.framework */, - ); - name = Frameworks; - sourceTree = ""; - }; /* End PBXGroup section */ /* Begin PBXNativeTarget section */ @@ -144,14 +144,14 @@ isa = PBXNativeTarget; buildConfigurationList = 97C147051CF9000F007C117D /* Build configuration list for PBXNativeTarget "Runner" */; buildPhases = ( - A43F367F477195F57487AEAA /* [CP] Check Pods Manifest.lock */, + FC67C2E2F2E4233AAAFA3380 /* [CP] Check Pods Manifest.lock */, 9740EEB61CF901F6004384FC /* Run Script */, 97C146EA1CF9000F007C117D /* Sources */, 97C146EB1CF9000F007C117D /* Frameworks */, 97C146EC1CF9000F007C117D /* Resources */, 9705A1C41CF9048500538489 /* Embed Frameworks */, 3B06AD1E1E4923F5004D2608 /* Thin Binary */, - AE010F81F563ADC683AAAEBC /* [CP] Embed Pods Frameworks */, + D4399F71B49163E30FC870D5 /* [CP] Embed Pods Frameworks */, ); buildRules = ( ); @@ -240,29 +240,7 @@ shellPath = /bin/sh; shellScript = "/bin/sh \"$FLUTTER_ROOT/packages/flutter_tools/bin/xcode_backend.sh\" build"; }; - A43F367F477195F57487AEAA /* [CP] Check Pods Manifest.lock */ = { - isa = PBXShellScriptBuildPhase; - buildActionMask = 2147483647; - files = ( - ); - inputFileListPaths = ( - ); - inputPaths = ( - "${PODS_PODFILE_DIR_PATH}/Podfile.lock", - "${PODS_ROOT}/Manifest.lock", - ); - name = "[CP] Check Pods Manifest.lock"; - outputFileListPaths = ( - ); - outputPaths = ( - "$(DERIVED_FILE_DIR)/Pods-Runner-checkManifestLockResult.txt", - ); - runOnlyForDeploymentPostprocessing = 0; - shellPath = /bin/sh; - shellScript = "diff \"${PODS_PODFILE_DIR_PATH}/Podfile.lock\" \"${PODS_ROOT}/Manifest.lock\" > /dev/null\nif [ $? != 0 ] ; then\n # print error to STDERR\n echo \"error: The sandbox is not in sync with the Podfile.lock. Run 'pod install' or update your CocoaPods installation.\" >&2\n exit 1\nfi\n# This output is used by Xcode 'outputs' to avoid re-running this script phase.\necho \"SUCCESS\" > \"${SCRIPT_OUTPUT_FILE_0}\"\n"; - showEnvVarsInLog = 0; - }; - AE010F81F563ADC683AAAEBC /* [CP] Embed Pods Frameworks */ = { + D4399F71B49163E30FC870D5 /* [CP] Embed Pods Frameworks */ = { isa = PBXShellScriptBuildPhase; buildActionMask = 2147483647; files = ( @@ -298,6 +276,28 @@ shellScript = "\"${PODS_ROOT}/Target Support Files/Pods-Runner/Pods-Runner-frameworks.sh\"\n"; showEnvVarsInLog = 0; }; + FC67C2E2F2E4233AAAFA3380 /* [CP] Check Pods Manifest.lock */ = { + isa = PBXShellScriptBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + inputFileListPaths = ( + ); + inputPaths = ( + "${PODS_PODFILE_DIR_PATH}/Podfile.lock", + "${PODS_ROOT}/Manifest.lock", + ); + name = "[CP] Check Pods Manifest.lock"; + outputFileListPaths = ( + ); + outputPaths = ( + "$(DERIVED_FILE_DIR)/Pods-Runner-checkManifestLockResult.txt", + ); + runOnlyForDeploymentPostprocessing = 0; + shellPath = /bin/sh; + shellScript = "diff \"${PODS_PODFILE_DIR_PATH}/Podfile.lock\" \"${PODS_ROOT}/Manifest.lock\" > /dev/null\nif [ $? != 0 ] ; then\n # print error to STDERR\n echo \"error: The sandbox is not in sync with the Podfile.lock. Run 'pod install' or update your CocoaPods installation.\" >&2\n exit 1\nfi\n# This output is used by Xcode 'outputs' to avoid re-running this script phase.\necho \"SUCCESS\" > \"${SCRIPT_OUTPUT_FILE_0}\"\n"; + showEnvVarsInLog = 0; + }; /* End PBXShellScriptBuildPhase section */ /* Begin PBXSourcesBuildPhase section */ diff --git a/example/lib/src/file_picker_demo.dart b/example/lib/src/file_picker_demo.dart index 84355af..c680b89 100644 --- a/example/lib/src/file_picker_demo.dart +++ b/example/lib/src/file_picker_demo.dart @@ -86,6 +86,10 @@ class _FilePickerDemoState extends State { child: new Text('FROM VIDEO'), value: FileType.video, ), + new DropdownMenuItem( + child: new Text('FROM MEDIA'), + value: FileType.media, + ), new DropdownMenuItem( child: new Text('FROM ANY'), value: FileType.any, diff --git a/go/file_darwin.go b/go/file_darwin.go index 558880b..fa20f71 100644 --- a/go/file_darwin.go +++ b/go/file_darwin.go @@ -11,27 +11,32 @@ import ( func fileFilter(method string, extensions []string, size int, multi bool) (string, error) { switch method { - case "ANY": + case "any": if multi { return "*", nil } return `"public.item"`, nil - case "IMAGE": + case "image": if multi { return "jpg, jpeg, bmp, gif, png", nil } return `"public.image"`, nil - case "AUDIO": + case "audio": if multi { return "mp3, wav, midi, ogg, aac", nil } return `"public.audio"`, nil - case "VIDEO": + case "video": if multi { return "webm, mpeg, mkv, mp4, avi, mov, flv", nil } return `"public.movie"`, nil - case "CUSTOM": + case "media": + if multi { + return "webm, mpeg, mkv, mp4, avi, mov, flv, jpg, jpeg, bmp, gif, png", nil + } + return `"public.audiovisual-content"`, nil + case "custom": var i int var filters = "" for i = 0; i < size; i++ { diff --git a/go/file_linux.go b/go/file_linux.go index a156ea6..bcf7a24 100644 --- a/go/file_linux.go +++ b/go/file_linux.go @@ -7,15 +7,17 @@ import ( func fileFilter(method string, extensions []string, size int, isMulti bool) (string, error) { switch method { - case "ANY": + case "any": return `*.*`, nil - case "IMAGE": + case "image": return `*.png *.jpg *.jpeg`, nil - case "AUDIO": + case "audio": return `*.mp3 *.wav *.midi *.ogg *.aac`, nil - case "VIDEO": + case "video": return `*.webm *.mpeg *.mkv *.mp4 *.avi *.mov *.flv`, nil - case "CUSTOM": + case "media": + return `*.png *.jpg *.jpeg *.webm *.mpeg *.mkv *.mp4 *.avi *.mov *.flv`, nil + case "custom": var i int var filters = "" for i = 0; i < size; i++ { diff --git a/go/file_windows.go b/go/file_windows.go index 97d4118..230f27e 100644 --- a/go/file_windows.go +++ b/go/file_windows.go @@ -7,19 +7,21 @@ import ( func fileFilter(method string, extensions []string, size int, isMulti bool) (string, error) { switch method { - case "ANY": + case "any": return "*", nil - case "IMAGE": + case "image": return "Images (*.jpeg,*.png,*.gif)\x00*.jpg;*.jpeg;*.png;*.gif\x00All Files (*.*)\x00*.*\x00\x00", nil - case "AUDIO": + case "audio": return "Audios (*.mp3)\x00*.mp3\x00All Files (*.*)\x00*.*\x00\x00", nil - case "VIDEO": + case "video": return "Videos (*.webm,*.wmv,*.mpeg,*.mkv,*.mp4,*.avi,*.mov,*.flv)\x00*.webm;*.wmv;*.mpeg;*.mkv;*mp4;*.avi;*.mov;*.flv\x00All Files (*.*)\x00*.*\x00\x00", nil - case "CUSTOM": + case "media": + return "Videos (*.webm,*.wmv,*.mpeg,*.mkv,*.mp4,*.avi,*.mov,*.flv)\x00*.webm;*.wmv;*.mpeg;*.mkv;*mp4;*.avi;*.mov;*.flv\x00Images (*.jpeg,*.png,*.gif)\x00*.jpg;*.jpeg;*.png;*.gif\x00All Files (*.*)\x00*.*\x00\x00", nil + case "custom": var i int var filters = "Files (" - for i = 0 ; i * videoTypes = @[(NSString*)kUTTypeMovie, (NSString*)kUTTypeAVIMovie, (NSString*)kUTTypeVideo, (NSString*)kUTTypeMPEG4]; + NSArray * imageTypes = @[(NSString *)kUTTypeImage]; + self.galleryPickerController = [[UIImagePickerController alloc] init]; self.galleryPickerController.delegate = self; self.galleryPickerController.modalPresentationStyle = UIModalPresentationCurrentContext; - self.galleryPickerController.mediaTypes = @[(NSString *)kUTTypeImage]; - self.galleryPickerController.sourceType = UIImagePickerControllerSourceTypePhotoLibrary; - - [_viewController presentViewController:self.galleryPickerController animated:YES completion:nil]; - -} - -- (void) resolvePickVideo:(BOOL)withMultiPick { - - if(withMultiPick) { - [self resolveMultiPickFromGallery:YES]; - return; - } - - self.galleryPickerController = [[UIImagePickerController alloc] init]; - self.galleryPickerController.delegate = self; - self.galleryPickerController.modalPresentationStyle = UIModalPresentationCurrentContext; - self.galleryPickerController.mediaTypes = @[(NSString*)kUTTypeMovie, (NSString*)kUTTypeAVIMovie, (NSString*)kUTTypeVideo, (NSString*)kUTTypeMPEG4]; self.galleryPickerController.videoQuality = UIImagePickerControllerQualityTypeHigh; + switch (type) { + case IMAGE: + self.galleryPickerController.mediaTypes = imageTypes; + break; + + case VIDEO: + self.galleryPickerController.mediaTypes = videoTypes; + break; + + default: + self.galleryPickerController.mediaTypes = [videoTypes arrayByAddingObjectsFromArray:imageTypes]; + break; + } + [self.viewController presentViewController:self.galleryPickerController animated:YES completion:nil]; } -- (void) resolveMultiPickFromGallery:(BOOL)withVideo { +- (void) resolveMultiPickFromGallery:(MediaType)type { DKImagePickerController * dkImagePickerController = [[DKImagePickerController alloc] init]; // Create alert dialog for asset caching @@ -150,7 +146,7 @@ dkImagePickerController.exportsWhenCompleted = YES; dkImagePickerController.showsCancelButton = YES; dkImagePickerController.sourceType = DKImagePickerControllerSourceTypePhoto; - dkImagePickerController.assetType = withVideo ? DKImagePickerControllerAssetTypeAllVideos : DKImagePickerControllerAssetTypeAllPhotos; + dkImagePickerController.assetType = type == VIDEO ? DKImagePickerControllerAssetTypeAllVideos : type == IMAGE ? DKImagePickerControllerAssetTypeAllPhotos : DKImagePickerControllerAssetTypeAllAssets; // Export status changed [dkImagePickerController setExportStatusChanged:^(enum DKImagePickerControllerExportStatus status) { diff --git a/ios/Classes/FileUtils.h b/ios/Classes/FileUtils.h index 990a8d1..4ad476a 100644 --- a/ios/Classes/FileUtils.h +++ b/ios/Classes/FileUtils.h @@ -13,8 +13,15 @@ #define Log(fmt, ...) #endif +typedef NS_ENUM(NSInteger, MediaType) { + VIDEO, + IMAGE, + MEDIA +}; + @interface FileUtils : NSObject + (NSArray*) resolveType:(NSString*)type withAllowedExtensions:(NSArray*)allowedExtensions; ++ (MediaType) resolveMediaType:(NSString*)type; + (NSArray*) resolvePath:(NSArray *)urls; @end diff --git a/ios/Classes/FileUtils.m b/ios/Classes/FileUtils.m index 03e32c0..42bd9c7 100644 --- a/ios/Classes/FileUtils.m +++ b/ios/Classes/FileUtils.m @@ -11,15 +11,17 @@ + (NSArray *) resolveType:(NSString*)type withAllowedExtensions:(NSArray*) allowedExtensions { - if ([type isEqualToString:@"ANY"]) { + if ([type isEqualToString:@"any"]) { return @[@"public.item"]; - } else if ([type isEqualToString:@"IMAGE"]) { + } else if ([type isEqualToString:@"image"]) { return @[@"public.image"]; - } else if ([type isEqualToString:@"VIDEO"]) { + } else if ([type isEqualToString:@"video"]) { return @[@"public.movie"]; - } else if ([type isEqualToString:@"AUDIO"]) { + } else if ([type isEqualToString:@"audio"]) { return @[@"public.audio"]; - } else if ([type isEqualToString:@"CUSTOM"]) { + } else if ([type isEqualToString:@"media"]) { + return @[@"public.image", @"public.video"]; + } else if ([type isEqualToString:@"custom"]) { if(allowedExtensions == (id)[NSNull null] || allowedExtensions.count == 0) { return nil; } @@ -45,6 +47,16 @@ } } ++ (MediaType) resolveMediaType:(NSString *)type { + if([type isEqualToString:@"video"]) { + return VIDEO; + } else if([type isEqualToString:@"image"]) { + return IMAGE; + } else { + return MEDIA; + } +} + + (NSMutableArray*) resolvePath:(NSArray *)urls{ NSString * uri; NSMutableArray * paths = [[NSMutableArray alloc] init]; diff --git a/lib/file_picker.dart b/lib/file_picker.dart index dece917..61689eb 100644 --- a/lib/file_picker.dart +++ b/lib/file_picker.dart @@ -1,10 +1,12 @@ import 'dart:async'; import 'dart:io'; +import 'package:flutter/foundation.dart'; import 'package:flutter/services.dart'; enum FileType { any, + media, image, video, audio, @@ -26,7 +28,7 @@ class FilePicker { static Future> getMultiFilePath( {FileType type = FileType.any, List allowedExtensions}) async => - await _getPath(_handleType(type), true, allowedExtensions); + await _getPath(describeEnum(type), true, allowedExtensions); /// Returns an absolute file path from the calling platform. /// @@ -36,7 +38,7 @@ class FilePicker { static Future getFilePath( {FileType type = FileType.any, List allowedExtensions}) async => - await _getPath(_handleType(type), false, allowedExtensions); + await _getPath(describeEnum(type), false, allowedExtensions); /// Returns a `File` object from the selected file path. /// @@ -45,7 +47,7 @@ class FilePicker { static Future getFile( {FileType type = FileType.any, List allowedExtensions}) async { final String filePath = - await _getPath(_handleType(type), false, allowedExtensions); + await _getPath(describeEnum(type), false, allowedExtensions); return filePath != null ? File(filePath) : null; } @@ -56,7 +58,7 @@ class FilePicker { static Future> getMultiFile( {FileType type = FileType.any, List allowedExtensions}) async { final Map paths = - await _getPath(_handleType(type), true, allowedExtensions); + await _getPath(describeEnum(type), true, allowedExtensions); return paths != null && paths.isNotEmpty ? paths.values.map((path) => File(path)).toList() : null; @@ -90,21 +92,4 @@ class FilePicker { rethrow; } } - - static String _handleType(FileType type) { - switch (type) { - case FileType.image: - return 'IMAGE'; - case FileType.audio: - return 'AUDIO'; - case FileType.video: - return 'VIDEO'; - case FileType.any: - return 'ANY'; - case FileType.custom: - return 'CUSTOM'; - default: - return 'ANY'; - } - } } diff --git a/pubspec.yaml b/pubspec.yaml index 4e64e72..dcb65cd 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -1,7 +1,7 @@ name: file_picker description: A package that allows you to use a native file explorer to pick single or multiple absolute file paths, with extension filtering support. homepage: https://github.com/miguelpruivo/plugins_flutter_file_picker -version: 1.7.1 +version: 1.8.0 dependencies: flutter: