From c5fab5d740eb4ecf44f72b6a22da24b902fa04e3 Mon Sep 17 00:00:00 2001 From: Swift Kim Date: Mon, 6 Dec 2021 14:20:06 +0900 Subject: [PATCH] [image_picker] Update image_picker to 0.8.4 (#282) * [image_picker] Update image_picker to 0.8.4 * Fix cancelled by a second request --- packages/image_picker/CHANGELOG.md | 21 +- packages/image_picker/README.md | 28 +-- ...icker_test.dart => image_picker_test.dart} | 5 +- packages/image_picker/example/lib/main.dart | 141 ++++++++----- packages/image_picker/example/pubspec.yaml | 4 +- .../example/test_driver/integration_test.dart | 2 - .../image_picker/example/tizen/Runner.csproj | 2 +- .../example/tizen/tizen-manifest.xml | 5 +- packages/image_picker/pubspec.yaml | 4 +- .../tizen/src/image_picker_tizen_plugin.cc | 195 ++++++++++-------- tools/recipe.yaml | 2 +- 11 files changed, 230 insertions(+), 179 deletions(-) rename packages/image_picker/example/integration_test/{old_image_picker_test.dart => image_picker_test.dart} (72%) diff --git a/packages/image_picker/CHANGELOG.md b/packages/image_picker/CHANGELOG.md index 92f6832b2..19b6ba90f 100644 --- a/packages/image_picker/CHANGELOG.md +++ b/packages/image_picker/CHANGELOG.md @@ -1,12 +1,19 @@ ## 1.0.0 -* Initial release +* Initial release. ## 2.0.0 -* Update Dart and Flutter SDK constraints -* Update Flutter copyright information -* Update example and integration_test -* Port to use platform interface -* Update video_player to 2.0.2 -* Organize dev_dependencies +* Update Dart and Flutter SDK constraints. +* Update Flutter copyright information. +* Update the example app and integration_test. +* Port to use platform interface. +* Organize dev_dependencies. + +## 2.1.0 + +* Update image_picker to 0.8.4. +* Update image_picker_platform_interface to 2.4.1. +* Implement `pickMultiImage`. +* Update the example app. +* Minor cleanups. diff --git a/packages/image_picker/README.md b/packages/image_picker/README.md index c04e974f6..838c6e30f 100644 --- a/packages/image_picker/README.md +++ b/packages/image_picker/README.md @@ -10,29 +10,31 @@ To use this plugin, add `image_picker` and `image_picker_tizen` as [dependencies ```yaml dependencies: - image_picker: ^0.7.3 - image_picker_tizen: ^2.0.0 + image_picker: ^0.8.4 + image_picker_tizen: ^2.1.0 ``` -## Example - -Import the library. +Then you can import `image_picker` in your Dart code. ``` dart import 'package:image_picker/image_picker.dart'; + +final ImagePicker picker = ImagePicker(); +final XFile? image = await picker.pickImage(source: ImageSource.gallery); ``` -Then invoke the static `image_picker` method anywhere in your Dart code. +For detailed usage, see https://github.com/flutter/plugins/tree/master/packages/image_picker/image_picker#example. -``` dart -final picker = ImagePicker(); -final pickedFile = await picker.getImage(source: ImageSource.gallery); -``` +## Supported devices + +- Galaxy Watch series (running Tizen 5.5 or later) -## Limitations +## Supported APIs -- This plugin is only supported on **Galaxy Watch** devices running Tizen 5.5 or later. -- The only API you can use is `getImage(source: ImageSource.gallery)`. You can't pick a video file (`getVideo()`) or pick a file from `ImageSource.camera`. +- [x] `ImagePicker.pickImage` (only `ImageSource.gallery` is available as `source`) +- [x] `ImagePicker.pickMultiImage` +- [ ] `ImagePicker.pickVideo` (no file manager app available) +- [ ] `ImagePicker.retrieveLostData` (Android-only) ## Required privileges diff --git a/packages/image_picker/example/integration_test/old_image_picker_test.dart b/packages/image_picker/example/integration_test/image_picker_test.dart similarity index 72% rename from packages/image_picker/example/integration_test/old_image_picker_test.dart rename to packages/image_picker/example/integration_test/image_picker_test.dart index 528c8b9f1..2b82b4bda 100644 --- a/packages/image_picker/example/integration_test/old_image_picker_test.dart +++ b/packages/image_picker/example/integration_test/image_picker_test.dart @@ -2,10 +2,11 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -// @dart=2.9 - +import 'package:flutter_test/flutter_test.dart'; import 'package:integration_test/integration_test.dart'; void main() { IntegrationTestWidgetsFlutterBinding.ensureInitialized(); + + testWidgets('placeholder test', (WidgetTester tester) async {}); } diff --git a/packages/image_picker/example/lib/main.dart b/packages/image_picker/example/lib/main.dart index 81cedc368..84f8a1fcc 100644 --- a/packages/image_picker/example/lib/main.dart +++ b/packages/image_picker/example/lib/main.dart @@ -19,7 +19,7 @@ void main() { class MyApp extends StatelessWidget { @override Widget build(BuildContext context) { - return const MaterialApp( + return MaterialApp( title: 'Image Picker Demo', home: MyHomePage(title: 'Image Picker Example'), ); @@ -27,7 +27,7 @@ class MyApp extends StatelessWidget { } class MyHomePage extends StatefulWidget { - const MyHomePage({Key? key, this.title}) : super(key: key); + MyHomePage({Key? key, this.title}) : super(key: key); final String? title; @@ -36,9 +36,15 @@ class MyHomePage extends StatefulWidget { } class _MyHomePageState extends State { - PickedFile? _imageFile; + List? _imageFileList; + + set _imageFile(XFile? value) { + _imageFileList = value == null ? null : [value]; + } + dynamic _pickImageError; bool isVideo = false; + VideoPlayerController? _controller; VideoPlayerController? _toBeDisposed; String? _retrieveDataError; @@ -48,7 +54,7 @@ class _MyHomePageState extends State { final TextEditingController maxHeightController = TextEditingController(); final TextEditingController qualityController = TextEditingController(); - Future _playVideo(PickedFile? file) async { + Future _playVideo(XFile? file) async { if (file != null && mounted) { await _disposeVideoController(); late VideoPlayerController controller; @@ -72,20 +78,38 @@ class _MyHomePageState extends State { } } - Future _onImageButtonPressed(ImageSource source, - {BuildContext? context}) async { + void _onImageButtonPressed(ImageSource source, + {BuildContext? context, bool isMultiImage = false}) async { if (_controller != null) { await _controller!.setVolume(0.0); } if (isVideo) { - final PickedFile? file = await _picker.getVideo( + final XFile? file = await _picker.pickVideo( source: source, maxDuration: const Duration(seconds: 10)); await _playVideo(file); + } else if (isMultiImage) { + await _displayPickImageDialog(context!, + (double? maxWidth, double? maxHeight, int? quality) async { + try { + final pickedFileList = await _picker.pickMultiImage( + maxWidth: maxWidth, + maxHeight: maxHeight, + imageQuality: quality, + ); + setState(() { + _imageFileList = pickedFileList; + }); + } catch (e) { + setState(() { + _pickImageError = e; + }); + } + }); } else { await _displayPickImageDialog(context!, (double? maxWidth, double? maxHeight, int? quality) async { try { - final PickedFile? pickedFile = await _picker.getImage( + final pickedFile = await _picker.pickImage( source: source, maxWidth: maxWidth, maxHeight: maxHeight, @@ -146,21 +170,28 @@ class _MyHomePageState extends State { ); } - Widget _previewImage() { + Widget _previewImages() { final Text? retrieveError = _getRetrieveErrorWidget(); if (retrieveError != null) { return retrieveError; } - if (_imageFile != null) { - if (kIsWeb) { - // Why network? - // See https://pub.dev/packages/image_picker#getting-ready-for-the-web-platform - return Image.network(_imageFile!.path); - } else { - return Semantics( - child: Image.file(File(_imageFile!.path)), - label: 'image_picker_example_picked_image'); - } + if (_imageFileList != null) { + return Semantics( + child: ListView.builder( + key: UniqueKey(), + itemBuilder: (context, index) { + // Why network for web? + // See https://pub.dev/packages/image_picker#getting-ready-for-the-web-platform + return Semantics( + label: 'image_picker_example_picked_image', + child: kIsWeb + ? Image.network(_imageFileList![index].path) + : Image.file(File(_imageFileList![index].path)), + ); + }, + itemCount: _imageFileList!.length, + ), + label: 'image_picker_example_picked_images'); } else if (_pickImageError != null) { return Text( 'Pick image error: $_pickImageError', @@ -174,8 +205,16 @@ class _MyHomePageState extends State { } } + Widget _handlePreview() { + if (isVideo) { + return _previewVideo(); + } else { + return _previewImages(); + } + } + Future retrieveLostData() async { - final LostData response = await _picker.getLostData(); + final LostDataResponse response = await _picker.retrieveLostData(); if (response.isEmpty) { return; } @@ -187,6 +226,7 @@ class _MyHomePageState extends State { isVideo = false; setState(() { _imageFile = response.file; + _imageFileList = response.files; }); } } else { @@ -213,7 +253,7 @@ class _MyHomePageState extends State { textAlign: TextAlign.center, ); case ConnectionState.done: - return isVideo ? _previewVideo() : _previewImage(); + return _handlePreview(); default: if (snapshot.hasError) { return Text( @@ -229,7 +269,7 @@ class _MyHomePageState extends State { } }, ) - : (isVideo ? _previewVideo() : _previewImage()), + : _handlePreview(), ), floatingActionButton: Column( mainAxisAlignment: MainAxisAlignment.end, @@ -243,7 +283,7 @@ class _MyHomePageState extends State { }, heroTag: 'image0', tooltip: 'Pick Image from gallery', - child: const Icon(Icons.photo_library), + child: const Icon(Icons.photo), ), ), Padding( @@ -251,11 +291,15 @@ class _MyHomePageState extends State { child: FloatingActionButton( onPressed: () { isVideo = false; - _onImageButtonPressed(ImageSource.camera, context: context); + _onImageButtonPressed( + ImageSource.gallery, + context: context, + isMultiImage: true, + ); }, heroTag: 'image1', - tooltip: 'Take a Photo', - child: const Icon(Icons.camera_alt), + tooltip: 'Pick Multiple Image from gallery', + child: const Icon(Icons.photo_library), ), ), Padding( @@ -271,19 +315,6 @@ class _MyHomePageState extends State { child: const Icon(Icons.video_library), ), ), - Padding( - padding: const EdgeInsets.only(top: 16.0), - child: FloatingActionButton( - backgroundColor: Colors.red, - onPressed: () { - isVideo = true; - _onImageButtonPressed(ImageSource.camera); - }, - heroTag: 'video1', - tooltip: 'Take a Video', - child: const Icon(Icons.videocam), - ), - ), ], ), ); @@ -302,30 +333,28 @@ class _MyHomePageState extends State { BuildContext context, OnPickImageCallback onPick) async { return showDialog( context: context, - builder: (BuildContext context) { + builder: (context) { return AlertDialog( - title: const Text('Add optional parameters'), + title: Text('Add optional parameters'), content: Column( children: [ TextField( controller: maxWidthController, - keyboardType: - const TextInputType.numberWithOptions(decimal: true), - decoration: const InputDecoration( - hintText: 'Enter maxWidth if desired'), + keyboardType: TextInputType.numberWithOptions(decimal: true), + decoration: + InputDecoration(hintText: "Enter maxWidth if desired"), ), TextField( controller: maxHeightController, - keyboardType: - const TextInputType.numberWithOptions(decimal: true), - decoration: const InputDecoration( - hintText: 'Enter maxHeight if desired'), + keyboardType: TextInputType.numberWithOptions(decimal: true), + decoration: + InputDecoration(hintText: "Enter maxHeight if desired"), ), TextField( controller: qualityController, keyboardType: TextInputType.number, - decoration: const InputDecoration( - hintText: 'Enter quality if desired'), + decoration: + InputDecoration(hintText: "Enter quality if desired"), ), ], ), @@ -339,13 +368,13 @@ class _MyHomePageState extends State { TextButton( child: const Text('PICK'), onPressed: () { - final double? width = maxWidthController.text.isNotEmpty + double? width = maxWidthController.text.isNotEmpty ? double.parse(maxWidthController.text) : null; - final double? height = maxHeightController.text.isNotEmpty + double? height = maxHeightController.text.isNotEmpty ? double.parse(maxHeightController.text) : null; - final int? quality = qualityController.text.isNotEmpty + int? quality = qualityController.text.isNotEmpty ? int.parse(qualityController.text) : null; onPick(width, height, quality); @@ -357,11 +386,11 @@ class _MyHomePageState extends State { } } -typedef OnPickImageCallback = void Function( +typedef void OnPickImageCallback( double? maxWidth, double? maxHeight, int? quality); class AspectRatioVideo extends StatefulWidget { - const AspectRatioVideo(this.controller); + AspectRatioVideo(this.controller); final VideoPlayerController? controller; diff --git a/packages/image_picker/example/pubspec.yaml b/packages/image_picker/example/pubspec.yaml index fa49bd037..d730f0548 100644 --- a/packages/image_picker/example/pubspec.yaml +++ b/packages/image_picker/example/pubspec.yaml @@ -5,10 +5,10 @@ publish_to: "none" dependencies: flutter: sdk: flutter - image_picker: ^0.7.3 + image_picker: ^0.8.4 image_picker_tizen: path: ../ - video_player: ^2.0.2 + video_player: ^2.1.4 dev_dependencies: flutter_driver: diff --git a/packages/image_picker/example/test_driver/integration_test.dart b/packages/image_picker/example/test_driver/integration_test.dart index 0603ed6f7..b38629cca 100644 --- a/packages/image_picker/example/test_driver/integration_test.dart +++ b/packages/image_picker/example/test_driver/integration_test.dart @@ -1,5 +1,3 @@ -// @dart=2.9 - import 'package:integration_test/integration_test_driver.dart'; Future main() => integrationDriver(); diff --git a/packages/image_picker/example/tizen/Runner.csproj b/packages/image_picker/example/tizen/Runner.csproj index f8346a628..351a83987 100644 --- a/packages/image_picker/example/tizen/Runner.csproj +++ b/packages/image_picker/example/tizen/Runner.csproj @@ -1,4 +1,4 @@ - + Exe diff --git a/packages/image_picker/example/tizen/tizen-manifest.xml b/packages/image_picker/example/tizen/tizen-manifest.xml index 6ff0f3f2f..633582c96 100644 --- a/packages/image_picker/example/tizen/tizen-manifest.xml +++ b/packages/image_picker/example/tizen/tizen-manifest.xml @@ -1,11 +1,10 @@ - - + + ic_launcher.png - diff --git a/packages/image_picker/pubspec.yaml b/packages/image_picker/pubspec.yaml index cc6e4b6ac..d1a640aa0 100644 --- a/packages/image_picker/pubspec.yaml +++ b/packages/image_picker/pubspec.yaml @@ -3,7 +3,7 @@ description: Flutter plugin for selecting images from the Tizen image library, and taking new pictures with the camera. homepage: https://github.com/flutter-tizen/plugins repository: https://github.com/flutter-tizen/plugins/tree/master/packages/image_picker -version: 2.0.0 +version: 2.1.0 flutter: plugin: @@ -15,7 +15,7 @@ flutter: dependencies: flutter: sdk: flutter - image_picker_platform_interface: ^2.0.1 + image_picker_platform_interface: ^2.4.1 dev_dependencies: pedantic: ^1.10.0 diff --git a/packages/image_picker/tizen/src/image_picker_tizen_plugin.cc b/packages/image_picker/tizen/src/image_picker_tizen_plugin.cc index 6b43481cf..0c5481849 100644 --- a/packages/image_picker/tizen/src/image_picker_tizen_plugin.cc +++ b/packages/image_picker/tizen/src/image_picker_tizen_plugin.cc @@ -9,15 +9,11 @@ #include #include #include -#include - #ifndef TV_PROFILE #include #endif -#include #include -#include #include #include "image_resize.h" @@ -25,18 +21,11 @@ enum class ImageSource { // Opens up the device camera, letting the user to take a new picture. - CAMERA, + kCamera, // Opens the user's photo gallery. - GALLERY, + kGallery, }; -#define RET_IF_ERROR(ret) \ - if (ret != APP_CONTROL_ERROR_NONE) { \ - SendResultWithError(std::to_string(ret), get_error_message(ret)); \ - if (handle) app_control_destroy(handle); \ - return; \ - } - class ImagePickerTizenPlugin : public flutter::Plugin { public: static void RegisterWithRegistrar(flutter::PluginRegistrar *registrar) { @@ -55,7 +44,7 @@ class ImagePickerTizenPlugin : public flutter::Plugin { registrar->AddPlugin(std::move(plugin)); } - ImagePickerTizenPlugin() : mime_type_("") {} + ImagePickerTizenPlugin() {} virtual ~ImagePickerTizenPlugin() {} @@ -63,26 +52,26 @@ class ImagePickerTizenPlugin : public flutter::Plugin { void HandleMethodCall( const flutter::MethodCall &method_call, std::unique_ptr> result) { - LOG_DEBUG("method : %s", method_call.method_name().data()); + const auto &method_name = method_call.method_name(); + const auto &arguments = *method_call.arguments(); if (result_) { - SendResultWithError("already_active", "Cancelled by a second request"); + SendResultWithError("Already active", "Cancelled by a second request."); return; } - result_ = std::move(result); - const auto &arguments = *method_call.arguments(); + multi_image_ = method_name == "pickMultiImage"; - ImageSource source = ImageSource::GALLERY; - if (method_call.method_name().compare("pickImage") == 0) { + ImageSource source = ImageSource::kGallery; + if (method_name == "pickImage" || method_name == "pickMultiImage") { double width = 0.0, height = 0.0; - int quality = 0; + int32_t quality = 0; if (std::holds_alternative(arguments)) { flutter::EncodableMap values = std::get(arguments); auto s = values[flutter::EncodableValue("source")]; - if (std::holds_alternative(s)) { - source = (ImageSource)std::get(s); + if (std::holds_alternative(s)) { + source = (ImageSource)std::get(s); } auto w = values[flutter::EncodableValue("maxWidth")]; if (std::holds_alternative(w)) { @@ -93,44 +82,44 @@ class ImagePickerTizenPlugin : public flutter::Plugin { height = std::get(h); } auto q = values[flutter::EncodableValue("imageQuality")]; - if (std::holds_alternative(q)) { - quality = std::get(q); + if (std::holds_alternative(q)) { + quality = std::get(q); } image_resize_.SetSize((unsigned int)width, (unsigned int)height, quality); - } else { SendResultWithError("Invalid arguments"); return; } - if (source == ImageSource::CAMERA) { + if (source == ImageSource::kCamera) { // TODO: we need to check this feature after webcam is prepared SendResultWithError("Not supported on this device"); - } else if (source == ImageSource::GALLERY) { - CheckPermissionAndPickImage("image"); + } else if (source == ImageSource::kGallery) { + SetContentMimeType("image"); + CheckPermissionAndPickContent(); } else { SendResultWithError("Invalid image source"); } - - } else if (method_call.method_name().compare("pickVideo") == 0) { + } else if (method_name == "pickVideo") { if (std::holds_alternative(arguments)) { flutter::EncodableMap values = std::get(arguments); auto s = values[flutter::EncodableValue("source")]; - if (std::holds_alternative(s)) { - source = (ImageSource)std::get(s); + if (std::holds_alternative(s)) { + source = (ImageSource)std::get(s); } } else { SendResultWithError("Invalid arguments"); return; } - if (source == ImageSource::CAMERA) { + if (source == ImageSource::kCamera) { // TODO: we need to check this feature after webcam is prepared SendResultWithError("Not supported on this device"); - } else if (source == ImageSource::GALLERY) { - CheckPermissionAndPickImage("video"); + } else if (source == ImageSource::kGallery) { + SetContentMimeType("video"); + CheckPermissionAndPickContent(); } else { SendResultWithError("Invalid video source"); } @@ -140,7 +129,7 @@ class ImagePickerTizenPlugin : public flutter::Plugin { } } - void CheckPermissionAndPickImage(const std::string &mimeType) { + void CheckPermissionAndPickContent() { #ifndef TV_PROFILE const char *privilege = "http://tizen.org/privilege/mediastorage"; @@ -151,131 +140,157 @@ class ImagePickerTizenPlugin : public flutter::Plugin { } else { switch (permission) { case PRIVACY_PRIVILEGE_MANAGER_CHECK_RESULT_ALLOW: - LOG_INFO("ppm_check_permission success! [%d]", (int)permission); - SetContentMimeType(mimeType); + LOG_INFO("ppm_check_permission success!"); PickContent(); return; case PRIVACY_PRIVILEGE_MANAGER_CHECK_RESULT_ASK: - ret = ppm_request_permission(privilege, AppRequestResponseCb, this); + ret = ppm_request_permission( + privilege, + [](ppm_call_cause_e cause, ppm_request_result_e result, + const char *privilege, void *data) -> void { + auto *plugin = (ImagePickerTizenPlugin *)data; + assert(plugin); + + if (cause == PRIVACY_PRIVILEGE_MANAGER_CALL_CAUSE_ERROR) { + LOG_ERROR("ppm_request_permission error! [%d]", result); + plugin->SendResultWithError("Permission denied"); + return; + } + if (result != + PRIVACY_PRIVILEGE_MANAGER_REQUEST_RESULT_ALLOW_FOREVER) { + LOG_ERROR("ppm_request_permission deny! [%d]", result); + plugin->SendResultWithError("Permission denied"); + return; + } + + plugin->PickContent(); + }, + this); if (ret != PRIVACY_PRIVILEGE_MANAGER_ERROR_NONE) { LOG_ERROR("ppm_request_permission fail! [%d]", ret); break; } return; default: - LOG_ERROR("ppm_check_permission deny! [%d]", (int)permission); + LOG_ERROR("ppm_check_permission deny!"); break; } } - SendResultWithError("Invalid permission"); + SendResultWithError("Permission denied"); #else - SetContentMimeType(mimeType); PickContent(); #endif } void PickContent() { - if (mime_type_.size() == 0) return; - app_control_h handle = nullptr; +#define RET_IF_ERROR(ret) \ + if (ret != APP_CONTROL_ERROR_NONE) { \ + SendResultWithError(std::to_string(ret), get_error_message(ret)); \ + if (handle) { \ + app_control_destroy(handle); \ + } \ + return; \ + } int ret = app_control_create(&handle); RET_IF_ERROR(ret); ret = app_control_set_operation(handle, APP_CONTROL_OPERATION_PICK); RET_IF_ERROR(ret); + ret = app_control_add_extra_data(handle, APP_CONTROL_DATA_SELECTION_MODE, + multi_image_ ? "multiple" : "single"); + RET_IF_ERROR(ret); + ret = app_control_set_mime(handle, mime_type_.c_str()); - mime_type_ = ""; RET_IF_ERROR(ret); - ret = app_control_send_launch_request(handle, PickImageReplyCb, this); + ret = app_control_send_launch_request(handle, PickImageReplyCallback, this); RET_IF_ERROR(ret); +#undef RET_IF_ERROR app_control_destroy(handle); } -#ifndef TV_PROFILE - static void AppRequestResponseCb(ppm_call_cause_e cause, - ppm_request_result_e result, - const char *privilege, void *data) { - ImagePickerTizenPlugin *plugin = (ImagePickerTizenPlugin *)data; - assert(plugin); - - if (cause == PRIVACY_PRIVILEGE_MANAGER_CALL_CAUSE_ERROR) { - LOG_ERROR("app_request_response_cb failed! [%d]", result); - plugin->SendResultWithError("Invalid permission"); - return; - } + static void PickImageReplyCallback(app_control_h request, app_control_h reply, + app_control_result_e result, + void *user_data) { + LOG_INFO("PickImageReplyCallback called: %d", (int)result); - plugin->PickContent(); - } -#endif - - static void PickImageReplyCb(app_control_h request, app_control_h reply, - app_control_result_e result, void *user_data) { - LOG_INFO("PickImageReplyCb called: %d", (int)result); - - ImagePickerTizenPlugin *plugin = (ImagePickerTizenPlugin *)user_data; + auto *plugin = (ImagePickerTizenPlugin *)user_data; assert(plugin != nullptr); assert(plugin->result_ != nullptr); if (result != APP_CONTROL_RESULT_SUCCEEDED) { - plugin->SendResultWithError("Not Found Images"); + plugin->SendResultWithError("Operation failed"); return; } - char **value = nullptr; + char **values = nullptr; int count = 0; int ret = app_control_get_extra_data_array(reply, APP_CONTROL_DATA_SELECTED, - &value, &count); + &values, &count); if (ret != APP_CONTROL_ERROR_NONE) { plugin->SendResultWithError(std::to_string(ret), get_error_message(ret)); return; } - if (count == 1) { - LOG_INFO("image path: %s", value[0]); - std::string src_path = value[0]; - std::string dst_path; - if (plugin->image_resize_.Resize(src_path, dst_path)) { - plugin->SendResultWithSuccess(dst_path); - } else { - plugin->SendResultWithSuccess(src_path); + if (count == 0) { + plugin->SendResultWithError("No file selected"); + } else if (plugin->multi_image_) { + flutter::EncodableList paths; + for (int i = 0; i < count; i++) { + std::string source_path = values[i]; + std::string dest_path; + if (plugin->image_resize_.Resize(source_path, dest_path)) { + paths.push_back(flutter::EncodableValue(dest_path)); + } else { + paths.push_back(flutter::EncodableValue(source_path)); + } + free(values[i]); } - free(value[0]); + plugin->SendResultWithSuccess(flutter::EncodableValue(paths)); } else { - plugin->SendResultWithError("Not Found Images"); + std::string source_path = values[0]; + std::string dest_path; + if (plugin->image_resize_.Resize(source_path, dest_path)) { + plugin->SendResultWithSuccess(flutter::EncodableValue(dest_path)); + } else { + plugin->SendResultWithSuccess(flutter::EncodableValue(source_path)); + } + free(values[0]); } - if (value) { - free(value); + if (values) { + free(values); } } - void SendResultWithSuccess(std::string imagePath) { + void SendResultWithSuccess(const flutter::EncodableValue &result) { if (result_ == nullptr) { return; } - result_->Success(flutter::EncodableValue(imagePath)); + result_->Success(result); result_ = nullptr; } - void SendResultWithError(std::string errorCode, - std::string errorMessage = "") { + void SendResultWithError(const std::string &error_code, + const std::string &error_message = "") { if (result_ == nullptr) { return; } - result_->Error(errorCode, errorMessage); + result_->Error(error_code, error_message); result_ = nullptr; } - void SetContentMimeType(const std::string &mimeType) { - mime_type_ = mimeType + "/*"; + void SetContentMimeType(const std::string &mime_type) { + mime_type_ = mime_type + "/*"; } ImageResize image_resize_; std::unique_ptr> result_; std::string mime_type_; + bool multi_image_ = false; }; void ImagePickerTizenPluginRegisterWithRegistrar( diff --git a/tools/recipe.yaml b/tools/recipe.yaml index b27d8061e..d27f08ac9 100644 --- a/tools/recipe.yaml +++ b/tools/recipe.yaml @@ -7,7 +7,7 @@ plugins: flutter_tts: ["wearable-5.5", "tv-6.0"] geolocator: ["wearable-5.5"] google_maps_flutter: [] - image_picker: [] + image_picker: ["wearable-5.5"] integration_test: ["wearable-5.5", "tv-6.0"] messageport: ["wearable-5.5", "tv-6.0"] network_info_plus: []