pickFromGallery static method
Pick an image from the gallery, preserving its EXIF GPS metadata.
On Android the pick is handled natively (ACTION_PICK on the MediaStore
images collection + MediaStore.setRequireOriginal() behind a runtime
ACCESS_MEDIA_LOCATION request) so the location tags survive the
Android 10+ media redaction that silently strips GPS from ImagePicker
results. If the native pick fails it falls back to ImagePicker. iOS and
other platforms use ImagePicker directly.
Note: the returned image is no longer auto-scrubbed — valid GPS is left intact. Use removeGps explicitly if you need to strip it.
Implementation
static Future<String?> pickFromGallery() async {
if (Platform.isAndroid) {
try {
// null == user cancelled.
return await _channel.invokeMethod<String>('pickImageWithGps');
} on PlatformException catch (e) {
// Only fall back to ImagePicker when the native picker could not launch
// at all. Never re-open a second picker after the user already chose an
// image (e.g. on a copy error) — that caused a double-pick.
if (e.code == 'NO_PICKER' || e.code == 'NO_ACTIVITY') {
debugPrint('Native picker unavailable, using ImagePicker: $e');
try {
final picker = ImagePicker();
final picked = await picker.pickImage(source: ImageSource.gallery);
return picked?.path;
} catch (e) {
debugPrint('ImagePicker fallback error: $e');
return null;
}
}
debugPrint('pickImageWithGps error: $e');
return null;
} catch (e) {
debugPrint('pickFromGallery error: $e');
return null;
}
}
try {
final picker = ImagePicker();
final picked = await picker.pickImage(source: ImageSource.gallery);
return picked?.path;
} catch (e) {
debugPrint('pickFromGallery error: $e');
return null;
}
}