Skip to content
This repository was archived by the owner on Feb 22, 2023. It is now read-only.

Commit 95a1f2c

Browse files
[image_picker] Switch Android to internal method channel (#5958)
1 parent 0b29924 commit 95a1f2c

File tree

5 files changed

+1545
-2
lines changed

5 files changed

+1545
-2
lines changed

packages/image_picker/image_picker_android/CHANGELOG.md

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,7 @@
1+
## 0.8.5+1
2+
3+
* Switches to an internal method channel implementation.
4+
15
## 0.8.5
26

37
* Updates gradle to 7.1.2.

packages/image_picker/image_picker_android/android/src/main/java/io/flutter/plugins/imagepicker/ImagePickerPlugin.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -183,7 +183,7 @@ ImagePickerDelegate getDelegate() {
183183
private static final String METHOD_CALL_RETRIEVE = "retrieve";
184184
private static final int CAMERA_DEVICE_FRONT = 1;
185185
private static final int CAMERA_DEVICE_REAR = 0;
186-
private static final String CHANNEL = "plugins.flutter.io/image_picker";
186+
private static final String CHANNEL = "plugins.flutter.io/image_picker_android";
187187

188188
private static final int SOURCE_CAMERA = 0;
189189
private static final int SOURCE_GALLERY = 1;
Lines changed: 282 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,282 @@
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 'dart:async';
6+
7+
import 'package:flutter/foundation.dart';
8+
import 'package:flutter/services.dart';
9+
10+
import 'package:image_picker_platform_interface/image_picker_platform_interface.dart';
11+
12+
const MethodChannel _channel =
13+
MethodChannel('plugins.flutter.io/image_picker_android');
14+
15+
/// An Android implementation of [ImagePickerPlatform].
16+
class ImagePickerAndroid extends ImagePickerPlatform {
17+
/// The MethodChannel that is being used by this implementation of the plugin.
18+
@visibleForTesting
19+
MethodChannel get channel => _channel;
20+
21+
/// Registers this class as the default platform implementation.
22+
static void registerWith() {
23+
ImagePickerPlatform.instance = ImagePickerAndroid();
24+
}
25+
26+
@override
27+
Future<PickedFile?> pickImage({
28+
required ImageSource source,
29+
double? maxWidth,
30+
double? maxHeight,
31+
int? imageQuality,
32+
CameraDevice preferredCameraDevice = CameraDevice.rear,
33+
}) async {
34+
final String? path = await _getImagePath(
35+
source: source,
36+
maxWidth: maxWidth,
37+
maxHeight: maxHeight,
38+
imageQuality: imageQuality,
39+
preferredCameraDevice: preferredCameraDevice,
40+
);
41+
return path != null ? PickedFile(path) : null;
42+
}
43+
44+
@override
45+
Future<List<PickedFile>?> pickMultiImage({
46+
double? maxWidth,
47+
double? maxHeight,
48+
int? imageQuality,
49+
}) async {
50+
final List<dynamic>? paths = await _getMultiImagePath(
51+
maxWidth: maxWidth,
52+
maxHeight: maxHeight,
53+
imageQuality: imageQuality,
54+
);
55+
if (paths == null) {
56+
return null;
57+
}
58+
59+
return paths.map((dynamic path) => PickedFile(path as String)).toList();
60+
}
61+
62+
Future<List<dynamic>?> _getMultiImagePath({
63+
double? maxWidth,
64+
double? maxHeight,
65+
int? imageQuality,
66+
}) {
67+
if (imageQuality != null && (imageQuality < 0 || imageQuality > 100)) {
68+
throw ArgumentError.value(
69+
imageQuality, 'imageQuality', 'must be between 0 and 100');
70+
}
71+
72+
if (maxWidth != null && maxWidth < 0) {
73+
throw ArgumentError.value(maxWidth, 'maxWidth', 'cannot be negative');
74+
}
75+
76+
if (maxHeight != null && maxHeight < 0) {
77+
throw ArgumentError.value(maxHeight, 'maxHeight', 'cannot be negative');
78+
}
79+
80+
return _channel.invokeMethod<List<dynamic>?>(
81+
'pickMultiImage',
82+
<String, dynamic>{
83+
'maxWidth': maxWidth,
84+
'maxHeight': maxHeight,
85+
'imageQuality': imageQuality,
86+
},
87+
);
88+
}
89+
90+
Future<String?> _getImagePath({
91+
required ImageSource source,
92+
double? maxWidth,
93+
double? maxHeight,
94+
int? imageQuality,
95+
CameraDevice preferredCameraDevice = CameraDevice.rear,
96+
bool requestFullMetadata = true,
97+
}) {
98+
if (imageQuality != null && (imageQuality < 0 || imageQuality > 100)) {
99+
throw ArgumentError.value(
100+
imageQuality, 'imageQuality', 'must be between 0 and 100');
101+
}
102+
103+
if (maxWidth != null && maxWidth < 0) {
104+
throw ArgumentError.value(maxWidth, 'maxWidth', 'cannot be negative');
105+
}
106+
107+
if (maxHeight != null && maxHeight < 0) {
108+
throw ArgumentError.value(maxHeight, 'maxHeight', 'cannot be negative');
109+
}
110+
111+
return _channel.invokeMethod<String>(
112+
'pickImage',
113+
<String, dynamic>{
114+
'source': source.index,
115+
'maxWidth': maxWidth,
116+
'maxHeight': maxHeight,
117+
'imageQuality': imageQuality,
118+
'cameraDevice': preferredCameraDevice.index,
119+
'requestFullMetadata': requestFullMetadata,
120+
},
121+
);
122+
}
123+
124+
@override
125+
Future<PickedFile?> pickVideo({
126+
required ImageSource source,
127+
CameraDevice preferredCameraDevice = CameraDevice.rear,
128+
Duration? maxDuration,
129+
}) async {
130+
final String? path = await _getVideoPath(
131+
source: source,
132+
maxDuration: maxDuration,
133+
preferredCameraDevice: preferredCameraDevice,
134+
);
135+
return path != null ? PickedFile(path) : null;
136+
}
137+
138+
Future<String?> _getVideoPath({
139+
required ImageSource source,
140+
CameraDevice preferredCameraDevice = CameraDevice.rear,
141+
Duration? maxDuration,
142+
}) {
143+
return _channel.invokeMethod<String>(
144+
'pickVideo',
145+
<String, dynamic>{
146+
'source': source.index,
147+
'maxDuration': maxDuration?.inSeconds,
148+
'cameraDevice': preferredCameraDevice.index
149+
},
150+
);
151+
}
152+
153+
@override
154+
Future<XFile?> getImage({
155+
required ImageSource source,
156+
double? maxWidth,
157+
double? maxHeight,
158+
int? imageQuality,
159+
CameraDevice preferredCameraDevice = CameraDevice.rear,
160+
}) async {
161+
final String? path = await _getImagePath(
162+
source: source,
163+
maxWidth: maxWidth,
164+
maxHeight: maxHeight,
165+
imageQuality: imageQuality,
166+
preferredCameraDevice: preferredCameraDevice,
167+
);
168+
return path != null ? XFile(path) : null;
169+
}
170+
171+
@override
172+
Future<XFile?> getImageFromSource({
173+
required ImageSource source,
174+
ImagePickerOptions options = const ImagePickerOptions(),
175+
}) async {
176+
final String? path = await _getImagePath(
177+
source: source,
178+
maxHeight: options.maxHeight,
179+
maxWidth: options.maxWidth,
180+
imageQuality: options.imageQuality,
181+
preferredCameraDevice: options.preferredCameraDevice,
182+
requestFullMetadata: options.requestFullMetadata,
183+
);
184+
return path != null ? XFile(path) : null;
185+
}
186+
187+
@override
188+
Future<List<XFile>?> getMultiImage({
189+
double? maxWidth,
190+
double? maxHeight,
191+
int? imageQuality,
192+
}) async {
193+
final List<dynamic>? paths = await _getMultiImagePath(
194+
maxWidth: maxWidth,
195+
maxHeight: maxHeight,
196+
imageQuality: imageQuality,
197+
);
198+
if (paths == null) {
199+
return null;
200+
}
201+
202+
return paths.map((dynamic path) => XFile(path as String)).toList();
203+
}
204+
205+
@override
206+
Future<XFile?> getVideo({
207+
required ImageSource source,
208+
CameraDevice preferredCameraDevice = CameraDevice.rear,
209+
Duration? maxDuration,
210+
}) async {
211+
final String? path = await _getVideoPath(
212+
source: source,
213+
maxDuration: maxDuration,
214+
preferredCameraDevice: preferredCameraDevice,
215+
);
216+
return path != null ? XFile(path) : null;
217+
}
218+
219+
@override
220+
Future<LostData> retrieveLostData() async {
221+
final LostDataResponse result = await getLostData();
222+
223+
if (result.isEmpty) {
224+
return LostData.empty();
225+
}
226+
227+
return LostData(
228+
file: result.file != null ? PickedFile(result.file!.path) : null,
229+
exception: result.exception,
230+
type: result.type,
231+
);
232+
}
233+
234+
@override
235+
Future<LostDataResponse> getLostData() async {
236+
List<XFile>? pickedFileList;
237+
238+
final Map<String, dynamic>? result =
239+
await _channel.invokeMapMethod<String, dynamic>('retrieve');
240+
241+
if (result == null) {
242+
return LostDataResponse.empty();
243+
}
244+
245+
assert(result.containsKey('path') != result.containsKey('errorCode'));
246+
247+
final String? type = result['type'] as String?;
248+
assert(type == kTypeImage || type == kTypeVideo);
249+
250+
RetrieveType? retrieveType;
251+
if (type == kTypeImage) {
252+
retrieveType = RetrieveType.image;
253+
} else if (type == kTypeVideo) {
254+
retrieveType = RetrieveType.video;
255+
}
256+
257+
PlatformException? exception;
258+
if (result.containsKey('errorCode')) {
259+
exception = PlatformException(
260+
code: result['errorCode']! as String,
261+
message: result['errorMessage'] as String?);
262+
}
263+
264+
final String? path = result['path'] as String?;
265+
266+
final List<String>? pathList =
267+
(result['pathList'] as List<dynamic>?)?.cast<String>();
268+
if (pathList != null) {
269+
pickedFileList = <XFile>[];
270+
for (final String path in pathList) {
271+
pickedFileList.add(XFile(path));
272+
}
273+
}
274+
275+
return LostDataResponse(
276+
file: path != null ? XFile(path) : null,
277+
exception: exception,
278+
type: retrieveType,
279+
files: pickedFileList,
280+
);
281+
}
282+
}

packages/image_picker/image_picker_android/pubspec.yaml

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@ name: image_picker_android
22
description: Android implementation of the image_picker plugin.
33
repository: https://github.com/flutter/plugins/tree/main/packages/image_picker/image_picker_android
44
issue_tracker: https://github.com/flutter/flutter/issues?q=is%3Aissue+is%3Aopen+label%3A%22p%3A+image_picker%22
5-
version: 0.8.5
5+
version: 0.8.5+1
66

77
environment:
88
sdk: ">=2.14.0 <3.0.0"
@@ -15,6 +15,7 @@ flutter:
1515
android:
1616
package: io.flutter.plugins.imagepicker
1717
pluginClass: ImagePickerPlugin
18+
dartPluginClass: ImagePickerAndroid
1819

1920
dependencies:
2021
flutter:

0 commit comments

Comments
 (0)