Skip to content

Commit 6565f17

Browse files
authored
[image_picker] getMedia platform changes (flutter#4174)
Adds `getMedia` and `getMultipleMedia` methods to image_picker_platform_interface. precursor to flutter/packages#3892 part of flutter#89159
1 parent ecf2b68 commit 6565f17

File tree

12 files changed

+316
-60
lines changed

12 files changed

+316
-60
lines changed

packages/image_picker/image_picker_platform_interface/CHANGELOG.md

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,7 @@
1+
## 2.8.0
2+
3+
* Adds `getMedia` method.
4+
15
## 2.7.0
26

37
* Adds `CameraDelegatingImagePickerPlatform` as a base class for platform

packages/image_picker/image_picker_platform_interface/lib/src/method_channel/method_channel_image_picker.dart

Lines changed: 37 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -252,6 +252,30 @@ class MethodChannelImagePicker extends ImagePickerPlatform {
252252
return paths.map((dynamic path) => XFile(path as String)).toList();
253253
}
254254

255+
@override
256+
Future<List<XFile>> getMedia({
257+
required MediaOptions options,
258+
}) async {
259+
final ImageOptions imageOptions = options.imageOptions;
260+
261+
final Map<String, dynamic> args = <String, dynamic>{
262+
'maxImageWidth': imageOptions.maxWidth,
263+
'maxImageHeight': imageOptions.maxHeight,
264+
'imageQuality': imageOptions.imageQuality,
265+
'allowMultiple': options.allowMultiple,
266+
};
267+
268+
final List<XFile>? paths = await _channel
269+
.invokeMethod<List<dynamic>?>(
270+
'pickMedia',
271+
args,
272+
)
273+
.then((List<dynamic>? paths) =>
274+
paths?.map((dynamic path) => XFile(path as String)).toList());
275+
276+
return paths ?? <XFile>[];
277+
}
278+
255279
@override
256280
Future<XFile?> getVideo({
257281
required ImageSource source,
@@ -280,13 +304,21 @@ class MethodChannelImagePicker extends ImagePickerPlatform {
280304
assert(result.containsKey('path') != result.containsKey('errorCode'));
281305

282306
final String? type = result['type'] as String?;
283-
assert(type == kTypeImage || type == kTypeVideo);
307+
assert(
308+
type == kTypeImage || type == kTypeVideo || type == kTypeMedia,
309+
);
284310

285311
RetrieveType? retrieveType;
286-
if (type == kTypeImage) {
287-
retrieveType = RetrieveType.image;
288-
} else if (type == kTypeVideo) {
289-
retrieveType = RetrieveType.video;
312+
switch (type) {
313+
case kTypeImage:
314+
retrieveType = RetrieveType.image;
315+
break;
316+
case kTypeVideo:
317+
retrieveType = RetrieveType.video;
318+
break;
319+
case kTypeMedia:
320+
retrieveType = RetrieveType.media;
321+
break;
290322
}
291323

292324
PlatformException? exception;

packages/image_picker/image_picker_platform_interface/lib/src/platform_interface/image_picker_platform.dart

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -213,6 +213,24 @@ abstract class ImagePickerPlatform extends PlatformInterface {
213213
throw UnimplementedError('getMultiImage() has not been implemented.');
214214
}
215215

216+
/// Returns a [List<XFile>] with the images and/or videos that were picked.
217+
/// The images and videos come from the gallery.
218+
///
219+
/// Where iOS supports HEIC images, Android 8 and below doesn't. Android 9 and
220+
/// above only support HEIC images if used in addition to a size modification,
221+
/// of which the usage is explained below.
222+
///
223+
/// In Android, the MainActivity can be destroyed for various reasons.
224+
/// If that happens, the result will be lost in this call. You can then
225+
/// call [getLostData] when your app relaunches to retrieve the lost data.
226+
///
227+
/// If no images or videos were picked, the return value is an empty list.
228+
Future<List<XFile>> getMedia({
229+
required MediaOptions options,
230+
}) {
231+
throw UnimplementedError('getMedia() has not been implemented.');
232+
}
233+
216234
/// Returns a [XFile] containing the video that was picked.
217235
///
218236
/// The [source] argument controls where the video comes from. This can

packages/image_picker/image_picker_platform_interface/lib/src/types/image_options.dart

Lines changed: 61 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,40 @@
22
// Use of this source code is governed by a BSD-style license that can be
33
// found in the LICENSE file.
44

5+
import 'types.dart';
6+
7+
/// Specifies options for picking a single image from the device's camera or gallery.
8+
///
9+
/// This class inheritance is a byproduct of the api changing over time.
10+
/// It exists solely to avoid breaking changes.
11+
class ImagePickerOptions extends ImageOptions {
12+
/// Creates an instance with the given [maxHeight], [maxWidth], [imageQuality],
13+
/// [referredCameraDevice] and [requestFullMetadata].
14+
const ImagePickerOptions({
15+
super.maxHeight,
16+
super.maxWidth,
17+
super.imageQuality,
18+
super.requestFullMetadata,
19+
this.preferredCameraDevice = CameraDevice.rear,
20+
}) : super();
21+
22+
/// Creates an instance with the given [maxHeight], [maxWidth], [imageQuality],
23+
/// [referredCameraDevice] and [requestFullMetadata].
24+
ImagePickerOptions.createAndValidate({
25+
super.maxHeight,
26+
super.maxWidth,
27+
super.imageQuality,
28+
super.requestFullMetadata,
29+
this.preferredCameraDevice = CameraDevice.rear,
30+
}) : super.createAndValidate();
31+
32+
/// Used to specify the camera to use when the `source` is [ImageSource.camera].
33+
///
34+
/// Ignored if the source is not [ImageSource.camera], or the chosen camera is not
35+
/// supported on the device. Defaults to [CameraDevice.rear].
36+
final CameraDevice preferredCameraDevice;
37+
}
38+
539
/// Specifies image-specific options for picking.
640
class ImageOptions {
741
/// Creates an instance with the given [maxHeight], [maxWidth], [imageQuality]
@@ -13,6 +47,18 @@ class ImageOptions {
1347
this.requestFullMetadata = true,
1448
});
1549

50+
/// Creates an instance with the given [maxHeight], [maxWidth], [imageQuality]
51+
/// and [requestFullMetadata]. Throws if options are not valid.
52+
ImageOptions.createAndValidate({
53+
this.maxHeight,
54+
this.maxWidth,
55+
this.imageQuality,
56+
this.requestFullMetadata = true,
57+
}) {
58+
_validateOptions(
59+
maxWidth: maxWidth, maxHeight: maxHeight, imageQuality: imageQuality);
60+
}
61+
1662
/// The maximum width of the image, in pixels.
1763
///
1864
/// If null, the image will only be resized if [maxHeight] is specified.
@@ -38,4 +84,19 @@ class ImageOptions {
3884
//
3985
// Defaults to true.
4086
final bool requestFullMetadata;
87+
88+
/// Validates that all values are within required ranges. Throws if not.
89+
static void _validateOptions(
90+
{double? maxWidth, final double? maxHeight, int? imageQuality}) {
91+
if (imageQuality != null && (imageQuality < 0 || imageQuality > 100)) {
92+
throw ArgumentError.value(
93+
imageQuality, 'imageQuality', 'must be between 0 and 100');
94+
}
95+
if (maxWidth != null && maxWidth < 0) {
96+
throw ArgumentError.value(maxWidth, 'maxWidth', 'cannot be negative');
97+
}
98+
if (maxHeight != null && maxHeight < 0) {
99+
throw ArgumentError.value(maxHeight, 'maxHeight', 'cannot be negative');
100+
}
101+
}
41102
}

packages/image_picker/image_picker_platform_interface/lib/src/types/image_picker_options.dart

Lines changed: 0 additions & 50 deletions
This file was deleted.

packages/image_picker/image_picker_platform_interface/lib/src/types/lost_data_response.dart

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -36,7 +36,8 @@ class LostDataResponse {
3636
/// An empty response should have [file], [exception] and [type] to be null.
3737
bool get isEmpty => _empty;
3838

39-
/// The file that was lost in a previous [getImage], [getMultiImage] or [getVideo] call due to MainActivity being destroyed.
39+
/// The file that was lost in a previous [getImage], [getMultiImage],
40+
/// [getVideo] or [getMedia] call due to MainActivity being destroyed.
4041
///
4142
/// Can be null if [exception] exists.
4243
final XFile? file;
@@ -51,7 +52,7 @@ class LostDataResponse {
5152
/// Note that it is not the exception that caused the destruction of the MainActivity.
5253
final PlatformException? exception;
5354

54-
/// Can either be [RetrieveType.image] or [RetrieveType.video];
55+
/// Can either be [RetrieveType.image], [RetrieveType.video], or [RetrieveType.media].
5556
///
5657
/// If the lost data is empty, this will be null.
5758
final RetrieveType? type;
Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
// Copyright 2013 The Flutter Authors. All rights reserved.
2+
// Use of this source code is governed by a BSD-style license that can be
3+
// found in the LICENSE file.
4+
5+
import 'package:flutter/foundation.dart';
6+
7+
import '../../image_picker_platform_interface.dart';
8+
9+
/// Specifies options for selecting items when using [ImagePickerPlatform.getMedia].
10+
@immutable
11+
class MediaOptions {
12+
/// Construct a new MediaOptions instance.
13+
const MediaOptions({
14+
this.imageOptions = const ImageOptions(),
15+
required this.allowMultiple,
16+
});
17+
18+
/// Options that will apply to images upon selection.
19+
final ImageOptions imageOptions;
20+
21+
/// Whether to allow for selecting multiple media.
22+
final bool allowMultiple;
23+
}
Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
// Copyright 2013 The Flutter Authors. All rights reserved.
2+
// Use of this source code is governed by a BSD-style license that can be
3+
// found in the LICENSE file.
4+
5+
import '../../image_picker_platform_interface.dart';
6+
7+
/// The type of media to allow the user to select with [ImagePickerPlatform.getMedia].
8+
enum MediaSelectionType {
9+
/// Static pictures.
10+
image,
11+
12+
/// Videos.
13+
video,
14+
}

packages/image_picker/image_picker_platform_interface/lib/src/types/retrieve_type.dart

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,5 +8,8 @@ enum RetrieveType {
88
image,
99

1010
/// A video. See [ImagePicker.pickVideo].
11-
video
11+
video,
12+
13+
/// Either a video or a static picture. See [ImagePicker.pickMedia].
14+
media,
1215
}

packages/image_picker/image_picker_platform_interface/lib/src/types/types.dart

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,9 +5,10 @@
55
export 'camera_delegate.dart';
66
export 'camera_device.dart';
77
export 'image_options.dart';
8-
export 'image_picker_options.dart';
98
export 'image_source.dart';
109
export 'lost_data_response.dart';
10+
export 'media_options.dart';
11+
export 'media_selection_type.dart';
1112
export 'multi_image_picker_options.dart';
1213
export 'picked_file/picked_file.dart';
1314
export 'retrieve_type.dart';
@@ -17,3 +18,6 @@ const String kTypeImage = 'image';
1718

1819
/// Denotes that a video is being picked.
1920
const String kTypeVideo = 'video';
21+
22+
/// Denotes that either a video or image is being picked.
23+
const String kTypeMedia = 'media';

0 commit comments

Comments
 (0)