diff --git a/packages/image_picker/image_picker/CHANGELOG.md b/packages/image_picker/image_picker/CHANGELOG.md index d0a667bf01..9e9d3ec6bf 100644 --- a/packages/image_picker/image_picker/CHANGELOG.md +++ b/packages/image_picker/image_picker/CHANGELOG.md @@ -1,6 +1,16 @@ +## 1.0.0 + +* **BREAKING CHANGE**: Removes the deprecated `get*` methods. Clients who have + not already done so will need to migrate to the `pick*` versions that use + `XFile` rather than `PickedFile` for return values. + * As this is the only change, we encourage authors of published packages + that depend on `image_picker` to consider using a constraint of + `'>=0.8.9 <2.0.0'` rather than `^1.0.0` when updating dependencies, to + avoid conflicts with packages that have not yet updated. + ## 0.8.9 -* Adds `getMedia` and `getMultipleMedia` methods. +* Adds `pickMedia` and `pickMultipleMedia` methods. ## 0.8.8 diff --git a/packages/image_picker/image_picker/README.md b/packages/image_picker/image_picker/README.md index 33ecc2edee..5e2306cd40 100755 --- a/packages/image_picker/image_picker/README.md +++ b/packages/image_picker/image_picker/README.md @@ -186,15 +186,13 @@ final XFile? media = await picker.pickMedia(); final List medias = await picker.pickMultipleMedia(); ``` -## Migrating to 0.8.2+ +## Migrating to 1.0 -Starting with version **0.8.2** of the image_picker plugin, new methods have -been added for picking files that return `XFile` instances (from the +Starting with version 0.8.2 of the image_picker plugin, new methods were +added that return `XFile` instances (from the [cross_file](https://pub.dev/packages/cross_file) package) rather than the -plugin's own `PickedFile` instances. While the previous methods still exist, it -is already recommended to start migrating over to their new equivalents. -Eventually, `PickedFile` and the methods that return instances of it will be -deprecated and removed. +plugin's own `PickedFile` instances. The previous methods were supported through +0.8.9, and removed in 1.0.0. #### Call the new methods diff --git a/packages/image_picker/image_picker/lib/image_picker.dart b/packages/image_picker/image_picker/lib/image_picker.dart index a558dbd7d5..b613ed8d35 100755 --- a/packages/image_picker/image_picker/lib/image_picker.dart +++ b/packages/image_picker/image_picker/lib/image_picker.dart @@ -25,150 +25,10 @@ class ImagePicker { @visibleForTesting static ImagePickerPlatform get platform => ImagePickerPlatform.instance; - /// Returns a [PickedFile] object wrapping the image that was picked. - /// - /// The returned [PickedFile] is intended to be used within a single app session. Do not save the file path and use it across sessions. - /// - /// The `source` argument controls where the image comes from. This can - /// be either [ImageSource.camera] or [ImageSource.gallery]. - /// - /// Where iOS supports HEIC images, Android 8 and below doesn't. Android 9 and above only support HEIC images if used - /// in addition to a size modification, of which the usage is explained below. - /// - /// If specified, the image will be at most `maxWidth` wide and - /// `maxHeight` tall. Otherwise the image will be returned at it's - /// original width and height. - /// The `imageQuality` argument modifies the quality of the image, ranging from 0-100 - /// where 100 is the original/max quality. If `imageQuality` is null, the image with - /// the original quality will be returned. Compression is only supported for certain - /// image types such as JPEG and on Android PNG and WebP, too. If compression is not supported for the image that is picked, - /// a warning message will be logged. - /// - /// Use `preferredCameraDevice` to specify the camera to use when the `source` is [ImageSource.camera]. - /// The `preferredCameraDevice` is ignored when `source` is [ImageSource.gallery]. It is also ignored if the chosen camera is not supported on the device. - /// Defaults to [CameraDevice.rear]. Note that Android has no documented parameter for an intent to specify if - /// the front or rear camera should be opened, this function is not guaranteed - /// to work on an Android device. - /// - /// In Android, the MainActivity can be destroyed for various reasons. If that happens, the result will be lost - /// in this call. You can then call [getLostData] when your app relaunches to retrieve the lost data. - /// - /// See also [getMultiImage] to allow users to select multiple images at once. - /// - /// The method could throw [PlatformException] if the app does not have permission to access - /// the camera or photos gallery, no camera is available, plugin is already in use, - /// temporary file could not be created (iOS only), plugin activity could not - /// be allocated (Android only) or due to an unknown error. - @Deprecated('Switch to using pickImage instead') - Future getImage({ - required ImageSource source, - double? maxWidth, - double? maxHeight, - int? imageQuality, - CameraDevice preferredCameraDevice = CameraDevice.rear, - }) { - return platform.pickImage( - source: source, - maxWidth: maxWidth, - maxHeight: maxHeight, - imageQuality: imageQuality, - preferredCameraDevice: preferredCameraDevice, - ); - } - - /// Returns a [List] object wrapping the images that were picked. - /// - /// The returned [List] is intended to be used within a single app session. Do not save the file path and use it across sessions. - /// - /// Where iOS supports HEIC images, Android 8 and below doesn't. Android 9 and above only support HEIC images if used - /// in addition to a size modification, of which the usage is explained below. - /// - /// This method is not supported in iOS versions lower than 14. - /// - /// If specified, the images will be at most `maxWidth` wide and - /// `maxHeight` tall. Otherwise the images will be returned at it's - /// original width and height. - /// The `imageQuality` argument modifies the quality of the images, ranging from 0-100 - /// where 100 is the original/max quality. If `imageQuality` is null, the images with - /// the original quality will be returned. Compression is only supported for certain - /// image types such as JPEG and on Android PNG and WebP, too. If compression is not supported for the image that is picked, - /// a warning message will be logged. - /// - /// The method could throw [PlatformException] if the app does not have permission to access - /// the camera or photos gallery, no camera is available, plugin is already in use, - /// temporary file could not be created (iOS only), plugin activity could not - /// be allocated (Android only) or due to an unknown error. - /// - /// See also [getImage] to allow users to only pick a single image. - @Deprecated('Switch to using pickMultiImage instead') - Future?> getMultiImage({ - double? maxWidth, - double? maxHeight, - int? imageQuality, - }) { - return platform.pickMultiImage( - maxWidth: maxWidth, - maxHeight: maxHeight, - imageQuality: imageQuality, - ); - } - - /// Returns a [PickedFile] object wrapping the video that was picked. - /// - /// The returned [PickedFile] is intended to be used within a single app session. Do not save the file path and use it across sessions. - /// - /// The [source] argument controls where the video comes from. This can - /// be either [ImageSource.camera] or [ImageSource.gallery]. - /// - /// The [maxDuration] argument specifies the maximum duration of the captured video. If no [maxDuration] is specified, - /// the maximum duration will be infinite. - /// - /// Use `preferredCameraDevice` to specify the camera to use when the `source` is [ImageSource.camera]. - /// The `preferredCameraDevice` is ignored when `source` is [ImageSource.gallery]. It is also ignored if the chosen camera is not supported on the device. - /// Defaults to [CameraDevice.rear]. - /// - /// In Android, the MainActivity can be destroyed for various reasons. If that happens, the result will be lost - /// in this call. You can then call [getLostData] when your app relaunches to retrieve the lost data. - /// - /// The method could throw [PlatformException] if the app does not have permission to access - /// the camera or photos gallery, no camera is available, plugin is already in use, - /// temporary file could not be created and video could not be cached (iOS only), - /// plugin activity could not be allocated (Android only) or due to an unknown error. - /// - @Deprecated('Switch to using pickVideo instead') - Future getVideo({ - required ImageSource source, - CameraDevice preferredCameraDevice = CameraDevice.rear, - Duration? maxDuration, - }) { - return platform.pickVideo( - source: source, - preferredCameraDevice: preferredCameraDevice, - maxDuration: maxDuration, - ); - } - - /// Retrieve the lost [PickedFile] when [selectImage] or [selectVideo] failed because the MainActivity is destroyed. (Android only) - /// - /// Image or video can be lost if the MainActivity is destroyed. And there is no guarantee that the MainActivity is always alive. - /// Call this method to retrieve the lost data and process the data according to your app's business logic. - /// - /// Returns a [LostData] object if successfully retrieved the lost data. The [LostData] object can represent either a - /// successful image/video selection, or a failure. - /// - /// Calling this on a non-Android platform will throw [UnimplementedError] exception. - /// - /// See also: - /// * [LostData], for what's included in the response. - /// * [Android Activity Lifecycle](https://developer.android.com/reference/android/app/Activity.html), for more information on MainActivity destruction. - @Deprecated('Switch to using retrieveLostData instead') - Future getLostData() { - return platform.retrieveLostData(); - } - /// Returns an [XFile] object wrapping the image that was picked. /// - /// The returned [XFile] is intended to be used within a single app session. Do not save the file path and use it across sessions. + /// The returned [XFile] is intended to be used within a single app session. + /// Do not save the file path and use it across sessions. /// /// The `source` argument controls where the image comes from. This can /// be either [ImageSource.camera] or [ImageSource.gallery]. @@ -234,7 +94,8 @@ class ImagePicker { /// Returns a [List] object wrapping the images that were picked. /// - /// The returned [List] is intended to be used within a single app session. Do not save the file path and use it across sessions. + /// The returned [List] is intended to be used within a single app session. + /// Do not save the file path and use it across sessions. /// /// Where iOS supports HEIC images, Android 8 and below doesn't. Android 9 and above only support HEIC images if used /// in addition to a size modification, of which the usage is explained below. @@ -284,7 +145,8 @@ class ImagePicker { } /// Returns an [XFile] of the image or video that was picked. - /// The image or videos can only come from the gallery. + /// + /// The image or video can only come from the gallery. /// /// The returned [XFile] is intended to be used within a single app session. /// Do not save the file path and use it across sessions. @@ -339,6 +201,7 @@ class ImagePicker { } /// Returns a [List] with the images and/or videos that were picked. + /// /// The images and videos come from the gallery. /// /// The returned [List] is intended to be used within a single app session. diff --git a/packages/image_picker/image_picker/pubspec.yaml b/packages/image_picker/image_picker/pubspec.yaml index 69e255c65b..310dc93992 100755 --- a/packages/image_picker/image_picker/pubspec.yaml +++ b/packages/image_picker/image_picker/pubspec.yaml @@ -3,7 +3,7 @@ description: Flutter plugin for selecting images from the Android and iOS image library, and taking new pictures with the camera. repository: https://github.com/flutter/packages/tree/main/packages/image_picker/image_picker issue_tracker: https://github.com/flutter/flutter/issues?q=is%3Aissue+is%3Aopen+label%3A%22p%3A+image_picker%22 -version: 0.8.9 +version: 1.0.0 environment: sdk: ">=2.18.0 <4.0.0" diff --git a/packages/image_picker/image_picker/test/image_picker_deprecated_test.dart b/packages/image_picker/image_picker/test/image_picker_deprecated_test.dart deleted file mode 100644 index 9ca4d9c977..0000000000 --- a/packages/image_picker/image_picker/test/image_picker_deprecated_test.dart +++ /dev/null @@ -1,285 +0,0 @@ -// Copyright 2013 The Flutter Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -// ignore_for_file: deprecated_member_use_from_same_package - -// This file preserves the tests for the deprecated methods as they were before -// the migration. See image_picker_test.dart for the current tests. - -import 'package:flutter/services.dart'; -import 'package:flutter_test/flutter_test.dart'; -import 'package:image_picker/image_picker.dart'; -import 'package:image_picker_platform_interface/image_picker_platform_interface.dart'; -import 'package:mockito/mockito.dart'; -import 'package:plugin_platform_interface/plugin_platform_interface.dart'; - -import 'image_picker_test.mocks.dart' as base_mock; - -// Add the mixin to make the platform interface accept the mock. -class MockImagePickerPlatform extends base_mock.MockImagePickerPlatform - with MockPlatformInterfaceMixin {} - -void main() { - group('ImagePicker', () { - late MockImagePickerPlatform mockPlatform; - - setUp(() { - mockPlatform = MockImagePickerPlatform(); - ImagePickerPlatform.instance = mockPlatform; - }); - - group('#Single image/video', () { - setUp(() { - when(mockPlatform.pickImage( - source: anyNamed('source'), - maxWidth: anyNamed('maxWidth'), - maxHeight: anyNamed('maxHeight'), - imageQuality: anyNamed('imageQuality'), - preferredCameraDevice: anyNamed('preferredCameraDevice'))) - .thenAnswer((Invocation _) async => null); - }); - - group('#pickImage', () { - test('passes the image source argument correctly', () async { - final ImagePicker picker = ImagePicker(); - await picker.getImage(source: ImageSource.camera); - await picker.getImage(source: ImageSource.gallery); - - verifyInOrder([ - mockPlatform.pickImage(source: ImageSource.camera), - mockPlatform.pickImage(source: ImageSource.gallery), - ]); - }); - - test('passes the width and height arguments correctly', () async { - final ImagePicker picker = ImagePicker(); - await picker.getImage(source: ImageSource.camera); - await picker.getImage( - source: ImageSource.camera, - maxWidth: 10.0, - ); - await picker.getImage( - source: ImageSource.camera, - maxHeight: 10.0, - ); - await picker.getImage( - source: ImageSource.camera, - maxWidth: 10.0, - maxHeight: 20.0, - ); - await picker.getImage( - source: ImageSource.camera, maxWidth: 10.0, imageQuality: 70); - await picker.getImage( - source: ImageSource.camera, maxHeight: 10.0, imageQuality: 70); - await picker.getImage( - source: ImageSource.camera, - maxWidth: 10.0, - maxHeight: 20.0, - imageQuality: 70); - - verifyInOrder([ - mockPlatform.pickImage(source: ImageSource.camera), - mockPlatform.pickImage(source: ImageSource.camera, maxWidth: 10.0), - mockPlatform.pickImage(source: ImageSource.camera, maxHeight: 10.0), - mockPlatform.pickImage( - source: ImageSource.camera, - maxWidth: 10.0, - maxHeight: 20.0, - ), - mockPlatform.pickImage( - source: ImageSource.camera, - maxWidth: 10.0, - imageQuality: 70, - ), - mockPlatform.pickImage( - source: ImageSource.camera, - maxHeight: 10.0, - imageQuality: 70, - ), - mockPlatform.pickImage( - source: ImageSource.camera, - maxWidth: 10.0, - maxHeight: 20.0, - imageQuality: 70, - ), - ]); - }); - - test('handles a null image file response gracefully', () async { - final ImagePicker picker = ImagePicker(); - - expect(await picker.getImage(source: ImageSource.gallery), isNull); - expect(await picker.getImage(source: ImageSource.camera), isNull); - }); - - test('camera position defaults to back', () async { - final ImagePicker picker = ImagePicker(); - await picker.getImage(source: ImageSource.camera); - - verify(mockPlatform.pickImage(source: ImageSource.camera)); - }); - - test('camera position can set to front', () async { - final ImagePicker picker = ImagePicker(); - await picker.getImage( - source: ImageSource.camera, - preferredCameraDevice: CameraDevice.front); - - verify(mockPlatform.pickImage( - source: ImageSource.camera, - preferredCameraDevice: CameraDevice.front)); - }); - }); - - group('#pickVideo', () { - setUp(() { - when(mockPlatform.pickVideo( - source: anyNamed('source'), - preferredCameraDevice: anyNamed('preferredCameraDevice'), - maxDuration: anyNamed('maxDuration'))) - .thenAnswer((Invocation _) async => null); - }); - - test('passes the image source argument correctly', () async { - final ImagePicker picker = ImagePicker(); - await picker.getVideo(source: ImageSource.camera); - await picker.getVideo(source: ImageSource.gallery); - - verifyInOrder([ - mockPlatform.pickVideo(source: ImageSource.camera), - mockPlatform.pickVideo(source: ImageSource.gallery), - ]); - }); - - test('passes the duration argument correctly', () async { - final ImagePicker picker = ImagePicker(); - await picker.getVideo(source: ImageSource.camera); - await picker.getVideo( - source: ImageSource.camera, - maxDuration: const Duration(seconds: 10)); - - verifyInOrder([ - mockPlatform.pickVideo(source: ImageSource.camera), - mockPlatform.pickVideo( - source: ImageSource.camera, - maxDuration: const Duration(seconds: 10), - ), - ]); - }); - - test('handles a null video file response gracefully', () async { - final ImagePicker picker = ImagePicker(); - - expect(await picker.getVideo(source: ImageSource.gallery), isNull); - expect(await picker.getVideo(source: ImageSource.camera), isNull); - }); - - test('camera position defaults to back', () async { - final ImagePicker picker = ImagePicker(); - await picker.getVideo(source: ImageSource.camera); - - verify(mockPlatform.pickVideo(source: ImageSource.camera)); - }); - - test('camera position can set to front', () async { - final ImagePicker picker = ImagePicker(); - await picker.getVideo( - source: ImageSource.camera, - preferredCameraDevice: CameraDevice.front); - - verify(mockPlatform.pickVideo( - source: ImageSource.camera, - preferredCameraDevice: CameraDevice.front)); - }); - }); - - group('#retrieveLostData', () { - test('retrieveLostData get success response', () async { - final ImagePicker picker = ImagePicker(); - when(mockPlatform.retrieveLostData()).thenAnswer( - (Invocation _) async => LostData( - file: PickedFile('/example/path'), type: RetrieveType.image)); - - final LostData response = await picker.getLostData(); - - expect(response.type, RetrieveType.image); - expect(response.file!.path, '/example/path'); - }); - - test('retrieveLostData get error response', () async { - final ImagePicker picker = ImagePicker(); - when(mockPlatform.retrieveLostData()).thenAnswer( - (Invocation _) async => LostData( - exception: PlatformException( - code: 'test_error_code', message: 'test_error_message'), - type: RetrieveType.video)); - - final LostData response = await picker.getLostData(); - - expect(response.type, RetrieveType.video); - expect(response.exception!.code, 'test_error_code'); - expect(response.exception!.message, 'test_error_message'); - }); - }); - }); - - group('Multi images', () { - setUp(() { - when(mockPlatform.pickMultiImage( - maxWidth: anyNamed('maxWidth'), - maxHeight: anyNamed('maxHeight'), - imageQuality: anyNamed('imageQuality'))) - .thenAnswer((Invocation _) async => null); - }); - - group('#pickMultiImage', () { - test('passes the width and height arguments correctly', () async { - final ImagePicker picker = ImagePicker(); - await picker.getMultiImage(); - await picker.getMultiImage( - maxWidth: 10.0, - ); - await picker.getMultiImage( - maxHeight: 10.0, - ); - await picker.getMultiImage( - maxWidth: 10.0, - maxHeight: 20.0, - ); - await picker.getMultiImage( - maxWidth: 10.0, - imageQuality: 70, - ); - await picker.getMultiImage( - maxHeight: 10.0, - imageQuality: 70, - ); - await picker.getMultiImage( - maxWidth: 10.0, maxHeight: 20.0, imageQuality: 70); - - verifyInOrder([ - mockPlatform.pickMultiImage(), - mockPlatform.pickMultiImage(maxWidth: 10.0), - mockPlatform.pickMultiImage(maxHeight: 10.0), - mockPlatform.pickMultiImage(maxWidth: 10.0, maxHeight: 20.0), - mockPlatform.pickMultiImage(maxWidth: 10.0, imageQuality: 70), - mockPlatform.pickMultiImage(maxHeight: 10.0, imageQuality: 70), - mockPlatform.pickMultiImage( - maxWidth: 10.0, - maxHeight: 20.0, - imageQuality: 70, - ), - ]); - }); - - test('handles a null image file response gracefully', () async { - final ImagePicker picker = ImagePicker(); - - expect(await picker.getMultiImage(), isNull); - expect(await picker.getMultiImage(), isNull); - }); - }); - }); - }); -}