adds support for gallery and camera path picks
This commit is contained in:
parent
f886a0011e
commit
603c0f15d2
|
@ -0,0 +1,3 @@
|
|||
{
|
||||
"java.configuration.updateBuildConfiguration": "disabled"
|
||||
}
|
23
CHANGELOG.md
23
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.
|
||||
|
|
22
LICENSE
22
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.
|
79
README.md
79
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 `<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).
|
||||
|
|
|
@ -1,2 +1,2 @@
|
|||
connection.project.dir=../example/android
|
||||
connection.project.dir=
|
||||
eclipse.preferences.version=1
|
||||
|
|
Binary file not shown.
After Width: | Height: | Size: 76 KiB |
|
@ -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
|
|
@ -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 */
|
||||
|
|
|
@ -4,4 +4,7 @@
|
|||
<FileRef
|
||||
location = "group:Runner.xcodeproj">
|
||||
</FileRef>
|
||||
<FileRef
|
||||
location = "group:Pods/Pods.xcodeproj">
|
||||
</FileRef>
|
||||
</Workspace>
|
||||
|
|
|
@ -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>
|
||||
|
|
|
@ -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(
|
||||
|
|
|
@ -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);
|
||||
});
|
||||
}
|
|
@ -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,
|
||||
}
|
||||
|
|
12
pubspec.yaml
12
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 <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
|
||||
|
|
Loading…
Reference in New Issue