Adds FileType.media for picking both images & video at same time

This commit is contained in:
Miguel Ruivo 2020-04-27 22:25:57 +01:00
parent 6afd2aa1a8
commit 4b1c047581
15 changed files with 152 additions and 128 deletions

View File

@ -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 ## 1.7.1
Updates iOS multi gallery picker dependency and adds a modal loading while fetching exporting assets. Updates iOS multi gallery picker dependency and adds a modal loading while fetching exporting assets.

View File

@ -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 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 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 **multiple files** optionally, supplying file extensions
* Load path from **gallery** * Load path from **media** (video & image only)
* Load path from **audio** * Load path from **audio** only
* Load path from **video** * Load path from **image** only
* Load path from **video** only
* Load path from **any** * Load path from **any**
* Create a `File` or `List<File>` objects from **any** selected file(s) * Create a `File` or `List<File>` objects from **any** selected file(s)
* Supports desktop through **go-flutter** (MacOS, Windows, Linux) * Supports desktop through **go-flutter** (MacOS, Windows, Linux)

View File

@ -123,10 +123,10 @@ public class FilePickerDelegate implements PluginRegistry.ActivityResultListener
@Override @Override
public boolean onRequestPermissionsResult(final int requestCode, final String[] permissions, final int[] grantResults) { public boolean onRequestPermissionsResult(final int requestCode, final String[] permissions, final int[] grantResults) {
if(REQUEST_CODE != requestCode) { if (REQUEST_CODE != requestCode) {
return false; return false;
} }
final boolean permissionGranted = final boolean permissionGranted =
grantResults.length > 0 && grantResults[0] == PackageManager.PERMISSION_GRANTED; 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); result.error("already_active", "File picker is already active", null);
} }
@SuppressWarnings("deprecation")
private void startFileExplorer() { private void startFileExplorer() {
final Intent intent; final Intent intent;
intent = new Intent(Intent.ACTION_GET_CONTENT); intent = new Intent(Intent.ACTION_GET_CONTENT);
final Uri uri = Uri.parse(Environment.getExternalStorageDirectory().getPath() + File.separator); final Uri uri = Uri.parse(Environment.getExternalStorageDirectory().getPath() + File.separator);
Log.d(TAG, "Type" + type);
intent.setDataAndType(uri, this.type); intent.setDataAndType(uri, this.type);
intent.setType(this.type); intent.setType(this.type);
intent.putExtra(Intent.EXTRA_ALLOW_MULTIPLE, this.isMultipleSelection); intent.putExtra(Intent.EXTRA_ALLOW_MULTIPLE, this.isMultipleSelection);
intent.addCategory(Intent.CATEGORY_OPENABLE); intent.addCategory(Intent.CATEGORY_OPENABLE);
if (type.contains(",")) {
allowedExtensions = type.split(",");
}
if (allowedExtensions != null) { if (allowedExtensions != null) {
intent.putExtra(Intent.EXTRA_MIME_TYPES, allowedExtensions); intent.putExtra(Intent.EXTRA_MIME_TYPES, allowedExtensions);
} }

View File

@ -153,7 +153,7 @@ public class FilePickerPlugin implements MethodChannel.MethodCallHandler, Flutte
if (fileType == null) { if (fileType == null) {
result.notImplemented(); 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); 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 { } else {
this.delegate.startFileExplorer(fileType, isMultipleSelection, allowedExtensions, result); this.delegate.startFileExplorer(fileType, isMultipleSelection, allowedExtensions, result);
@ -165,14 +165,16 @@ public class FilePickerPlugin implements MethodChannel.MethodCallHandler, Flutte
switch (type) { switch (type) {
case "AUDIO": case "audio":
return "audio/*"; return "audio/*";
case "IMAGE": case "image":
return "image/*"; return "image/*";
case "VIDEO": case "video":
return "video/*"; return "video/*";
case "ANY": case "media":
case "CUSTOM": return "image/*,video/*";
case "any":
case "custom":
return "*/*"; return "*/*";
default: default:
return null; return null;

View File

@ -1,5 +1,5 @@
# Uncomment this line to define a global platform for your project # 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. # CocoaPods analytics sends network stats synchronously affecting flutter build latency.
ENV['COCOAPODS_DISABLE_STATS'] = 'true' ENV['COCOAPODS_DISABLE_STATS'] = 'true'

View File

@ -9,12 +9,12 @@
/* Begin PBXBuildFile section */ /* Begin PBXBuildFile section */
1498D2341E8E89220040F4C2 /* GeneratedPluginRegistrant.m in Sources */ = {isa = PBXBuildFile; fileRef = 1498D2331E8E89220040F4C2 /* GeneratedPluginRegistrant.m */; }; 1498D2341E8E89220040F4C2 /* GeneratedPluginRegistrant.m in Sources */ = {isa = PBXBuildFile; fileRef = 1498D2331E8E89220040F4C2 /* GeneratedPluginRegistrant.m */; };
3B3967161E833CAA004F5970 /* AppFrameworkInfo.plist in Resources */ = {isa = PBXBuildFile; fileRef = 3B3967151E833CAA004F5970 /* AppFrameworkInfo.plist */; }; 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 */; }; 978B8F6F1D3862AE00F588F7 /* AppDelegate.m in Sources */ = {isa = PBXBuildFile; fileRef = 7AFFD8EE1D35381100E5BB4D /* AppDelegate.m */; };
97C146F31CF9000F007C117D /* main.m in Sources */ = {isa = PBXBuildFile; fileRef = 97C146F21CF9000F007C117D /* main.m */; }; 97C146F31CF9000F007C117D /* main.m in Sources */ = {isa = PBXBuildFile; fileRef = 97C146F21CF9000F007C117D /* main.m */; };
97C146FC1CF9000F007C117D /* Main.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 97C146FA1CF9000F007C117D /* Main.storyboard */; }; 97C146FC1CF9000F007C117D /* Main.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 97C146FA1CF9000F007C117D /* Main.storyboard */; };
97C146FE1CF9000F007C117D /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 97C146FD1CF9000F007C117D /* Assets.xcassets */; }; 97C146FE1CF9000F007C117D /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 97C146FD1CF9000F007C117D /* Assets.xcassets */; };
97C147011CF9000F007C117D /* LaunchScreen.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 97C146FF1CF9000F007C117D /* LaunchScreen.storyboard */; }; 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 */ /* End PBXBuildFile section */
/* Begin PBXCopyFilesBuildPhase section */ /* Begin PBXCopyFilesBuildPhase section */
@ -31,14 +31,16 @@
/* End PBXCopyFilesBuildPhase section */ /* End PBXCopyFilesBuildPhase section */
/* Begin PBXFileReference 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 = "<group>"; };
1498D2321E8E86230040F4C2 /* GeneratedPluginRegistrant.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = GeneratedPluginRegistrant.h; sourceTree = "<group>"; }; 1498D2321E8E86230040F4C2 /* GeneratedPluginRegistrant.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = GeneratedPluginRegistrant.h; sourceTree = "<group>"; };
1498D2331E8E89220040F4C2 /* GeneratedPluginRegistrant.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = GeneratedPluginRegistrant.m; sourceTree = "<group>"; }; 1498D2331E8E89220040F4C2 /* GeneratedPluginRegistrant.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = GeneratedPluginRegistrant.m; sourceTree = "<group>"; };
3B3967151E833CAA004F5970 /* AppFrameworkInfo.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; name = AppFrameworkInfo.plist; path = Flutter/AppFrameworkInfo.plist; sourceTree = "<group>"; }; 3B3967151E833CAA004F5970 /* AppFrameworkInfo.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; name = AppFrameworkInfo.plist; path = Flutter/AppFrameworkInfo.plist; sourceTree = "<group>"; };
3B80C3931E831B6300D905FE /* App.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = App.framework; path = Flutter/App.framework; sourceTree = "<group>"; }; 3B80C3931E831B6300D905FE /* App.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = App.framework; path = Flutter/App.framework; sourceTree = "<group>"; };
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 = "<group>"; };
7AFA3C8E1D35360C0083082E /* Release.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; name = Release.xcconfig; path = Flutter/Release.xcconfig; sourceTree = "<group>"; }; 7AFA3C8E1D35360C0083082E /* Release.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; name = Release.xcconfig; path = Flutter/Release.xcconfig; sourceTree = "<group>"; };
7AFFD8ED1D35381100E5BB4D /* AppDelegate.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = AppDelegate.h; sourceTree = "<group>"; }; 7AFFD8ED1D35381100E5BB4D /* AppDelegate.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = AppDelegate.h; sourceTree = "<group>"; };
7AFFD8EE1D35381100E5BB4D /* AppDelegate.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = AppDelegate.m; sourceTree = "<group>"; }; 7AFFD8EE1D35381100E5BB4D /* AppDelegate.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = AppDelegate.m; sourceTree = "<group>"; };
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 = "<group>"; };
9740EEB21CF90195004384FC /* Debug.xcconfig */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.xcconfig; name = Debug.xcconfig; path = Flutter/Debug.xcconfig; sourceTree = "<group>"; }; 9740EEB21CF90195004384FC /* Debug.xcconfig */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.xcconfig; name = Debug.xcconfig; path = Flutter/Debug.xcconfig; sourceTree = "<group>"; };
9740EEB31CF90195004384FC /* Generated.xcconfig */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.xcconfig; name = Generated.xcconfig; path = Flutter/Generated.xcconfig; sourceTree = "<group>"; }; 9740EEB31CF90195004384FC /* Generated.xcconfig */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.xcconfig; name = Generated.xcconfig; path = Flutter/Generated.xcconfig; sourceTree = "<group>"; };
9740EEBA1CF902C7004384FC /* Flutter.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Flutter.framework; path = Flutter/Flutter.framework; sourceTree = "<group>"; }; 9740EEBA1CF902C7004384FC /* Flutter.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Flutter.framework; path = Flutter/Flutter.framework; sourceTree = "<group>"; };
@ -48,8 +50,6 @@
97C146FD1CF9000F007C117D /* Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Assets.xcassets; sourceTree = "<group>"; }; 97C146FD1CF9000F007C117D /* Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Assets.xcassets; sourceTree = "<group>"; };
97C147001CF9000F007C117D /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/LaunchScreen.storyboard; sourceTree = "<group>"; }; 97C147001CF9000F007C117D /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/LaunchScreen.storyboard; sourceTree = "<group>"; };
97C147021CF9000F007C117D /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = "<group>"; }; 97C147021CF9000F007C117D /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = "<group>"; };
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 = "<group>"; };
E093F13416E116B41F70DC9A /* Pods_Runner.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Pods_Runner.framework; sourceTree = BUILT_PRODUCTS_DIR; };
/* End PBXFileReference section */ /* End PBXFileReference section */
/* Begin PBXFrameworksBuildPhase section */ /* Begin PBXFrameworksBuildPhase section */
@ -57,7 +57,7 @@
isa = PBXFrameworksBuildPhase; isa = PBXFrameworksBuildPhase;
buildActionMask = 2147483647; buildActionMask = 2147483647;
files = ( files = (
F4241881D42A79991D987032 /* Pods_Runner.framework in Frameworks */, 78EB448BD5060711D7E3FCEC /* Pods_Runner.framework in Frameworks */,
); );
runOnlyForDeploymentPostprocessing = 0; runOnlyForDeploymentPostprocessing = 0;
}; };
@ -84,7 +84,7 @@
97C146F01CF9000F007C117D /* Runner */, 97C146F01CF9000F007C117D /* Runner */,
97C146EF1CF9000F007C117D /* Products */, 97C146EF1CF9000F007C117D /* Products */,
E62393F6B8A7F2BF56A0B62D /* Pods */, E62393F6B8A7F2BF56A0B62D /* Pods */,
EF8FB2B5878597859ACDA5F4 /* Frameworks */, D2A1DF9F69FF1E54F4223294 /* Frameworks */,
); );
sourceTree = "<group>"; sourceTree = "<group>";
}; };
@ -120,23 +120,23 @@
name = "Supporting Files"; name = "Supporting Files";
sourceTree = "<group>"; sourceTree = "<group>";
}; };
D2A1DF9F69FF1E54F4223294 /* Frameworks */ = {
isa = PBXGroup;
children = (
4FE42FA345519DC2CF8F7CAB /* Pods_Runner.framework */,
);
name = Frameworks;
sourceTree = "<group>";
};
E62393F6B8A7F2BF56A0B62D /* Pods */ = { E62393F6B8A7F2BF56A0B62D /* Pods */ = {
isa = PBXGroup; isa = PBXGroup;
children = ( children = (
A20269E5E72E5C7764E96D49 /* Pods-Runner.debug.xcconfig */, 620D3249E16C66CF31F39A1D /* Pods-Runner.debug.xcconfig */,
92150FFEDED79AD7268B2247 /* Pods-Runner.release.xcconfig */, 12526927AA724E8A8C5BA965 /* Pods-Runner.release.xcconfig */,
); );
path = Pods; path = Pods;
sourceTree = "<group>"; sourceTree = "<group>";
}; };
EF8FB2B5878597859ACDA5F4 /* Frameworks */ = {
isa = PBXGroup;
children = (
E093F13416E116B41F70DC9A /* Pods_Runner.framework */,
);
name = Frameworks;
sourceTree = "<group>";
};
/* End PBXGroup section */ /* End PBXGroup section */
/* Begin PBXNativeTarget section */ /* Begin PBXNativeTarget section */
@ -144,14 +144,14 @@
isa = PBXNativeTarget; isa = PBXNativeTarget;
buildConfigurationList = 97C147051CF9000F007C117D /* Build configuration list for PBXNativeTarget "Runner" */; buildConfigurationList = 97C147051CF9000F007C117D /* Build configuration list for PBXNativeTarget "Runner" */;
buildPhases = ( buildPhases = (
A43F367F477195F57487AEAA /* [CP] Check Pods Manifest.lock */, FC67C2E2F2E4233AAAFA3380 /* [CP] Check Pods Manifest.lock */,
9740EEB61CF901F6004384FC /* Run Script */, 9740EEB61CF901F6004384FC /* Run Script */,
97C146EA1CF9000F007C117D /* Sources */, 97C146EA1CF9000F007C117D /* Sources */,
97C146EB1CF9000F007C117D /* Frameworks */, 97C146EB1CF9000F007C117D /* Frameworks */,
97C146EC1CF9000F007C117D /* Resources */, 97C146EC1CF9000F007C117D /* Resources */,
9705A1C41CF9048500538489 /* Embed Frameworks */, 9705A1C41CF9048500538489 /* Embed Frameworks */,
3B06AD1E1E4923F5004D2608 /* Thin Binary */, 3B06AD1E1E4923F5004D2608 /* Thin Binary */,
AE010F81F563ADC683AAAEBC /* [CP] Embed Pods Frameworks */, D4399F71B49163E30FC870D5 /* [CP] Embed Pods Frameworks */,
); );
buildRules = ( buildRules = (
); );
@ -240,29 +240,7 @@
shellPath = /bin/sh; shellPath = /bin/sh;
shellScript = "/bin/sh \"$FLUTTER_ROOT/packages/flutter_tools/bin/xcode_backend.sh\" build"; shellScript = "/bin/sh \"$FLUTTER_ROOT/packages/flutter_tools/bin/xcode_backend.sh\" build";
}; };
A43F367F477195F57487AEAA /* [CP] Check Pods Manifest.lock */ = { D4399F71B49163E30FC870D5 /* [CP] Embed Pods Frameworks */ = {
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 */ = {
isa = PBXShellScriptBuildPhase; isa = PBXShellScriptBuildPhase;
buildActionMask = 2147483647; buildActionMask = 2147483647;
files = ( files = (
@ -298,6 +276,28 @@
shellScript = "\"${PODS_ROOT}/Target Support Files/Pods-Runner/Pods-Runner-frameworks.sh\"\n"; shellScript = "\"${PODS_ROOT}/Target Support Files/Pods-Runner/Pods-Runner-frameworks.sh\"\n";
showEnvVarsInLog = 0; 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 */ /* End PBXShellScriptBuildPhase section */
/* Begin PBXSourcesBuildPhase section */ /* Begin PBXSourcesBuildPhase section */

View File

@ -86,6 +86,10 @@ class _FilePickerDemoState extends State<FilePickerDemo> {
child: new Text('FROM VIDEO'), child: new Text('FROM VIDEO'),
value: FileType.video, value: FileType.video,
), ),
new DropdownMenuItem(
child: new Text('FROM MEDIA'),
value: FileType.media,
),
new DropdownMenuItem( new DropdownMenuItem(
child: new Text('FROM ANY'), child: new Text('FROM ANY'),
value: FileType.any, value: FileType.any,

View File

@ -11,27 +11,32 @@ import (
func fileFilter(method string, extensions []string, size int, multi bool) (string, error) { func fileFilter(method string, extensions []string, size int, multi bool) (string, error) {
switch method { switch method {
case "ANY": case "any":
if multi { if multi {
return "*", nil return "*", nil
} }
return `"public.item"`, nil return `"public.item"`, nil
case "IMAGE": case "image":
if multi { if multi {
return "jpg, jpeg, bmp, gif, png", nil return "jpg, jpeg, bmp, gif, png", nil
} }
return `"public.image"`, nil return `"public.image"`, nil
case "AUDIO": case "audio":
if multi { if multi {
return "mp3, wav, midi, ogg, aac", nil return "mp3, wav, midi, ogg, aac", nil
} }
return `"public.audio"`, nil return `"public.audio"`, nil
case "VIDEO": case "video":
if multi { if multi {
return "webm, mpeg, mkv, mp4, avi, mov, flv", nil return "webm, mpeg, mkv, mp4, avi, mov, flv", nil
} }
return `"public.movie"`, 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 i int
var filters = "" var filters = ""
for i = 0; i < size; i++ { for i = 0; i < size; i++ {

View File

@ -7,15 +7,17 @@ import (
func fileFilter(method string, extensions []string, size int, isMulti bool) (string, error) { func fileFilter(method string, extensions []string, size int, isMulti bool) (string, error) {
switch method { switch method {
case "ANY": case "any":
return `*.*`, nil return `*.*`, nil
case "IMAGE": case "image":
return `*.png *.jpg *.jpeg`, nil return `*.png *.jpg *.jpeg`, nil
case "AUDIO": case "audio":
return `*.mp3 *.wav *.midi *.ogg *.aac`, nil return `*.mp3 *.wav *.midi *.ogg *.aac`, nil
case "VIDEO": case "video":
return `*.webm *.mpeg *.mkv *.mp4 *.avi *.mov *.flv`, nil 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 i int
var filters = "" var filters = ""
for i = 0; i < size; i++ { for i = 0; i < size; i++ {

View File

@ -7,19 +7,21 @@ import (
func fileFilter(method string, extensions []string, size int, isMulti bool) (string, error) { func fileFilter(method string, extensions []string, size int, isMulti bool) (string, error) {
switch method { switch method {
case "ANY": case "any":
return "*", nil return "*", nil
case "IMAGE": case "image":
return "Images (*.jpeg,*.png,*.gif)\x00*.jpg;*.jpeg;*.png;*.gif\x00All Files (*.*)\x00*.*\x00\x00", nil 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 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 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 i int
var filters = "Files (" var filters = "Files ("
for i = 0 ; i<size ; i++ { for i = 0; i < size; i++ {
filters += `*.` + extensions[i] + `,` filters += `*.` + extensions[i] + `,`
} }
filters += ")" filters += ")"
return filters, nil return filters, nil

View File

@ -49,7 +49,7 @@
_result = result; _result = result;
NSDictionary * arguments = call.arguments; NSDictionary * arguments = call.arguments;
BOOL isMultiplePick = ((NSNumber*)[arguments valueForKey:@"allowMultipleSelection"]).boolValue; BOOL isMultiplePick = ((NSNumber*)[arguments valueForKey:@"allowMultipleSelection"]).boolValue;
if([call.method isEqualToString:@"ANY"] || [call.method containsString:@"CUSTOM"]) { if([call.method isEqualToString:@"any"] || [call.method containsString:@"custom"]) {
self.allowedExtensions = [FileUtils resolveType:call.method withAllowedExtensions: [arguments valueForKey:@"allowedExtensions"]]; self.allowedExtensions = [FileUtils resolveType:call.method withAllowedExtensions: [arguments valueForKey:@"allowedExtensions"]];
if(self.allowedExtensions == nil) { if(self.allowedExtensions == nil) {
_result([FlutterError errorWithCode:@"Unsupported file extension" _result([FlutterError errorWithCode:@"Unsupported file extension"
@ -59,12 +59,10 @@
} else if(self.allowedExtensions != nil) { } else if(self.allowedExtensions != nil) {
[self resolvePickDocumentWithMultipleSelection:isMultiplePick]; [self resolvePickDocumentWithMultipleSelection:isMultiplePick];
} }
} else if([call.method isEqualToString:@"VIDEO"]) { } else if([call.method isEqualToString:@"video"] || [call.method isEqualToString:@"image"] || [call.method isEqualToString:@"media"]) {
[self resolvePickVideo:isMultiplePick]; [self resolvePickMedia:[FileUtils resolveMediaType:call.method] withMultiPick:isMultiplePick];
} else if([call.method isEqualToString:@"AUDIO"]) { } else if([call.method isEqualToString:@"audio"]) {
[self resolvePickAudio]; [self resolvePickAudio];
} else if([call.method isEqualToString:@"IMAGE"]) {
[self resolvePickImage:isMultiplePick];
} else { } else {
result(FlutterMethodNotImplemented); result(FlutterMethodNotImplemented);
_result = nil; _result = nil;
@ -99,41 +97,39 @@
[_viewController presentViewController:self.documentPickerController animated:YES completion:nil]; [_viewController presentViewController:self.documentPickerController animated:YES completion:nil];
} }
- (void) resolvePickMedia:(MediaType)type withMultiPick:(BOOL)multiPick {
- (void) resolvePickImage:(BOOL)withMultiPick {
if(withMultiPick){ if(multiPick) {
[self resolveMultiPickFromGallery:NO]; [self resolveMultiPickFromGallery:type];
return; return;
} }
NSArray<NSString*> * videoTypes = @[(NSString*)kUTTypeMovie, (NSString*)kUTTypeAVIMovie, (NSString*)kUTTypeVideo, (NSString*)kUTTypeMPEG4];
NSArray<NSString*> * imageTypes = @[(NSString *)kUTTypeImage];
self.galleryPickerController = [[UIImagePickerController alloc] init]; self.galleryPickerController = [[UIImagePickerController alloc] init];
self.galleryPickerController.delegate = self; self.galleryPickerController.delegate = self;
self.galleryPickerController.modalPresentationStyle = UIModalPresentationCurrentContext; 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; 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]; [self.viewController presentViewController:self.galleryPickerController animated:YES completion:nil];
} }
- (void) resolveMultiPickFromGallery:(BOOL)withVideo { - (void) resolveMultiPickFromGallery:(MediaType)type {
DKImagePickerController * dkImagePickerController = [[DKImagePickerController alloc] init]; DKImagePickerController * dkImagePickerController = [[DKImagePickerController alloc] init];
// Create alert dialog for asset caching // Create alert dialog for asset caching
@ -150,7 +146,7 @@
dkImagePickerController.exportsWhenCompleted = YES; dkImagePickerController.exportsWhenCompleted = YES;
dkImagePickerController.showsCancelButton = YES; dkImagePickerController.showsCancelButton = YES;
dkImagePickerController.sourceType = DKImagePickerControllerSourceTypePhoto; dkImagePickerController.sourceType = DKImagePickerControllerSourceTypePhoto;
dkImagePickerController.assetType = withVideo ? DKImagePickerControllerAssetTypeAllVideos : DKImagePickerControllerAssetTypeAllPhotos; dkImagePickerController.assetType = type == VIDEO ? DKImagePickerControllerAssetTypeAllVideos : type == IMAGE ? DKImagePickerControllerAssetTypeAllPhotos : DKImagePickerControllerAssetTypeAllAssets;
// Export status changed // Export status changed
[dkImagePickerController setExportStatusChanged:^(enum DKImagePickerControllerExportStatus status) { [dkImagePickerController setExportStatusChanged:^(enum DKImagePickerControllerExportStatus status) {

View File

@ -13,8 +13,15 @@
#define Log(fmt, ...) #define Log(fmt, ...)
#endif #endif
typedef NS_ENUM(NSInteger, MediaType) {
VIDEO,
IMAGE,
MEDIA
};
@interface FileUtils : NSObject @interface FileUtils : NSObject
+ (NSArray<NSString*>*) resolveType:(NSString*)type withAllowedExtensions:(NSArray<NSString*>*)allowedExtensions; + (NSArray<NSString*>*) resolveType:(NSString*)type withAllowedExtensions:(NSArray<NSString*>*)allowedExtensions;
+ (MediaType) resolveMediaType:(NSString*)type;
+ (NSArray*) resolvePath:(NSArray<NSURL *> *)urls; + (NSArray*) resolvePath:(NSArray<NSURL *> *)urls;
@end @end

View File

@ -11,15 +11,17 @@
+ (NSArray<NSString*> *) resolveType:(NSString*)type withAllowedExtensions:(NSArray<NSString*>*) allowedExtensions { + (NSArray<NSString*> *) resolveType:(NSString*)type withAllowedExtensions:(NSArray<NSString*>*) allowedExtensions {
if ([type isEqualToString:@"ANY"]) { if ([type isEqualToString:@"any"]) {
return @[@"public.item"]; return @[@"public.item"];
} else if ([type isEqualToString:@"IMAGE"]) { } else if ([type isEqualToString:@"image"]) {
return @[@"public.image"]; return @[@"public.image"];
} else if ([type isEqualToString:@"VIDEO"]) { } else if ([type isEqualToString:@"video"]) {
return @[@"public.movie"]; return @[@"public.movie"];
} else if ([type isEqualToString:@"AUDIO"]) { } else if ([type isEqualToString:@"audio"]) {
return @[@"public.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) { if(allowedExtensions == (id)[NSNull null] || allowedExtensions.count == 0) {
return nil; 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<NSURL *> *)urls{ + (NSMutableArray*) resolvePath:(NSArray<NSURL *> *)urls{
NSString * uri; NSString * uri;
NSMutableArray * paths = [[NSMutableArray alloc] init]; NSMutableArray * paths = [[NSMutableArray alloc] init];

View File

@ -1,10 +1,12 @@
import 'dart:async'; import 'dart:async';
import 'dart:io'; import 'dart:io';
import 'package:flutter/foundation.dart';
import 'package:flutter/services.dart'; import 'package:flutter/services.dart';
enum FileType { enum FileType {
any, any,
media,
image, image,
video, video,
audio, audio,
@ -26,7 +28,7 @@ class FilePicker {
static Future<Map<String, String>> getMultiFilePath( static Future<Map<String, String>> getMultiFilePath(
{FileType type = FileType.any, {FileType type = FileType.any,
List<String> allowedExtensions}) async => List<String> allowedExtensions}) async =>
await _getPath(_handleType(type), true, allowedExtensions); await _getPath(describeEnum(type), true, allowedExtensions);
/// Returns an absolute file path from the calling platform. /// Returns an absolute file path from the calling platform.
/// ///
@ -36,7 +38,7 @@ class FilePicker {
static Future<String> getFilePath( static Future<String> getFilePath(
{FileType type = FileType.any, {FileType type = FileType.any,
List<String> allowedExtensions}) async => List<String> allowedExtensions}) async =>
await _getPath(_handleType(type), false, allowedExtensions); await _getPath(describeEnum(type), false, allowedExtensions);
/// Returns a `File` object from the selected file path. /// Returns a `File` object from the selected file path.
/// ///
@ -45,7 +47,7 @@ class FilePicker {
static Future<File> getFile( static Future<File> getFile(
{FileType type = FileType.any, List<String> allowedExtensions}) async { {FileType type = FileType.any, List<String> allowedExtensions}) async {
final String filePath = final String filePath =
await _getPath(_handleType(type), false, allowedExtensions); await _getPath(describeEnum(type), false, allowedExtensions);
return filePath != null ? File(filePath) : null; return filePath != null ? File(filePath) : null;
} }
@ -56,7 +58,7 @@ class FilePicker {
static Future<List<File>> getMultiFile( static Future<List<File>> getMultiFile(
{FileType type = FileType.any, List<String> allowedExtensions}) async { {FileType type = FileType.any, List<String> allowedExtensions}) async {
final Map<String, String> paths = final Map<String, String> paths =
await _getPath(_handleType(type), true, allowedExtensions); await _getPath(describeEnum(type), true, allowedExtensions);
return paths != null && paths.isNotEmpty return paths != null && paths.isNotEmpty
? paths.values.map((path) => File(path)).toList() ? paths.values.map((path) => File(path)).toList()
: null; : null;
@ -90,21 +92,4 @@ class FilePicker {
rethrow; 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';
}
}
} }

View File

@ -1,7 +1,7 @@
name: file_picker 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. 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 homepage: https://github.com/miguelpruivo/plugins_flutter_file_picker
version: 1.7.1 version: 1.8.0
dependencies: dependencies:
flutter: flutter: