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

Flutter Android:从Intent获取文件及读取内容的问题

问题解决方案

1. 解决Intent路径格式不一致的问题

直接取intent.data?.path会因Uri协议类型不同导致路径混乱:当Uri为file://协议时返回文件系统路径,content://协议时返回内容提供者的内部路径。正确做法是通过ContentResolver解析真实文件路径:

修正后的Kotlin代码:

override fun onCreate(savedInstanceState: Bundle?) {
    super.onCreate(savedInstanceState)
    handleOpenFileUrl(intent)
}

override fun onNewIntent(intent: Intent) {
    super.onNewIntent(intent)
    handleOpenFileUrl(intent)
}

private fun handleOpenFileUrl(intent: Intent?) {
    intent?.data?.let { uri ->
        intentPath = getRealPathFromUri(uri)
    }
}

private fun getRealPathFromUri(uri: Uri): String? {
    val scheme = uri.scheme
    return when (scheme) {
        "file" -> uri.path
        "content" -> {
            val projection = arrayOf(MediaStore.Files.FileColumns.DATA)
            contentResolver.query(uri, projection, null, null, null)?.use { cursor ->
                if (cursor.moveToFirst()) {
                    val columnIndex = cursor.getColumnIndexOrThrow(MediaStore.Files.FileColumns.DATA)
                    return cursor.getString(columnIndex)
                }
            }
            null
        }
        else -> null
    }
}

注:Android API 29+直接获取DATA列可能受权限限制,此时可通过ContentResolver打开输入流读取文件内容,再传递给Flutter;或使用DocumentFile操作文件。

2. Flutter端获取文件并读取内容

通过MethodChannel将原生处理后的文件路径(或内容)传递到Flutter层:

步骤1:原生端配置MethodChannel

在MainActivity中初始化通道并提供路径获取方法:

private val CHANNEL = "com.example.file_channel"
private var intentPath: String? = null

override fun onCreate(savedInstanceState: Bundle?) {
    super.onCreate(savedInstanceState)
    MethodChannel(flutterEngine.dartExecutor.binaryMessenger, CHANNEL).setMethodCallHandler { call, result ->
        when (call.method) {
            "getOpenedFilePath" -> {
                result.success(intentPath)
            }
            else -> result.notImplemented()
        }
    }
    handleOpenFileUrl(intent)
}

// 保留之前的onNewIntent、handleOpenFileUrl、getRealPathFromUri方法

步骤2:Flutter端调用通道并读取文件

import 'package:flutter/services.dart';
import 'dart:io';

class FileHandler {
  static const MethodChannel _channel = MethodChannel('com.example.file_channel');

  static Future<String?> getOpenedFilePath() async {
    try {
      return await _channel.invokeMethod('getOpenedFilePath');
    } on PlatformException catch (e) {
      print("获取文件路径失败: ${e.message}");
      return null;
    }
  }

  static Future<String?> readFileContent() async {
    String? path = await getOpenedFilePath();
    if (path != null && File(path).existsSync()) {
      return await File(path).readAsString();
    }
    return null;
  }
}

在需要读取文件的地方调用FileHandler.readFileContent()即可获取内容。若高版本Android无法获取真实路径,可在原生端直接读取文件输入流,将内容转为字符串后通过MethodChannel传递给Flutter。

内容的提问来源于stack exchange,提问作者Maximilian Kröll

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.26 01:55:16