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

Flutter中WebView点击文件选择按钮唤起自定义页面方案咨询

Flutter WebView Android端文件选择按钮无响应的解决方案

Flutter的webview_flutter包在Android端默认未实现文件选择的回调逻辑,这就是点击按钮无反应的核心原因。可以通过配置WebChromeClient的文件选择回调,结合文件选择插件来实现和原生Android类似的功能,具体步骤如下:

1. 添加依赖

在pubspec.yaml中引入所需的包:

dependencies:
  flutter:
    sdk: flutter
  webview_flutter: ^4.4.0  # 使用稳定版本
  file_picker: ^5.5.0       # 用于唤起文件选择器
  permission_handler: ^10.2.0 # 可选,用于动态申请权限

2. 配置WebView的文件选择回调

通过WebChromeClient的onShowFileChooser方法拦截WebView的文件选择请求,调用文件选择器并返回结果:

import 'dart:async';
import 'dart:io';
import 'package:flutter/material.dart';
import 'package:webview_flutter/webview_flutter.dart';
import 'package:file_picker/file_picker.dart';
import 'package:permission_handler/permission_handler.dart';

class WebViewWithFilePicker extends StatefulWidget {
  final String targetUrl;

  const WebViewWithFilePicker({super.key, required this.targetUrl});

  @override
  State<WebViewWithFilePicker> createState() => _WebViewWithFilePickerState();
}

class _WebViewWithFilePickerState extends State<WebViewWithFilePicker> {
  late WebViewController _webViewController;

  @override
  void initState() {
    super.initState();
    _setupWebViewController();
    _requestPermissions(); // 提前申请文件访问权限
  }

  // 动态申请文件访问权限
  Future<void> _requestPermissions() async {
    if (Platform.isAndroid) {
      if (await Permission.storage.request().isGranted ||
          await Permission.manageExternalStorage.request().isGranted) {
        // 权限已获取
      }
    }
  }

  void _setupWebViewController() {
    _webViewController = WebViewController()
      ..setJavaScriptMode(JavaScriptMode.unrestricted) // 必须开启JS支持
      ..setWebChromeClient(WebChromeClient(
        onShowFileChooser: (controller, params) async {
          // 根据WebView的请求决定是否允许多选
          FilePickerResult? result = await FilePicker.platform.pickFiles(
            type: FileType.any,
            allowMultiple: params.mode == FileChooserMode.openMultiple,
          );

          if (result != null) {
            // 将选中文件的路径转为Uri,返回给WebView
            List<Uri> selectedUris = result.files
                .where((file) => file.path != null)
                .map((file) => Uri.file(file.path!))
                .toList();
            params.onFileSelected(selectedUris);
            return true;
          }
          // 用户取消选择
          return false;
        },
      ))
      ..loadRequest(Uri.parse(widget.targetUrl));
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(title: const Text('WebView 文件选择')),
      body: WebViewWidget(controller: _webViewController),
    );
  }
}

3. 配置Android权限

在android/app/src/main/AndroidManifest.xml中添加必要的权限:

<!-- Android 13及以下读取外部存储权限 -->
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
<!-- Android 13+ 媒体文件权限 -->
<uses-permission android:name="android.permission.READ_MEDIA_IMAGES" />
<uses-permission android:name="android.permission.READ_MEDIA_VIDEO" />
<uses-permission android:name="android.permission.READ_MEDIA_AUDIO" />
<!-- 针对Android 10+的文件访问权限 -->
<uses-permission android:name="android.permission.MANAGE_EXTERNAL_STORAGE"
    tools:ignore="ScopedStorage" />

注意事项

  • 如果需要自定义文件选择页面,可以替换file_picker的调用为自己实现的文件选择UI,只要最终返回符合要求的Uri列表即可。
  • 不同Android版本的权限机制差异较大,需根据目标SDK版本调整权限申请逻辑。
  • 确保webview_flutter的版本支持onShowFileChooser回调(v3.0.0及以上版本已支持)。

内容的提问来源于stack exchange,提问作者giordy16

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.25 04:13:19