adds support for gallery and camera path picks

This commit is contained in:
Miguel Ruivo 2018-09-11 15:59:35 +01:00
parent f886a0011e
commit 603c0f15d2
14 changed files with 282 additions and 40 deletions

3
.vscode/settings.json vendored Normal file
View File

@ -0,0 +1,3 @@
{
"java.configuration.updateBuildConfiguration": "disabled"
}

View File

@ -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.

22
LICENSE
View File

@ -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.

View File

@ -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 `<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />` 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 `<project root>/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)<br>
[X] Load PDF file path<br>
[X] Load path from gallery<br>
[X] Load path from camera shot<br>
[ ] Load a custom format<br>
## 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<MyHomePage> {
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).
For help on editing plugin code, view the [documentation](https://flutter.io/platform-plugins/#edit-code).

View File

@ -1,2 +1,2 @@
connection.project.dir=../example/android
connection.project.dir=
eclipse.preferences.version=1

BIN
example/demo.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 76 KiB

28
example/ios/Podfile.lock Normal file
View File

@ -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

View File

@ -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 = "<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>"; };
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 = "<group>";
};
@ -127,6 +131,21 @@
name = "Supporting Files";
sourceTree = "<group>";
};
BDC8FA085BD2993252DE5757 /* Frameworks */ = {
isa = PBXGroup;
children = (
9E29C2B321AA1B6738D05DCC /* libPods-Runner.a */,
);
name = Frameworks;
sourceTree = "<group>";
};
EE3450EDCED914F636FA6BB9 /* Pods */ = {
isa = PBXGroup;
children = (
);
name = Pods;
sourceTree = "<group>";
};
/* 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 */

View File

@ -4,4 +4,7 @@
<FileRef
location = "group:Runner.xcodeproj">
</FileRef>
<FileRef
location = "group:Pods/Pods.xcodeproj">
</FileRef>
</Workspace>

View File

@ -4,8 +4,15 @@
<dict>
<key>CFBundleDevelopmentRegion</key>
<string>en</string>
<key>CFBundleExecutable</key>
<string>$(EXECUTABLE_NAME)</string>
<key>NSCameraUsageDescription</key>
<string>Used to demonstrate image picker plugin</string>
<key>NSMicrophoneUsageDescription</key>
<string>Used to capture audio for image picker plugin</string>
<key>NSPhotoLibraryUsageDescription</key>
<string>Used to demonstrate image picker plugin</string>
<key>CFBundleIdentifier</key>
<string>$(PRODUCT_BUNDLE_IDENTIFIER)</string>
<key>CFBundleInfoDictionaryVersion</key>

View File

@ -13,10 +13,11 @@ class MyApp extends StatefulWidget {
class _MyAppState extends State<MyApp> {
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<MyApp> {
if (!mounted) return;
setState(() {
_fileName = _path.split('/').last;
_fileName = _path != null ? _path.split('/').last : '...';
});
}
@ -45,6 +46,32 @@ class _MyAppState extends State<MyApp> {
child: new Column(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
new Padding(
padding: const EdgeInsets.all(20.0),
child: new DropdownButton(
hint: new Text('LOAD FILE PATH FROM...'),
value: _pickingType,
items: <DropdownMenuItem>[
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(

View File

@ -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);
});
}

View File

@ -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<String> get getFilePath async => await _channel.invokeMethod('pickPDF');
static Future<String> get _getPDF async => await _channel.invokeMethod('pickPDF');
static Future<String> _getImage(ImageSource type) async {
var image = await ImagePicker.pickImage(source: type);
return image?.path;
}
static Future<String> 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,
}

View File

@ -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 <miguelpruivo@hotmail.com>
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