From a291b7477992425a2a3ffc3033a1532b7b734cb0 Mon Sep 17 00:00:00 2001 From: Miguel Ruivo Date: Wed, 26 May 2021 01:00:48 +0100 Subject: [PATCH] Updates docs and removes deprecated call warnings --- CHANGELOG.md | 15 +++++++++++ README.md | 20 +++++++++++--- analysis_options.yaml | 3 +++ .../plugin/filepicker/FilePickerPlugin.java | 4 +-- .../android/app/src/main/AndroidManifest.xml | 4 ++- .../filepickerexample/MainActivity.java | 12 ++------- example/ios/Flutter/Flutter.podspec | 18 ------------- example/lib/src/file_picker_demo.dart | 2 +- lib/src/file_picker.dart | 27 ++++++++++++------- lib/src/file_picker_io.dart | 6 ++--- lib/src/file_picker_web.dart | 5 ++++ lib/src/platform_file.dart | 13 +++++---- pubspec.yaml | 2 +- 13 files changed, 76 insertions(+), 55 deletions(-) create mode 100644 analysis_options.yaml delete mode 100644 example/ios/Flutter/Flutter.podspec diff --git a/CHANGELOG.md b/CHANGELOG.md index 14842e4..f1b4e85 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,18 @@ +## 3.0.2 +##### General +- `name` and `size` properties are now non-nullable types. +##### Docs +- Updates README; +- Updates API docs; + +##### Example +- Updates Android example app to V2; +##### Android +- Removes deprecated call warnings; + +##### Other +- Adds analysis_options.yaml with linter rule to surpress warnings from generated_plugin_registrant. + ## 3.0.1 #### Android - Use MediaStore Opener (which goes through the gallery) instead of default explorer. (Thank you @tmthecoder). diff --git a/README.md b/README.md index 93d25e4..dd6e837 100644 --- a/README.md +++ b/README.md @@ -53,7 +53,7 @@ Quick simple usage example: #### Single file ``` -FilePickerResult result = await FilePicker.platform.pickFiles(); +FilePickerResult? result = await FilePicker.platform.pickFiles(); if(result != null) { File file = File(result.files.single.path); @@ -63,7 +63,7 @@ if(result != null) { ``` #### Multiple files ``` -FilePickerResult result = await FilePicker.platform.pickFiles(allowMultiple: true); +FilePickerResult? result = await FilePicker.platform.pickFiles(allowMultiple: true); if(result != null) { List files = result.paths.map((path) => File(path)).toList(); @@ -73,14 +73,14 @@ if(result != null) { ``` #### Multiple files with extension filter ``` -FilePickerResult result = await FilePicker.platform.pickFiles( +FilePickerResult? result = await FilePicker.platform.pickFiles( type: FileType.custom, allowedExtensions: ['jpg', 'pdf', 'doc'], ); ``` ### Load result and file details ``` -FilePickerResult result = await FilePicker.platform.pickFiles(); +FilePickerResult? result = await FilePicker.platform.pickFiles(); if(result != null) { PlatformFile file = result.files.first; @@ -94,6 +94,18 @@ if(result != null) { // User canceled the picker } ``` +#### Pick and upload a file to Firebase Storage with Flutter Web +``` +FilePickerResult? result = await FilePicker.platform.pickFiles(); + +if (result != null) { + Uint8List fileBytes = result.files.first.bytes; + String fileName = result.files.first.name; + + // Upload file + await FirebaseStorage.instance.ref('uploads/$fileName').putData(fileBytes); +} +``` For full usage details refer to the **[Wiki](https://github.com/miguelpruivo/flutter_file_picker/wiki)** above. diff --git a/analysis_options.yaml b/analysis_options.yaml new file mode 100644 index 0000000..5fa857e --- /dev/null +++ b/analysis_options.yaml @@ -0,0 +1,3 @@ +analyzer: + exclude: + - lib/generated_plugin_registrant.dart \ No newline at end of file diff --git a/android/src/main/java/com/mr/flutter/plugin/filepicker/FilePickerPlugin.java b/android/src/main/java/com/mr/flutter/plugin/filepicker/FilePickerPlugin.java index 6a79aba..f25eff0 100644 --- a/android/src/main/java/com/mr/flutter/plugin/filepicker/FilePickerPlugin.java +++ b/android/src/main/java/com/mr/flutter/plugin/filepicker/FilePickerPlugin.java @@ -23,11 +23,11 @@ import io.flutter.plugin.common.EventChannel; import io.flutter.plugin.common.MethodCall; import io.flutter.plugin.common.MethodChannel; import io.flutter.plugin.common.PluginRegistry; -import io.flutter.plugin.common.PluginRegistry.Registrar; /** * FilePickerPlugin */ +@SuppressWarnings("deprecation") public class FilePickerPlugin implements MethodChannel.MethodCallHandler, FlutterPlugin, ActivityAware { private static final String TAG = "FilePicker"; @@ -117,7 +117,7 @@ public class FilePickerPlugin implements MethodChannel.MethodCallHandler, Flutte /** * Plugin registration. */ - public static void registerWith(final Registrar registrar) { + public static void registerWith(final io.flutter.plugin.common.PluginRegistry.Registrar registrar) { if (registrar.activity() == null) { // If a background flutter view tries to register the plugin, there will be no activity from the registrar, diff --git a/example/android/app/src/main/AndroidManifest.xml b/example/android/app/src/main/AndroidManifest.xml index 6365b83..ca5e701 100644 --- a/example/android/app/src/main/AndroidManifest.xml +++ b/example/android/app/src/main/AndroidManifest.xml @@ -14,7 +14,6 @@ additional functionality it is fine to subclass or reimplement FlutterApplication and put your custom class here. --> + diff --git a/example/android/app/src/main/java/com/mr/flutter/plugin/filepickerexample/MainActivity.java b/example/android/app/src/main/java/com/mr/flutter/plugin/filepickerexample/MainActivity.java index ec4249b..192f40a 100644 --- a/example/android/app/src/main/java/com/mr/flutter/plugin/filepickerexample/MainActivity.java +++ b/example/android/app/src/main/java/com/mr/flutter/plugin/filepickerexample/MainActivity.java @@ -1,13 +1,5 @@ package com.mr.flutter.plugin.filepicker.example; -import android.os.Bundle; -import io.flutter.app.FlutterActivity; -import io.flutter.plugins.GeneratedPluginRegistrant; +import io.flutter.embedding.android.FlutterActivity; -public class MainActivity extends FlutterActivity { - @Override - protected void onCreate(Bundle savedInstanceState) { - super.onCreate(savedInstanceState); - GeneratedPluginRegistrant.registerWith(this); - } -} +public class MainActivity extends FlutterActivity { } diff --git a/example/ios/Flutter/Flutter.podspec b/example/ios/Flutter/Flutter.podspec deleted file mode 100644 index 5ca3041..0000000 --- a/example/ios/Flutter/Flutter.podspec +++ /dev/null @@ -1,18 +0,0 @@ -# -# NOTE: This podspec is NOT to be published. It is only used as a local source! -# - -Pod::Spec.new do |s| - s.name = 'Flutter' - s.version = '1.0.0' - s.summary = 'High-performance, high-fidelity mobile apps.' - s.description = <<-DESC -Flutter provides an easy and productive way to build and deploy high-performance mobile apps for Android and iOS. - DESC - s.homepage = 'https://flutter.io' - s.license = { :type => 'MIT' } - s.author = { 'Flutter Dev Team' => 'flutter-dev@googlegroups.com' } - s.source = { :git => 'https://github.com/flutter/engine', :tag => s.version.to_s } - s.ios.deployment_target = '8.0' - s.vendored_frameworks = 'Flutter.framework' -end diff --git a/example/lib/src/file_picker_demo.dart b/example/lib/src/file_picker_demo.dart index e86e439..e855b00 100644 --- a/example/lib/src/file_picker_demo.dart +++ b/example/lib/src/file_picker_demo.dart @@ -196,7 +196,7 @@ class _FilePickerDemoState extends State { ? _paths! .map((e) => e.name) .toList()[index] - : _fileName ?? '...')!; + : _fileName ?? '...'); final path = _paths! .map((e) => e.path) .toList()[index] diff --git a/lib/src/file_picker.dart b/lib/src/file_picker.dart index d7bd8c8..2312e6f 100644 --- a/lib/src/file_picker.dart +++ b/lib/src/file_picker.dart @@ -46,28 +46,35 @@ abstract class FilePicker extends PlatformInterface { /// Default [type] set to [FileType.any] with [allowMultiple] set to [false] /// Optionally, [allowedExtensions] might be provided (e.g. `[pdf, svg, jpg]`.). /// - /// If [withData] is set, picked files will have its byte data immediately available on memory as [Uint8List] - /// which can be useful if you are picking it for server upload or similar. + /// If [withData] is set, picked files will have its byte data immediately available on memory as `Uint8List` + /// which can be useful if you are picking it for server upload or similar. However, have in mind that + /// enabling this on IO (iOS & Android) may result in out of memory issues if you allow multiple picks or + /// pick huge files. Use [withReadStream] instead. Defaults to `true` on web, `false` otherwise. /// /// If [withReadStream] is set, picked files will have its byte data available as a [Stream>] - /// which can be useful for uploading and processing large files. + /// which can be useful for uploading and processing large files. Defaults to `false`. /// /// If you want to track picking status, for example, because some files may take some time to be /// cached (particularly those picked from cloud providers), you may want to set [onFileLoading] handler /// that will give you the current status of picking. /// + /// If [allowCompression] is set, it will allow media to apply the default OS compression. + /// Defaults to `true`. + /// /// The result is wrapped in a [FilePickerResult] which contains helper getters /// with useful information regarding the picked [List]. /// + /// For more information, check the [API documentation](https://github.com/miguelpruivo/flutter_file_picker/wiki/api). + /// /// Returns [null] if aborted. Future pickFiles({ FileType type = FileType.any, List? allowedExtensions, Function(FilePickerStatus)? onFileLoading, - bool? allowCompression, + bool allowCompression = true, bool allowMultiple = false, - bool? withData, - bool? withReadStream, + bool withData = false, + bool withReadStream = false, }) async => throw UnimplementedError('pickFiles() has not been implemented.'); @@ -78,13 +85,13 @@ abstract class FilePicker extends PlatformInterface { /// of it whenever needed. However, this will force the cleanup if you want to manage those on your own. /// /// Returns [true] if the files were removed with success, [false] otherwise. - Future clearTemporaryFiles() async => throw UnimplementedError( - 'clearTemporaryFiles() has not been implemented.'); + Future clearTemporaryFiles() async => throw UnimplementedError('clearTemporaryFiles() has not been implemented.'); /// Selects a directory and returns its absolute path. /// /// On Android, this requires to be running on SDK 21 or above, else won't work. /// Returns [null] if folder path couldn't be resolved. - Future getDirectoryPath() async => - throw UnimplementedError('getDirectoryPath() has not been implemented.'); + /// + /// Note: Some Android paths are protected, hence can't be accessed and will return `/` instead. + Future getDirectoryPath() async => throw UnimplementedError('getDirectoryPath() has not been implemented.'); } diff --git a/lib/src/file_picker_io.dart b/lib/src/file_picker_io.dart index d168611..2b9e9f7 100644 --- a/lib/src/file_picker_io.dart +++ b/lib/src/file_picker_io.dart @@ -70,9 +70,9 @@ class FilePickerIO extends FilePicker { bool? withReadStream, ) async { final String type = describeEnum(fileType); - if (type != 'custom' && (allowedExtensions?.isNotEmpty ?? false)) { + if (type != FileType.custom && (allowedExtensions?.isNotEmpty ?? false)) { throw Exception( - 'If you are using a custom extension filter, please use the FileType.custom instead.'); + 'You are setting a type [$fileType]. Custom extension filters are only allowed with FileType.custom, please change it or remove filters.'); } try { _eventSubscription?.cancel(); @@ -98,7 +98,7 @@ class FilePickerIO extends FilePicker { final List platformFiles = []; - for (final platformFileMap in result) { + for (final Map platformFileMap in result) { platformFiles.add( PlatformFile.fromMap( platformFileMap, diff --git a/lib/src/file_picker_web.dart b/lib/src/file_picker_web.dart index c0da716..43c52c5 100644 --- a/lib/src/file_picker_web.dart +++ b/lib/src/file_picker_web.dart @@ -47,6 +47,11 @@ class FilePickerWeb extends FilePicker { bool? withData = true, bool? withReadStream = false, }) async { + if (type != FileType.custom && (allowedExtensions?.isNotEmpty ?? false)) { + throw Exception( + 'You are setting a type [$type]. Custom extension filters are only allowed with FileType.custom, please change it or remove filters.'); + } + final Completer?> filesCompleter = Completer?>(); diff --git a/lib/src/platform_file.dart b/lib/src/platform_file.dart index f2adccc..62e5b2a 100644 --- a/lib/src/platform_file.dart +++ b/lib/src/platform_file.dart @@ -3,11 +3,11 @@ import 'dart:typed_data'; class PlatformFile { const PlatformFile({ + required this.name, + required this.size, this.path, - this.name, this.bytes, this.readStream, - this.size, }); PlatformFile.fromMap(Map data, {this.readStream}) @@ -21,21 +21,24 @@ class PlatformFile { /// ``` /// final File myFile = File(platformFile.path); /// ``` + /// On web this is always `null`. You should access `bytes` property instead. + /// Read more about it [here](https://github.com/miguelpruivo/flutter_file_picker/wiki/FAQ) final String? path; /// File name including its extension. - final String? name; + final String name; /// Byte data for this file. Particurlarly useful if you want to manipulate its data /// or easily upload to somewhere else. + /// [Check here in the FAQ](https://github.com/miguelpruivo/flutter_file_picker/wiki/FAQ) an example on how to use it to upload on web. final Uint8List? bytes; /// File content as stream final Stream>? readStream; /// The file size in bytes. - final int? size; + final int size; /// File extension for this file. - String? get extension => name?.split('.').last; + String? get extension => name.split('.').last; } diff --git a/pubspec.yaml b/pubspec.yaml index 07eb50a..d23734d 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -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: 3.0.1 +version: 3.0.2 dependencies: flutter: