调用availableCameras()触发MissingPluginException问题求助
问题背景
测试带相机功能的Flutter应用时,调用availableCameras()仅在Android端报错,iOS端正常。该问题在添加自定义Native MethodChannel后出现。
报错信息
MissingPluginException (MissingPluginException(No implementation found for method availableCameras on channel plugins.flutter.io/camera_android))
调用代码
DartPluginRegistrant.ensureInitialized(); WidgetsFlutterBinding.ensureInitialized(); var cameras = await availableCameras();
已尝试的无效操作
- 降低camera包版本(测试过
^0.10.0+4和0.9.7+1) - 执行
flutter clean+flutter pub get - 重启VS Code和Android Studio
- 修改自定义MethodChannel名称(排查通道冲突)
相关配置与代码
pubspec.yaml
dependencies: flutter: sdk: flutter camera: ^0.10.0+4 # camera: 0.9.7+1 path_provider: ^2.0.11 path: ^1.8.2 # dependency_overrides: # camera_android: 0.9.7+1 # camera_avfoundation: 0.9.7+1
Dart端自定义通道代码
class AppInfo { static const MethodChannel _channel = MethodChannel('appInfo'); static Future<String?> get appVersion async { final String? version = await _channel.invokeMethod('getAppVersion'); return version; } }
Android端MainActivity.kt
package com.xxx.xxxx import android.content.pm.PackageManager import androidx.annotation.NonNull import io.flutter.embedding.android.FlutterActivity import io.flutter.embedding.engine.FlutterEngine import io.flutter.plugin.common.MethodChannel import kotlinx.coroutines.ExperimentalCoroutinesApi class MainActivity : FlutterActivity() { private val CHANNEL = "appInfo" @OptIn(ExperimentalCoroutinesApi::class) override fun configureFlutterEngine(@NonNull flutterEngine: FlutterEngine) { MethodChannel( flutterEngine.dartExecutor.binaryMessenger, CHANNEL ).setMethodCallHandler { call, result -> if (call.method == "getAppVersion") { try { val pInfo = applicationContext.packageManager.getPackageInfo(context.packageName, 0) var version = pInfo.versionName result.success("${pInfo.versionName}"); } catch (e: PackageManager.NameNotFoundException) { e.printStackTrace() result.notImplemented() } } else { result.notImplemented() } } } }
iOS端AppDelegate.swift
import UIKit import Flutter @UIApplicationMain @objc class AppDelegate: FlutterAppDelegate { override func application( _ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]? ) -> Bool { GeneratedPluginRegistrant.register(with: self) let controller: FlutterViewController = window?.rootViewController as! FlutterViewController let helloMethodChannel = FlutterMethodChannel(name: "appInfo",binaryMessenger: controller as! FlutterBinaryMessenger) helloMethodChannel.setMethodCallHandler({ (call:FlutterMethodCall,result:FlutterResult) -> Void in switch call.method{ case "getAppVersion": result(Bundle.main.object(forInfoDictionaryKey:"CFBundleShortVersionString") as? String) default: result("iOS" + UIDevice.current.systemVersion) } }) return super.application(application, didFinishLaunchingWithOptions: launchOptions) } }
flutter doctor -v结果
[✓] Flutter (Channel stable, 3.3.6, on macOS 12.6 21G115 darwin-x64, locale en-JP) • Flutter version 3.3.6 on channel stable at /Users/ganessa/fvm/versions/stable • Upstream repository https://github.com/flutter/flutter.git • Framework revision 6928314d50 (7 days ago), 2022-10-25 16:34:41 -0400 • Engine revision 3ad69d7be3 • Dart version 2.18.2 • DevTools version 2.15.0 [✓] Android toolchain - develop for Android devices (Android SDK version 33.0.0) • Android SDK at /Users/ganessa/src/android-sdks • Platform android-33, build-tools 33.0.0 • Java binary at: /Applications/Android Studio.app/Contents/jre/Contents/Home/bin/java • Java version OpenJDK Runtime Environment (build 11.0.12+0-b1504.28-7817840) • All Android licenses accepted. [✓] Xcode - develop for iOS and macOS (Xcode 13.4.1) • Xcode at /Applications/Xcode.app/Contents/Developer • Build 13F100 • CocoaPods version 1.11.2 [✓] Chrome - develop for the web • Chrome at /Applications/Google Chrome.app/Contents/MacOS/Google Chrome [✓] Android Studio (version 2021.2) • Android Studio at /Applications/Android Studio.app/Contents • Flutter plugin can be installed from: 🔨 https://plugins.jetbrains.com/plugin/9212-flutter • Dart plugin can be installed from: 🔨 https://plugins.jetbrains.com/plugin/6351-dart • Java version OpenJDK Runtime Environment (build 11.0.12+0-b1504.28-7817840) [✓] VS Code (version 1.72.2) • VS Code at /Applications/Visual Studio Code.app/Contents • Flutter extension version 3.52.0 [✓] Connected device (4 available) • SHV43 (mobile) • XXXXXXXXXXXXXXX • android-arm64 • Android 9 (API 28) • iPhone SE2 MS (mobile) • XXXXXXXX-XXXXXXXXXXXXXXXX • ios • iOS 15.6.1 19G82 • macOS (desktop) • macos • darwin-x64 • macOS 12.6 21G115 darwin-x64 • Chrome (web) • chrome • web-javascript • Google Chrome 107.0.5304.87 [✓] HTTP Host Availability • All required HTTP hosts are available • No issues found!
可行排查/解决方法
手动注册Android端相机插件
在MainActivity的configureFlutterEngine方法中,优先注册相机插件,确保其初始化完成:import io.flutter.plugins.camera.CameraPlugin override fun configureFlutterEngine(@NonNull flutterEngine: FlutterEngine) { // 先注册相机插件 CameraPlugin.registerWith(flutterEngine.dartExecutor.binaryMessenger) // 再注册自定义通道 MethodChannel(flutterEngine.dartExecutor.binaryMessenger, CHANNEL).setMethodCallHandler(...) }验证AndroidManifest.xml配置
确认已添加相机相关权限:<uses-permission android:name="android.permission.CAMERA" /> <uses-feature android:name="android.hardware.camera" /> <uses-feature android:name="android.hardware.camera.autofocus" />清除Android项目深层缓存
进入项目的android目录,执行./gradlew clean,同时删除android/.gradle目录,再重新执行flutter pub get和flutter run。调整引擎初始化顺序
将WidgetsFlutterBinding.ensureInitialized()放在DartPluginRegistrant.ensureInitialized()之前:WidgetsFlutterBinding.ensureInitialized(); DartPluginRegistrant.ensureInitialized(); var cameras = await availableCameras();升级Flutter版本
当前使用的Flutter 3.3.6版本较旧,尝试升级到最新稳定版,修复潜在的插件兼容性问题:flutter upgrade适配低版本Android设备
测试设备为Android 9(API 28),尝试锁定更适配该版本的camera包版本,例如0.9.4+5,并添加依赖覆盖:dependency_overrides: camera_android: 0.9.4+5
内容的提问来源于stack exchange,提问作者Ganessa

