diff --git a/.vscode/settings.json b/.vscode/settings.json
new file mode 100644
index 0000000..0e14d8e
--- /dev/null
+++ b/.vscode/settings.json
@@ -0,0 +1,3 @@
+{
+ "java.configuration.updateBuildConfiguration": "disabled"
+}
\ No newline at end of file
diff --git a/CHANGELOG.md b/CHANGELOG.md
index 41cc7d8..9072f13 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -1,3 +1,22 @@
-## 0.0.1
+## 0.1.4
+* Changed Meta minimum version due to versioning conflict with flutter_localization.
-* TODO: Describe initial release.
+## 0.1.3
+
+* Updated readme.
+
+## 0.1.2
+
+* Changed license from Apache 2.0 to MIT.
+* Adds demo screenshot.
+
+## 0.1.1
+
+* Adds license information (Apache 2.0).
+* Adds CHANGELOG details.
+
+## 0.1.0
+
+* Initial realise.
+* Supports picking paths from files on local storage, cloud.
+* Supports picking paths from both gallery & camera due to [image_picker](https://pub.dartlang.org/packages/image_picker) dependency.
diff --git a/LICENSE b/LICENSE
index ba75c69..e8b4b28 100644
--- a/LICENSE
+++ b/LICENSE
@@ -1 +1,21 @@
-TODO: Add your license here.
+MIT License
+
+Copyright (c) 2018 Miguel Ruivo
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in all
+copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NON INFRINGEMENT. IN NO EVENT SHALL THE
+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+SOFTWARE.
\ No newline at end of file
diff --git a/README.md b/README.md
index 95161b6..14c9cbf 100644
--- a/README.md
+++ b/README.md
@@ -1,10 +1,85 @@
# file_picker
-A new flutter plugin project.
+File picker plugin alows you to use a native file explorer to load absolute file path from different types of files.
+
+## Installation
+
+First, add *file_picker* as a dependency in [your pubspec.yaml file](https://flutter.io/platform-plugins/).
+
+```
+file_picker: ^0.1.3
+```
+## Android
+Add `` to your app `AndroidManifest.xml` file.
+
+## iOS
+Since we are using *image_picker* as a dependency from this plugin to load paths from gallery and camera, we need the following keys to your _Info.plist_ file, located in `/ios/Runner/Info.plist`:
+
+* `NSPhotoLibraryUsageDescription` - describe why your app needs permission for the photo library. This is called _Privacy - Photo Library Usage Description_ in the visual editor.
+* `NSCameraUsageDescription` - describe why your app needs access to the camera. This is called _Privacy - Camera Usage Description_ in the visual editor.
+* `NSMicrophoneUsageDescription` - describe why your app needs access to the microphone, if you intend to record videos. This is called _Privacy - Microphone Usage Description_ in the visual editor.
+
+## To-do
+[X] Load paths from local files & cloud (GDrive, Dropbox, iCloud)
+[X] Load PDF file path
+[X] Load path from gallery
+[X] Load path from camera shot
+[ ] Load a custom format
+
+## Demo App
+
+![Demo](https://github.com/miguelpruivo/plugins_flutter_file_picker/blob/master/example/demo.png)
+
+## Example
+```
+import 'package:file_picker/file_picker.dart';
+
+class MyHomePage extends StatefulWidget {
+ @override
+ _MyHomePageState createState() => new _MyHomePageState();
+}
+
+class _MyHomePageState extends State {
+ String _filePath;
+
+ void getFilePath() async {
+ try {
+ String filePath = await FilePicker.getFilePath(type: FileType.PDF);
+ if (filePath == '') {
+ return;
+ }
+ print("File path: " + filePath);
+ setState((){this._filePath = filePath;});
+ } on PlatformException catch (e) {
+ print("Error while picking the file: " + e.toString());
+ }
+ }
+
+ @override
+ Widget build(BuildContext context) {
+ return new Scaffold(
+ appBar: new AppBar(
+ title: new Text('File Picker Example'),
+ ),
+ body: new Center(
+ child: _filePath == null
+ ? new Text('No file selected.')
+ : new Text('Path' + _filePath),
+ ),
+ floatingActionButton: new FloatingActionButton(
+ onPressed: getFilePath,
+ tooltip: 'Select file',
+ child: new Icon(Icons.sd_storage),
+ ),
+ );
+ }
+}
+
+```
## Getting Started
For help getting started with Flutter, view our online
[documentation](https://flutter.io/).
-For help on editing plugin code, view the [documentation](https://flutter.io/platform-plugins/#edit-code).
\ No newline at end of file
+For help on editing plugin code, view the [documentation](https://flutter.io/platform-plugins/#edit-code).
diff --git a/android/.settings/org.eclipse.buildship.core.prefs b/android/.settings/org.eclipse.buildship.core.prefs
index 6aa97a9..e889521 100644
--- a/android/.settings/org.eclipse.buildship.core.prefs
+++ b/android/.settings/org.eclipse.buildship.core.prefs
@@ -1,2 +1,2 @@
-connection.project.dir=../example/android
+connection.project.dir=
eclipse.preferences.version=1
diff --git a/example/demo.png b/example/demo.png
new file mode 100644
index 0000000..b2bf21c
Binary files /dev/null and b/example/demo.png differ
diff --git a/example/ios/Podfile.lock b/example/ios/Podfile.lock
new file mode 100644
index 0000000..652a159
--- /dev/null
+++ b/example/ios/Podfile.lock
@@ -0,0 +1,28 @@
+PODS:
+ - file_picker (0.0.1):
+ - Flutter
+ - Flutter (1.0.0)
+ - image_picker (0.0.1):
+ - Flutter
+
+DEPENDENCIES:
+ - file_picker (from `.symlinks/plugins/file_picker/ios`)
+ - Flutter (from `.symlinks/flutter/ios`)
+ - image_picker (from `.symlinks/plugins/image_picker/ios`)
+
+EXTERNAL SOURCES:
+ file_picker:
+ :path: ".symlinks/plugins/file_picker/ios"
+ Flutter:
+ :path: ".symlinks/flutter/ios"
+ image_picker:
+ :path: ".symlinks/plugins/image_picker/ios"
+
+SPEC CHECKSUMS:
+ file_picker: 78c3344d9b2c343bb3090c2f032b796242ebaea7
+ Flutter: 9d0fac939486c9aba2809b7982dfdbb47a7b0296
+ image_picker: ee00aab0487cedc80a304085219503cc6d0f2e22
+
+PODFILE CHECKSUM: 1e5af4103afd21ca5ead147d7b81d06f494f51a2
+
+COCOAPODS: 1.5.3
diff --git a/example/ios/Runner.xcodeproj/project.pbxproj b/example/ios/Runner.xcodeproj/project.pbxproj
index 1d98193..b694a11 100644
--- a/example/ios/Runner.xcodeproj/project.pbxproj
+++ b/example/ios/Runner.xcodeproj/project.pbxproj
@@ -12,6 +12,7 @@
3B3967161E833CAA004F5970 /* AppFrameworkInfo.plist in Resources */ = {isa = PBXBuildFile; fileRef = 3B3967151E833CAA004F5970 /* AppFrameworkInfo.plist */; };
3B80C3941E831B6300D905FE /* App.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 3B80C3931E831B6300D905FE /* App.framework */; };
3B80C3951E831B6300D905FE /* App.framework in Embed Frameworks */ = {isa = PBXBuildFile; fileRef = 3B80C3931E831B6300D905FE /* App.framework */; settings = {ATTRIBUTES = (CodeSignOnCopy, RemoveHeadersOnCopy, ); }; };
+ 94EE95F5D222CC3C902F7AA8 /* libPods-Runner.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 9E29C2B321AA1B6738D05DCC /* libPods-Runner.a */; };
9705A1C61CF904A100538489 /* Flutter.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 9740EEBA1CF902C7004384FC /* Flutter.framework */; };
9705A1C71CF904A300538489 /* Flutter.framework in Embed Frameworks */ = {isa = PBXBuildFile; fileRef = 9740EEBA1CF902C7004384FC /* Flutter.framework */; settings = {ATTRIBUTES = (CodeSignOnCopy, RemoveHeadersOnCopy, ); }; };
9740EEB41CF90195004384FC /* Debug.xcconfig in Resources */ = {isa = PBXBuildFile; fileRef = 9740EEB21CF90195004384FC /* Debug.xcconfig */; };
@@ -56,6 +57,7 @@
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 = ""; };
+ 9E29C2B321AA1B6738D05DCC /* libPods-Runner.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = "libPods-Runner.a"; sourceTree = BUILT_PRODUCTS_DIR; };
/* End PBXFileReference section */
/* Begin PBXFrameworksBuildPhase section */
@@ -65,6 +67,7 @@
files = (
9705A1C61CF904A100538489 /* Flutter.framework in Frameworks */,
3B80C3941E831B6300D905FE /* App.framework in Frameworks */,
+ 94EE95F5D222CC3C902F7AA8 /* libPods-Runner.a in Frameworks */,
);
runOnlyForDeploymentPostprocessing = 0;
};
@@ -91,7 +94,8 @@
9740EEB11CF90186004384FC /* Flutter */,
97C146F01CF9000F007C117D /* Runner */,
97C146EF1CF9000F007C117D /* Products */,
- CF3B75C9A7D2FA2A4C99F110 /* Frameworks */,
+ EE3450EDCED914F636FA6BB9 /* Pods */,
+ BDC8FA085BD2993252DE5757 /* Frameworks */,
);
sourceTree = "";
};
@@ -127,6 +131,21 @@
name = "Supporting Files";
sourceTree = "";
};
+ BDC8FA085BD2993252DE5757 /* Frameworks */ = {
+ isa = PBXGroup;
+ children = (
+ 9E29C2B321AA1B6738D05DCC /* libPods-Runner.a */,
+ );
+ name = Frameworks;
+ sourceTree = "";
+ };
+ EE3450EDCED914F636FA6BB9 /* Pods */ = {
+ isa = PBXGroup;
+ children = (
+ );
+ name = Pods;
+ sourceTree = "";
+ };
/* End PBXGroup section */
/* Begin PBXNativeTarget section */
@@ -134,12 +153,14 @@
isa = PBXNativeTarget;
buildConfigurationList = 97C147051CF9000F007C117D /* Build configuration list for PBXNativeTarget "Runner" */;
buildPhases = (
+ A3515840785C8A9829855BB5 /* [CP] Check Pods Manifest.lock */,
9740EEB61CF901F6004384FC /* Run Script */,
97C146EA1CF9000F007C117D /* Sources */,
97C146EB1CF9000F007C117D /* Frameworks */,
97C146EC1CF9000F007C117D /* Resources */,
9705A1C41CF9048500538489 /* Embed Frameworks */,
3B06AD1E1E4923F5004D2608 /* Thin Binary */,
+ AB4C7D1508951531E70F0A36 /* [CP] Embed Pods Frameworks */,
);
buildRules = (
);
@@ -228,6 +249,42 @@
shellPath = /bin/sh;
shellScript = "/bin/sh \"$FLUTTER_ROOT/packages/flutter_tools/bin/xcode_backend.sh\" build";
};
+ A3515840785C8A9829855BB5 /* [CP] Check Pods Manifest.lock */ = {
+ isa = PBXShellScriptBuildPhase;
+ buildActionMask = 2147483647;
+ files = (
+ );
+ inputPaths = (
+ "${PODS_PODFILE_DIR_PATH}/Podfile.lock",
+ "${PODS_ROOT}/Manifest.lock",
+ );
+ name = "[CP] Check Pods Manifest.lock";
+ 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;
+ };
+ AB4C7D1508951531E70F0A36 /* [CP] Embed Pods Frameworks */ = {
+ isa = PBXShellScriptBuildPhase;
+ buildActionMask = 2147483647;
+ files = (
+ );
+ inputPaths = (
+ "${SRCROOT}/Pods/Target Support Files/Pods-Runner/Pods-Runner-frameworks.sh",
+ "${PODS_ROOT}/../.symlinks/flutter/ios/Flutter.framework",
+ );
+ name = "[CP] Embed Pods Frameworks";
+ outputPaths = (
+ "${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/Flutter.framework",
+ );
+ runOnlyForDeploymentPostprocessing = 0;
+ shellPath = /bin/sh;
+ shellScript = "\"${SRCROOT}/Pods/Target Support Files/Pods-Runner/Pods-Runner-frameworks.sh\"\n";
+ showEnvVarsInLog = 0;
+ };
/* End PBXShellScriptBuildPhase section */
/* Begin PBXSourcesBuildPhase section */
diff --git a/example/ios/Runner.xcworkspace/contents.xcworkspacedata b/example/ios/Runner.xcworkspace/contents.xcworkspacedata
index 1d526a1..21a3cc1 100644
--- a/example/ios/Runner.xcworkspace/contents.xcworkspacedata
+++ b/example/ios/Runner.xcworkspace/contents.xcworkspacedata
@@ -4,4 +4,7 @@
+
+
diff --git a/example/ios/Runner/Info.plist b/example/ios/Runner/Info.plist
index 09849c0..15b1edd 100644
--- a/example/ios/Runner/Info.plist
+++ b/example/ios/Runner/Info.plist
@@ -4,8 +4,15 @@
CFBundleDevelopmentRegion
en
+
CFBundleExecutable
$(EXECUTABLE_NAME)
+ NSCameraUsageDescription
+ Used to demonstrate image picker plugin
+ NSMicrophoneUsageDescription
+ Used to capture audio for image picker plugin
+ NSPhotoLibraryUsageDescription
+ Used to demonstrate image picker plugin
CFBundleIdentifier
$(PRODUCT_BUNDLE_IDENTIFIER)
CFBundleInfoDictionaryVersion
diff --git a/example/lib/main.dart b/example/lib/main.dart
index c1b824f..c65897b 100644
--- a/example/lib/main.dart
+++ b/example/lib/main.dart
@@ -13,10 +13,11 @@ class MyApp extends StatefulWidget {
class _MyAppState extends State {
String _path = '...';
String _fileName = '...';
+ FileType _pickingType;
void _openFileExplorer() async {
try {
- _path = await FilePicker.getFilePath;
+ _path = await FilePicker.getFilePath(type: _pickingType);
} on PlatformException catch (e) {
print(e.toString());
}
@@ -24,7 +25,7 @@ class _MyAppState extends State {
if (!mounted) return;
setState(() {
- _fileName = _path.split('/').last;
+ _fileName = _path != null ? _path.split('/').last : '...';
});
}
@@ -45,6 +46,32 @@ class _MyAppState extends State {
child: new Column(
mainAxisAlignment: MainAxisAlignment.center,
children: [
+ new Padding(
+ padding: const EdgeInsets.all(20.0),
+ child: new DropdownButton(
+ hint: new Text('LOAD FILE PATH FROM...'),
+ value: _pickingType,
+ items: [
+ new DropdownMenuItem(
+ child: new Text('FROM CAMERA'),
+ value: FileType.CAPTURE,
+ ),
+ new DropdownMenuItem(
+ child: new Text('FROM GALLERY'),
+ value: FileType.IMAGE,
+ ),
+ new DropdownMenuItem(
+ child: new Text('FROM PDF'),
+ value: FileType.PDF,
+ )
+ ],
+ onChanged: (value) {
+ setState(() {
+ _pickingType = value;
+ });
+ },
+ ),
+ ),
new Padding(
padding: const EdgeInsets.all(20.0),
child: new RaisedButton(
diff --git a/example/test/widget_test.dart b/example/test/widget_test.dart
deleted file mode 100644
index 8b7e66d..0000000
--- a/example/test/widget_test.dart
+++ /dev/null
@@ -1,25 +0,0 @@
-// This is a basic Flutter widget test.
-// To perform an interaction with a widget in your test, use the WidgetTester utility that Flutter
-// provides. For example, you can send tap and scroll gestures. You can also use WidgetTester to
-// find child widgets in the widget tree, read text, and verify that the values of widget properties
-// are correct.
-
-import 'package:flutter/material.dart';
-import 'package:flutter_test/flutter_test.dart';
-
-import 'package:file_picker_example/main.dart';
-
-void main() {
- testWidgets('Verify Platform version', (WidgetTester tester) async {
- // Build our app and trigger a frame.
- await tester.pumpWidget(new MyApp());
-
- // Verify that platform version is retrieved.
- expect(
- find.byWidgetPredicate(
- (Widget widget) =>
- widget is Text && widget.data.startsWith('Running on:'),
- ),
- findsOneWidget);
- });
-}
diff --git a/lib/file_picker.dart b/lib/file_picker.dart
index 4868fc1..8987b37 100644
--- a/lib/file_picker.dart
+++ b/lib/file_picker.dart
@@ -1,9 +1,35 @@
import 'dart:async';
import 'package:flutter/services.dart';
+import 'package:image_picker/image_picker.dart';
+import 'package:meta/meta.dart';
class FilePicker {
static const MethodChannel _channel = const MethodChannel('file_picker');
- static Future get getFilePath async => await _channel.invokeMethod('pickPDF');
+ static Future get _getPDF async => await _channel.invokeMethod('pickPDF');
+
+ static Future _getImage(ImageSource type) async {
+ var image = await ImagePicker.pickImage(source: type);
+
+ return image?.path;
+ }
+
+ static Future getFilePath({@required FileType type}) async {
+ switch (type) {
+ case FileType.PDF:
+ return _getPDF;
+ case FileType.IMAGE:
+ return _getImage(ImageSource.gallery);
+ case FileType.CAPTURE:
+ return _getImage(ImageSource.camera);
+ }
+ return '';
+ }
+}
+
+enum FileType {
+ PDF,
+ IMAGE,
+ CAPTURE,
}
diff --git a/pubspec.yaml b/pubspec.yaml
index f3a0388..54e0f04 100644
--- a/pubspec.yaml
+++ b/pubspec.yaml
@@ -1,15 +1,17 @@
name: file_picker
-description: A new flutter plugin project.
-version: 0.0.1
-author:
-homepage:
+description: A plugin that allows you to pick absolute paths from diferent file types.
+version: 0.1.4
+author: Miguel Ruivo
+homepage: https://github.com/miguelpruivo/plugins_flutter_file_picker
dependencies:
flutter:
sdk: flutter
+ image_picker: ^0.4.10
+ meta: ^1.1.5
environment:
- sdk: '<3.0.0'
+ sdk: ">=1.19.0 <3.0.0"
# For information on the generic Dart part of this file, see the
# following page: https://www.dartlang.org/tools/pub/pubspec