diff --git a/example/android/app/build.gradle b/example/android/app/build.gradle index 1169101..1a6a6b8 100644 --- a/example/android/app/build.gradle +++ b/example/android/app/build.gradle @@ -26,7 +26,7 @@ apply plugin: 'kotlin-android' apply from: "$flutterRoot/packages/flutter_tools/gradle/flutter.gradle" android { - compileSdkVersion 30 + compileSdkVersion 31 sourceSets { main.java.srcDirs += 'src/main/kotlin' diff --git a/example/android/app/src/debug/AndroidManifest.xml b/example/android/app/src/debug/AndroidManifest.xml index 1a7c525..75e0411 100644 --- a/example/android/app/src/debug/AndroidManifest.xml +++ b/example/android/app/src/debug/AndroidManifest.xml @@ -4,4 +4,5 @@ to allow setting breakpoints, to provide hot reload, etc. --> + diff --git a/example/android/app/src/main/AndroidManifest.xml b/example/android/app/src/main/AndroidManifest.xml index 98989a8..ac82a25 100644 --- a/example/android/app/src/main/AndroidManifest.xml +++ b/example/android/app/src/main/AndroidManifest.xml @@ -14,10 +14,11 @@ FlutterApplication and put your custom class here. --> + { backgroundColor: MaterialStateProperty.all(Colors.blue), ), onPressed: _takePhoto, - child: Text(firstButtonText, - style: TextStyle( - fontSize: textSize, color: Colors.white)), + child: Text( + firstButtonText, + style: TextStyle( + fontSize: textSize, + color: Colors.white, + ), + ), ), ), ), @@ -61,9 +65,13 @@ class _MyAppState extends State { backgroundColor: MaterialStateProperty.all(Colors.white), ), onPressed: _recordVideo, - child: Text(secondButtonText, - style: TextStyle( - fontSize: textSize, color: Colors.blueGrey)), + child: Text( + secondButtonText, + style: TextStyle( + fontSize: textSize, + color: Colors.blueGrey, + ), + ), ), )), flex: 1, @@ -76,39 +84,36 @@ class _MyAppState extends State { } void _takePhoto() async { - ImagePicker() - .getImage(source: ImageSource.camera) - .then((PickedFile recordedImage) { - if (recordedImage != null && recordedImage.path != null) { + final recordedImage = + await ImagePicker().pickImage(source: ImageSource.camera); + if (recordedImage != null && recordedImage.path != null) { + setState(() { + firstButtonText = 'saving in progress...'; + }); + GallerySaver.saveImage(recordedImage.path, albumName: albumName) + .then((bool success) { setState(() { - firstButtonText = 'saving in progress...'; - }); - GallerySaver.saveImage(recordedImage.path, albumName: albumName) - .then((bool success) { - setState(() { - firstButtonText = 'image saved!'; - }); + firstButtonText = 'image saved!'; }); - } - }); + }); + } } void _recordVideo() async { - ImagePicker() - .getVideo(source: ImageSource.camera) - .then((PickedFile recordedVideo) { - if (recordedVideo != null && recordedVideo.path != null) { + final recordedVideo = + await ImagePicker().pickVideo(source: ImageSource.camera); + + if (recordedVideo != null && recordedVideo.path != null) { + setState(() { + secondButtonText = 'saving in progress...'; + }); + GallerySaver.saveVideo(recordedVideo.path, albumName: albumName) + .then((bool success) { setState(() { - secondButtonText = 'saving in progress...'; + secondButtonText = 'video saved!'; }); - GallerySaver.saveVideo(recordedVideo.path, albumName: albumName) - .then((bool success) { - setState(() { - secondButtonText = 'video saved!'; - }); - }); - } - }); + }); + } } // ignore: unused_element @@ -173,6 +178,13 @@ class _ScreenshotWidgetState extends State { //extract bytes final RenderRepaintBoundary boundary = _globalKey.currentContext.findRenderObject(); + + // if it needs repaint, we paint it. + if (boundary.debugNeedsPaint) { + Timer(Duration(seconds: 1), () => _saveScreenshot()); + return null; + } + final ui.Image image = await boundary.toImage(pixelRatio: 3.0); final ByteData byteData = await image.toByteData(format: ui.ImageByteFormat.png); diff --git a/example/pubspec.lock b/example/pubspec.lock index 71758ec..e937486 100644 --- a/example/pubspec.lock +++ b/example/pubspec.lock @@ -7,7 +7,7 @@ packages: name: async url: "https://pub.dartlang.org" source: hosted - version: "2.8.1" + version: "2.8.2" boolean_selector: dependency: transitive description: @@ -21,7 +21,7 @@ packages: name: characters url: "https://pub.dartlang.org" source: hosted - version: "1.1.0" + version: "1.2.0" charcode: dependency: transitive description: @@ -49,7 +49,7 @@ packages: name: cross_file url: "https://pub.dartlang.org" source: hosted - version: "0.3.1+5" + version: "0.3.2" fake_async: dependency: transitive description: @@ -63,14 +63,14 @@ packages: name: ffi url: "https://pub.dartlang.org" source: hosted - version: "1.0.0" + version: "1.1.2" file: dependency: transitive description: name: file url: "https://pub.dartlang.org" source: hosted - version: "6.1.0" + version: "6.1.2" flutter: dependency: "direct main" description: flutter @@ -82,7 +82,7 @@ packages: name: flutter_plugin_android_lifecycle url: "https://pub.dartlang.org" source: hosted - version: "2.0.3" + version: "2.0.5" flutter_test: dependency: "direct dev" description: flutter @@ -99,14 +99,14 @@ packages: path: ".." relative: true source: path - version: "2.1.3" + version: "2.3.2" http: dependency: "direct main" description: name: http url: "https://pub.dartlang.org" source: hosted - version: "0.13.3" + version: "0.13.4" http_parser: dependency: transitive description: @@ -120,21 +120,21 @@ packages: name: image_picker url: "https://pub.dartlang.org" source: hosted - version: "0.8.4+2" + version: "0.8.4+10" image_picker_for_web: dependency: transitive description: name: image_picker_for_web url: "https://pub.dartlang.org" source: hosted - version: "2.1.3" + version: "2.1.6" image_picker_platform_interface: dependency: transitive description: name: image_picker_platform_interface url: "https://pub.dartlang.org" source: hosted - version: "2.4.1" + version: "2.4.4" js: dependency: transitive description: @@ -148,7 +148,14 @@ packages: name: matcher url: "https://pub.dartlang.org" source: hosted - version: "0.12.10" + version: "0.12.11" + material_color_utilities: + dependency: transitive + description: + name: material_color_utilities + url: "https://pub.dartlang.org" + source: hosted + version: "0.1.3" meta: dependency: transitive description: @@ -169,63 +176,70 @@ packages: name: path_provider url: "https://pub.dartlang.org" source: hosted - version: "2.0.2" + version: "2.0.9" + path_provider_android: + dependency: transitive + description: + name: path_provider_android + url: "https://pub.dartlang.org" + source: hosted + version: "2.0.12" + path_provider_ios: + dependency: transitive + description: + name: path_provider_ios + url: "https://pub.dartlang.org" + source: hosted + version: "2.0.8" path_provider_linux: dependency: transitive description: name: path_provider_linux url: "https://pub.dartlang.org" source: hosted - version: "2.0.0" + version: "2.1.5" path_provider_macos: dependency: transitive description: name: path_provider_macos url: "https://pub.dartlang.org" source: hosted - version: "2.0.0" + version: "2.0.5" path_provider_platform_interface: dependency: transitive description: name: path_provider_platform_interface url: "https://pub.dartlang.org" source: hosted - version: "2.0.1" + version: "2.0.3" path_provider_windows: dependency: transitive description: name: path_provider_windows url: "https://pub.dartlang.org" source: hosted - version: "2.0.0" - pedantic: - dependency: transitive - description: - name: pedantic - url: "https://pub.dartlang.org" - source: hosted - version: "1.11.0" + version: "2.0.5" platform: dependency: transitive description: name: platform url: "https://pub.dartlang.org" source: hosted - version: "3.0.0" + version: "3.1.0" plugin_platform_interface: dependency: transitive description: name: plugin_platform_interface url: "https://pub.dartlang.org" source: hosted - version: "2.0.0" + version: "2.1.2" process: dependency: transitive description: name: process url: "https://pub.dartlang.org" source: hosted - version: "4.1.0" + version: "4.2.4" sky_engine: dependency: transitive description: flutter @@ -272,7 +286,7 @@ packages: name: test_api url: "https://pub.dartlang.org" source: hosted - version: "0.4.2" + version: "0.4.8" typed_data: dependency: transitive description: @@ -286,21 +300,21 @@ packages: name: vector_math url: "https://pub.dartlang.org" source: hosted - version: "2.1.0" + version: "2.1.1" win32: dependency: transitive description: name: win32 url: "https://pub.dartlang.org" source: hosted - version: "2.0.4" + version: "2.4.1" xdg_directories: dependency: transitive description: name: xdg_directories url: "https://pub.dartlang.org" source: hosted - version: "0.2.0" + version: "0.2.0+1" sdks: - dart: ">=2.14.0 <3.0.0" - flutter: ">=2.5.0" + dart: ">=2.15.0 <3.0.0" + flutter: ">=2.8.0" diff --git a/lib/gallery_saver.dart b/lib/gallery_saver.dart index e7b9a0e..453d265 100644 --- a/lib/gallery_saver.dart +++ b/lib/gallery_saver.dart @@ -1,4 +1,5 @@ import 'dart:async'; +import 'dart:developer'; import 'dart:io'; import 'package:flutter/services.dart'; @@ -24,17 +25,15 @@ class GallerySaver { bool toDcim = false, Map? headers, }) async { + assert(path.isNotEmpty, pleaseProvidePath); + assert(isVideo(path), fileIsNotVideo); + File? tempFile; - if (path.isEmpty) { - throw ArgumentError(pleaseProvidePath); - } - if (!isVideo(path)) { - throw ArgumentError(fileIsNotVideo); - } if (!isLocalFilePath(path)) { tempFile = await _downloadFile(path, headers: headers); path = tempFile.path; } + bool? result = await _channel.invokeMethod( methodSaveVideo, {'path': path, 'albumName': albumName, 'toDcim': toDcim}, @@ -52,13 +51,10 @@ class GallerySaver { bool toDcim = false, Map? headers, }) async { + assert(path.isNotEmpty, pleaseProvidePath); + assert(isImage(path), fileIsNotImage); + File? tempFile; - if (path.isEmpty) { - throw ArgumentError(pleaseProvidePath); - } - if (!isImage(path)) { - throw ArgumentError(fileIsNotImage); - } if (!isLocalFilePath(path)) { tempFile = await _downloadFile(path, headers: headers); path = tempFile.path; @@ -75,10 +71,10 @@ class GallerySaver { return result; } - static Future _downloadFile(String url, - {Map? headers}) async { - print(url); - print(headers); + static Future _downloadFile( + String url, { + Map? headers, + }) async { http.Client _client = new http.Client(); var req = await _client.get(Uri.parse(url), headers: headers); if (req.statusCode >= 400) { @@ -86,10 +82,25 @@ class GallerySaver { } var bytes = req.bodyBytes; String dir = (await getTemporaryDirectory()).path; - File file = new File('$dir/${basename(url)}'); + String fileName = _shortenFileName(url); + + File file = new File('$dir/$fileName'); + await file.writeAsBytes(bytes); - print('File size:${await file.length()}'); - print(file.path); + log('Saving $fileName, ${await file.length() ~/ 1024} Kb', + name: 'GallerySaver'); + return file; } + + static String _shortenFileName(String url) { + String fileName = basename(url); + final len = fileName.length; + + if (len > 255) { + fileName = fileName.substring(len - 255, len); + } + + return fileName; + } } diff --git a/pubspec.lock b/pubspec.lock index b40bd22..9d038db 100644 --- a/pubspec.lock +++ b/pubspec.lock @@ -7,7 +7,7 @@ packages: name: async url: "https://pub.dartlang.org" source: hosted - version: "2.8.1" + version: "2.8.2" boolean_selector: dependency: transitive description: @@ -21,7 +21,7 @@ packages: name: characters url: "https://pub.dartlang.org" source: hosted - version: "1.1.0" + version: "1.2.0" charcode: dependency: transitive description: @@ -80,7 +80,7 @@ packages: name: http url: "https://pub.dartlang.org" source: hosted - version: "0.13.3" + version: "0.13.4" http_parser: dependency: transitive description: @@ -94,7 +94,14 @@ packages: name: matcher url: "https://pub.dartlang.org" source: hosted - version: "0.12.10" + version: "0.12.11" + material_color_utilities: + dependency: transitive + description: + name: material_color_utilities + url: "https://pub.dartlang.org" + source: hosted + version: "0.1.3" meta: dependency: transitive description: @@ -115,63 +122,70 @@ packages: name: path_provider url: "https://pub.dartlang.org" source: hosted - version: "2.0.2" + version: "2.0.9" + path_provider_android: + dependency: transitive + description: + name: path_provider_android + url: "https://pub.dartlang.org" + source: hosted + version: "2.0.12" + path_provider_ios: + dependency: transitive + description: + name: path_provider_ios + url: "https://pub.dartlang.org" + source: hosted + version: "2.0.8" path_provider_linux: dependency: transitive description: name: path_provider_linux url: "https://pub.dartlang.org" source: hosted - version: "2.0.0" + version: "2.1.5" path_provider_macos: dependency: transitive description: name: path_provider_macos url: "https://pub.dartlang.org" source: hosted - version: "2.0.0" + version: "2.0.5" path_provider_platform_interface: dependency: transitive description: name: path_provider_platform_interface url: "https://pub.dartlang.org" source: hosted - version: "2.0.1" + version: "2.0.3" path_provider_windows: dependency: transitive description: name: path_provider_windows url: "https://pub.dartlang.org" source: hosted - version: "2.0.1" - pedantic: - dependency: transitive - description: - name: pedantic - url: "https://pub.dartlang.org" - source: hosted - version: "1.11.1" + version: "2.0.5" platform: dependency: transitive description: name: platform url: "https://pub.dartlang.org" source: hosted - version: "3.0.0" + version: "3.1.0" plugin_platform_interface: dependency: transitive description: name: plugin_platform_interface url: "https://pub.dartlang.org" source: hosted - version: "2.0.0" + version: "2.1.2" process: dependency: transitive description: name: process url: "https://pub.dartlang.org" source: hosted - version: "4.2.1" + version: "4.2.4" sky_engine: dependency: transitive description: flutter @@ -218,7 +232,7 @@ packages: name: test_api url: "https://pub.dartlang.org" source: hosted - version: "0.4.2" + version: "0.4.8" typed_data: dependency: transitive description: @@ -232,21 +246,21 @@ packages: name: vector_math url: "https://pub.dartlang.org" source: hosted - version: "2.1.0" + version: "2.1.1" win32: dependency: transitive description: name: win32 url: "https://pub.dartlang.org" source: hosted - version: "2.0.5" + version: "2.4.1" xdg_directories: dependency: transitive description: name: xdg_directories url: "https://pub.dartlang.org" source: hosted - version: "0.2.0" + version: "0.2.0+1" sdks: - dart: ">=2.12.0 <3.0.0" - flutter: ">=1.20.0" + dart: ">=2.15.0 <3.0.0" + flutter: ">=2.8.0"