Adds FileType.media for picking both images & video at same time
This commit is contained in:
parent
6afd2aa1a8
commit
4b1c047581
|
@ -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.
|
||||
|
||||
|
|
|
@ -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<File>` objects from **any** selected file(s)
|
||||
* Supports desktop through **go-flutter** (MacOS, Windows, Linux)
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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'
|
||||
|
|
|
@ -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 = "<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>"; };
|
||||
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>"; };
|
||||
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>"; };
|
||||
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>"; };
|
||||
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>"; };
|
||||
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>"; };
|
||||
|
@ -48,8 +50,6 @@
|
|||
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>"; };
|
||||
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 */
|
||||
|
||||
/* 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 = "<group>";
|
||||
};
|
||||
|
@ -120,23 +120,23 @@
|
|||
name = "Supporting Files";
|
||||
sourceTree = "<group>";
|
||||
};
|
||||
D2A1DF9F69FF1E54F4223294 /* Frameworks */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
4FE42FA345519DC2CF8F7CAB /* Pods_Runner.framework */,
|
||||
);
|
||||
name = Frameworks;
|
||||
sourceTree = "<group>";
|
||||
};
|
||||
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 = "<group>";
|
||||
};
|
||||
EF8FB2B5878597859ACDA5F4 /* Frameworks */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
E093F13416E116B41F70DC9A /* Pods_Runner.framework */,
|
||||
);
|
||||
name = Frameworks;
|
||||
sourceTree = "<group>";
|
||||
};
|
||||
/* 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 */
|
||||
|
|
|
@ -86,6 +86,10 @@ class _FilePickerDemoState extends State<FilePickerDemo> {
|
|||
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,
|
||||
|
|
|
@ -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++ {
|
||||
|
|
|
@ -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++ {
|
||||
|
|
|
@ -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<size ; i++ {
|
||||
filters += `*.` + extensions[i] + `,`
|
||||
for i = 0; i < size; i++ {
|
||||
filters += `*.` + extensions[i] + `,`
|
||||
}
|
||||
filters += ")"
|
||||
return filters, nil
|
||||
|
|
|
@ -49,7 +49,7 @@
|
|||
_result = result;
|
||||
NSDictionary * arguments = call.arguments;
|
||||
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"]];
|
||||
if(self.allowedExtensions == nil) {
|
||||
_result([FlutterError errorWithCode:@"Unsupported file extension"
|
||||
|
@ -59,12 +59,10 @@
|
|||
} else if(self.allowedExtensions != nil) {
|
||||
[self resolvePickDocumentWithMultipleSelection:isMultiplePick];
|
||||
}
|
||||
} else if([call.method isEqualToString:@"VIDEO"]) {
|
||||
[self resolvePickVideo:isMultiplePick];
|
||||
} else if([call.method isEqualToString:@"AUDIO"]) {
|
||||
} else if([call.method isEqualToString:@"video"] || [call.method isEqualToString:@"image"] || [call.method isEqualToString:@"media"]) {
|
||||
[self resolvePickMedia:[FileUtils resolveMediaType:call.method] withMultiPick:isMultiplePick];
|
||||
} else if([call.method isEqualToString:@"audio"]) {
|
||||
[self resolvePickAudio];
|
||||
} else if([call.method isEqualToString:@"IMAGE"]) {
|
||||
[self resolvePickImage:isMultiplePick];
|
||||
} else {
|
||||
result(FlutterMethodNotImplemented);
|
||||
_result = nil;
|
||||
|
@ -99,41 +97,39 @@
|
|||
[_viewController presentViewController:self.documentPickerController animated:YES completion:nil];
|
||||
}
|
||||
|
||||
|
||||
- (void) resolvePickImage:(BOOL)withMultiPick {
|
||||
- (void) resolvePickMedia:(MediaType)type withMultiPick:(BOOL)multiPick {
|
||||
|
||||
if(withMultiPick){
|
||||
[self resolveMultiPickFromGallery:NO];
|
||||
if(multiPick) {
|
||||
[self resolveMultiPickFromGallery:type];
|
||||
return;
|
||||
}
|
||||
|
||||
NSArray<NSString*> * videoTypes = @[(NSString*)kUTTypeMovie, (NSString*)kUTTypeAVIMovie, (NSString*)kUTTypeVideo, (NSString*)kUTTypeMPEG4];
|
||||
NSArray<NSString*> * 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) {
|
||||
|
|
|
@ -13,8 +13,15 @@
|
|||
#define Log(fmt, ...)
|
||||
#endif
|
||||
|
||||
typedef NS_ENUM(NSInteger, MediaType) {
|
||||
VIDEO,
|
||||
IMAGE,
|
||||
MEDIA
|
||||
};
|
||||
|
||||
@interface FileUtils : NSObject
|
||||
+ (NSArray<NSString*>*) resolveType:(NSString*)type withAllowedExtensions:(NSArray<NSString*>*)allowedExtensions;
|
||||
+ (MediaType) resolveMediaType:(NSString*)type;
|
||||
+ (NSArray*) resolvePath:(NSArray<NSURL *> *)urls;
|
||||
@end
|
||||
|
||||
|
|
|
@ -11,15 +11,17 @@
|
|||
|
||||
+ (NSArray<NSString*> *) resolveType:(NSString*)type withAllowedExtensions:(NSArray<NSString*>*) 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<NSURL *> *)urls{
|
||||
NSString * uri;
|
||||
NSMutableArray * paths = [[NSMutableArray alloc] init];
|
||||
|
|
|
@ -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<Map<String, String>> getMultiFilePath(
|
||||
{FileType type = FileType.any,
|
||||
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.
|
||||
///
|
||||
|
@ -36,7 +38,7 @@ class FilePicker {
|
|||
static Future<String> getFilePath(
|
||||
{FileType type = FileType.any,
|
||||
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.
|
||||
///
|
||||
|
@ -45,7 +47,7 @@ class FilePicker {
|
|||
static Future<File> getFile(
|
||||
{FileType type = FileType.any, List<String> 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<List<File>> getMultiFile(
|
||||
{FileType type = FileType.any, List<String> allowedExtensions}) async {
|
||||
final Map<String, String> 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';
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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:
|
||||
|
|
Loading…
Reference in New Issue