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

webview_flutter安卓端文件上传失效问题求助

安卓端webview_flutter文件上传解决方案

核心问题

安卓版webview_flutter默认未启用文件选择的相关回调与权限配置,导致前端文件上传组件无法触发系统文件选择器。

具体解决步骤

1. 添加安卓权限

在安卓项目的android/app/src/main/AndroidManifest.xml中添加对应权限:

  • 安卓12及以下:
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" android:maxSdkVersion="32" />
  • 安卓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" />

同时在application标签下添加Scoped Storage兼容配置:

<application
    ...
    android:requestLegacyExternalStorage="true">

2. 配置webview_flutter的WebChromeClient

自定义WebChromeClient,重写onShowFileChooser方法处理文件选择请求,调用系统文件选择器并返回结果给WebView:

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

class CustomWebChromeClient extends WebChromeClient {
  final WebViewController controller;

  CustomWebChromeClient(this.controller);

  @override
  bool onShowFileChooser(
      WebViewController controller,
      FileChooserParams params,
      ) async {
    // 使用file_picker支持全类型文件选择
    final result = await FilePicker.platform.pickFiles(
      allowMultiple: params.mode == FileChooserMode.openMultiple,
      type: FileType.any,
    );

    if (result != null) {
      // 将选中文件的URI传递给WebView
      final uris = result.files.map((file) => Uri.file(file.path!).toString()).toList();
      controller.onFileChooserComplete(uris);
    }
    return true;
  }
}

// 在WebView组件中使用
WebView(
  initialUrl: '你的Vue应用地址',
  javascriptMode: JavascriptMode.unrestricted,
  webChromeClient: CustomWebChromeClient(controller),
  // 其他配置...
)

3. 确认前端代码兼容性

确保Vue端使用标准文件上传组件并正确处理选择事件:

<template>
  <input type="file" @change="handleUpload" :multiple="true" />
</template>

<script>
export default {
  methods: {
    handleUpload(event) {
      const files = event.target.files;
      if (!files.length) return;

      const formData = new FormData();
      Array.from(files).forEach(file => formData.append('upload_files', file));

      // 执行上传请求
      fetch('/api/upload', {
        method: 'POST',
        body: formData
      }).then(res => {
        // 处理上传结果
      });
    }
  }
}
</script>

4. 适配安卓Scoped Storage

若安卓10+出现文件访问权限问题,可将选中文件复制到应用沙盒目录后再传递给WebView,避免URI权限失效:

import 'dart:io';
import 'package:path_provider/path_provider.dart';

// 在文件选择后添加复制逻辑
final tempDir = await getTemporaryDirectory();
final copiedFiles = <File>[];
for (var file in result.files) {
  final originalFile = File(file.path!);
  final copiedFile = await originalFile.copy('${tempDir.path}/${file.name}');
  copiedFiles.add(copiedFile);
}
// 传递沙盒内的文件URI给WebView
final uris = copiedFiles.map((file) => Uri.file(file.path).toString()).toList();
controller.onFileChooserComplete(uris);

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.16 05:42:48