You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Flutter调用scanDirectory报MissingPluginException问题求助

问题根源

你的Kotlin代码里,scanDirectory对应的MethodChannel分支处理逻辑,以及私有方法scanDirectory都被注释掉了,这就是调用时提示“找不到方法实现”的直接原因。

修复方案

1. 恢复Kotlin端的方法实现

将MainActivity中被注释的scanDirectory分支和私有方法取消注释,同时优化代码细节:

  • 支持递归扫描子目录(原代码仅扫描一级目录)
  • 开启独立线程处理扫描逻辑,避免阻塞UI
  • 完善目录有效性校验,返回更精准的错误信息

修改后的Kotlin代码:

import io.flutter.embedding.android.FlutterActivity
import android.util.Log
import android.media.MediaScannerConnection
import io.flutter.embedding.engine.FlutterEngine
import io.flutter.plugin.common.MethodChannel
import java.io.File
import android.os.Bundle
import io.flutter.plugins.GeneratedPluginRegistrant

class MainActivity: FlutterActivity() {
    val CHANNEL = "media_scanner"

    override fun configureFlutterEngine(flutterEngine: FlutterEngine) {
        super.configureFlutterEngine(flutterEngine)
        GeneratedPluginRegistrant.registerWith(flutterEngine)
        
        MethodChannel(flutterEngine.dartExecutor.binaryMessenger, CHANNEL)
            .setMethodCallHandler { call, result ->
                Log.d("MethodChannel", "Method called: ${call.method}")
                when (call.method) {
                    "scanFile" -> {
                        val filePath = call.argument<String>("filePath")
                        filePath?.let {
                            MediaScannerConnection.scanFile(this, arrayOf(filePath), null) { _, _ ->
                                result.success(null)
                            }
                        } ?: result.error("INVALID_PATH", "Invalid file path", null)
                    }
                    "scanDirectory" -> {
                        try {
                            val directoryPath = call.argument<String>("directoryPath")
                            Log.d("MethodChannel", "Scanning directory: $directoryPath")
                            directoryPath?.let { dirPath ->
                                val directory = File(dirPath)
                                if (!directory.exists() || !directory.isDirectory) {
                                    result.error("INVALID_DIR", "Directory does not exist or is not a directory", null)
                                    return@let
                                }
                                // 开启线程处理扫描,避免阻塞UI
                                Thread {
                                    scanDirectoryRecursively(directory)
                                    runOnUiThread {
                                        result.success(null)
                                    }
                                }.start()
                            } ?: result.error("INVALID_PATH", "Invalid directory path", null)
                        } catch (e: Exception) {
                            Log.e("MethodChannel", "Error scanning directory", e)
                            result.error("ERROR", "Error scanning directory", e.localizedMessage)
                        }
                    }
                    else -> result.notImplemented()
                }
            }
    }

    private fun scanDirectoryRecursively(directory: File) {
        directory.listFiles()?.forEach { file ->
            if (file.isFile) {
                MediaScannerConnection.scanFile(this, arrayOf(file.absolutePath), null, null)
            } else if (file.isDirectory) {
                scanDirectoryRecursively(file)
            }
        }
    }
}

2. 优化Dart端错误处理

你的Dart代码已正确定义方法,建议添加错误捕获避免崩溃:

class MediaScanner {
  static const MethodChannel _channel = MethodChannel('media_scanner');

  static Future<void> scanFile(String filePath) async {
    try {
      await _channel.invokeMethod('scanFile', {'filePath': filePath});
    } catch (e) {
      print('Scan file error: $e');
      rethrow;
    }
  }

  static Future<void> scanDirectory(String directoryPath) async {
    try {
      await _channel.invokeMethod('scanDirectory', {'directoryPath': directoryPath});
    } catch (e) {
      print('Scan directory error: $e');
      rethrow;
    }
  }
}

3. 权限前置校验

调用扫描方法前,确保已获取对应存储权限:

  • Android 13+:需申请READ_MEDIA_IMAGES/READ_MEDIA_VIDEO等细分权限
  • Android 12及以下:需申请READ_EXTERNAL_STORAGE/WRITE_EXTERNAL_STORAGE
  • MANAGE_EXTERNAL_STORAGE权限需引导用户到系统设置手动开启

4. 强制重建项目

执行以下命令确保代码生效:

flutter clean
flutter pub get
cd android && ./gradlew clean
cd ..
flutter run

内容的提问来源于stack exchange,提问作者who-aditya-nawandar

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.02 05:13:22