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
相关产品推荐
相关产品推荐

