Flutter Android端image_picker调用pickImage报MissingPluginException
问题场景
- 基于Flutter框架开发仅适配Android端的应用,使用
image_picker: ^0.8.5+3插件实现相机拍摄、相册选取图片功能,业务逻辑采用GetX框架编写 - 适配目标为Android 29+版本,已在
AndroidManifest.xml中添加android:requestLegacyExternalStorage="true"配置,未做iOS端适配 - 调用选图方法时持续抛出异常,已尝试公开社区同类问题的常规解决方案,均未生效
抛出的异常信息如下:
Unhandled Exception: MissingPluginException(No implementation found for method pickImage on channel plugins.flutter.io/image_picker_android)
关联代码与报错日志
1. GetX图片选取业务逻辑代码
import 'dart:io'; import 'package:flutter/material.dart'; import 'package:get/get.dart'; import 'package:image_picker/image_picker.dart'; class ImageController extends GetxController { var selectedImagePath = ''.obs; var selectedImageSize = ''.obs; void getImage(ImageSource imageSource) async { final pickedFile = await ImagePicker().pickImage(source: imageSource); if (pickedFile != null) { selectedImagePath.value = pickedFile.path; selectedImageSize.value = ((File(selectedImagePath.value).lengthSync() / 1024 / 1024) .toStringAsFixed(2) + "Mb"); } else { selectedImagePath.value = ''; selectedImageSize.value = ''; Get.snackbar( "Please Select Image", "No Image Selected", snackPosition: SnackPosition.BOTTOM, backgroundColor: Colors.red, colorText: Colors.white, borderRadius: 10, margin: EdgeInsets.all(10), borderColor: Colors.red, borderWidth: 2, duration: Duration(seconds: 2), icon: Icon( Icons.error, color: Colors.white, ), ); } } }
2. UI层选图功能调用代码
GestureDetector( onTap: () { Get.bottomSheet( Container( height: currentOrientation == Orientation.portrait ? screenHeight * 0.10 : screenHeight * 0.22, width: double.infinity, decoration: BoxDecoration( color: ProjectColors.kPrimaryColor, borderRadius: BorderRadius.only( topLeft: Radius.circular( currentOrientation == Orientation.portrait ? screenHeight * 0.02 : screenHeight * 0.05, ), topRight: Radius.circular( currentOrientation == Orientation.portrait ? screenHeight * 0.02 : screenHeight * 0.05, ), ), ), child: Row( mainAxisAlignment: MainAxisAlignment.center, children: [ GestureDetector( onTap: () { imageController .getImage(ImageSource.camera); }, child: Icon( Icons.camera_alt_outlined, color: ProjectColors.kWhiteColor, size: currentOrientation == Orientation.portrait ? screenHeight * 0.06 : screenHeight * 0.15, ), ), SizedBox( width: currentOrientation == Orientation.portrait ? screenWidth * 0.20 : screenWidth * 0.15, ), GestureDetector( onTap: () { imageController .getImage(ImageSource.gallery); }, child: Icon( Icons.image_outlined, color: ProjectColors.kWhiteColor, size: currentOrientation == Orientation.portrait ? screenHeight * 0.06 : screenHeight * 0.15, ), ), ], ), ), ); }, child: Obx( () => imageController.selectedImagePath.value == '' ? Container( height: currentOrientation == Orientation.portrait ? screenHeight * 0.20 : screenHeight * 0.50, width: currentOrientation == Orientation.portrait ? screenWidth * 0.85 : double.infinity, color: Colors.white, child: Icon( Icons.add_box_sharp, color: ProjectColors.kPrimaryColor, size: currentOrientation == Orientation.portrait ? screenHeight * 0.06 : screenHeight * 0.10, ), ) : Image.file( File(imageController.selectedImagePath.value), fit: BoxFit.cover, ), ), ),
3. 完整运行报错日志
E/flutter ( 5139): [ERROR:flutter/lib/ui/ui_dart_state.cc(198)] Unhandled Exception: MissingPluginException(No implementation found for method pickImage on channel plugins.flutter.io/image_picker_android) E/flutter ( 5139): #0 MethodChannel._invokeMethod (package:flutter/src/services/platform_channel.dart:165:7) E/flutter ( 5139): <asynchronous suspension> E/flutter ( 5139): #1 ImagePickerAndroid.getImage (package:image_picker_android/image_picker_android.dart:161:26) E/flutter ( 5139): <asynchronous suspension> E/flutter ( 5139): #2 ImageController.getImage (package:cede_mobile/controller/select_image.dart:11:24) E/flutter ( 5139): <asynchronous suspension> E/flutter ( 5139): E/flutter ( 5139): [ERROR:flutter/lib/ui/ui_dart_state.cc(198)] Unhandled Exception: MissingPluginException(No implementation found for method pickImage on channel plugins.flutter.io/image_picker_android) E/flutter ( 5139): #0 MethodChannel._invokeMethod (package:flutter/src/services/platform_channel.dart:165:7) E/flutter ( 5139): <asynchronous suspension> E/flutter ( 5139): #1 ImagePickerAndroid.getImage (package:image_picker_android/image_picker_android.dart:161:26) E/flutter ( 5139): <asynchronous suspension> E/flutter ( 5139): #2 ImageController.getImage (package:cede_mobile/controller/select_image.dart:11:24) E/flutter ( 5139): <asynchronous suspension> E/flutter ( 5139):
排查与解决步骤
按顺序执行以下操作,绝大多数同类问题可在前三步解决:
- 全量清理重建项目:热重载、热重启不会注册新增原生插件的通道,必须执行完整清理流程
执行完成后,完全卸载设备/模拟器上已安装的旧版本应用,重新执行flutter clean flutter pub getflutter run全量编译安装,不要使用热重载启动应用。 - 检查Android端基础配置:
- 打开
android/app/build.gradle文件,确认minSdkVersion配置不低于20,这是image_picker 0.8.5+3要求的最低Android版本 - 执行
flutter build apk --debug查看构建日志,确认是否存在Manifest合并冲突,比如引入android:requestLegacyExternalStorage属性时未声明xmlns:tools命名空间,或其他依赖覆盖了插件的清单配置 - 如果项目中自定义了FlutterEngine、继承了FlutterActivity做二次开发,需要手动在引擎注册逻辑中添加ImagePickerAndroid插件的注册,不要完全依赖自动生成的插件注册逻辑
- 打开
- 修复pub缓存损坏问题:0.8.5版本的image_picker首次拆分Android端为独立的
image_picker_android原生包,本地pub缓存损坏时会导致原生代码未被正确引入,直接删除本地pub缓存目录(Windows路径为C:\Users\用户名\AppData\Local\Pub\Cache,Mac路径为~/.pub-cache),重新执行flutter pub get拉取依赖 - 版本降级验证:如果以上操作都无效,将pubspec.yaml中image_picker版本调整为
^0.8.4+4,该版本未拆分Android端独立实现包,不存在通道注册失败的兼容问题,重新编译验证功能是否正常,排除0.8.5+3版本本身的兼容bug - 权限逻辑修正:Android 11及以上版本会自动忽略
android:requestLegacyExternalStorage="true"配置,且image_picker调用系统选图器不需要申请全量存储权限,不要在选图前额外申请存储权限,避免权限逻辑冲突导致插件调用异常。
内容的提问来源于stack exchange,提问作者Kennedy Owusu
相关产品推荐
相关产品推荐

