Flutter: File Upload using WebView on Android
WebViews are one of the most common widgets in Flutter applications. We can use a WebView to add a functionality in the application where the logic can reside entirely in the server. Thankfully we have a lot of WebView plugins to choose from in the pub.dev repository. However, the basic functionality of supporting file upload from the HTML pages on Android was lacking for a good few years.
The webview_flutter plugin, created by the Flutter team, is one of the most popular WebView plugins. It uses WKWebView on iOS and WebView on Android as native libraries. This plugin contains tons of features that we can use in our application just as JavaScript communication, Cookie Manager, Media Playback functionality, etc.
The Flutter team has recently fixed this bug and now we can finally have file upload using Webview on both Android & iOS platforms. In this tutorial, we are going to implement file upload functionality on both platforms.
Step 1: Add dependency to pubspec.yaml
Get the latest version number of webview_flutter and add it to your pubspec.yaml.
Step 2: Add WebView to the Widget
Firstly create the instance of WebViewController
. It’s better to create it the initState
function of the widget.
late final WebViewController controller;
@override
void initState() {
controller = WebViewController();
controller.loadRequest(
Uri.parse("https://theprogrammingway.com/html-file-upload/"));
super.initState();
}
Next, assign the controller
to WebView
widget.
@override
Widget build(BuildContext context) {
return WebViewWidget(controller: controller);
}
Now run this application, it will open a web page with a Choose File button. If you open this link on your laptop, Chrome, or any other browser on your Android phone and tap on the button, it will ask you to select files to upload. However, in Flutter WebView, nothing happens if you tap the button.
We are going to fix this issue next.
Step 3: Add File upload functionality in Android WebView
Import the following dependency
import 'package:webview_flutter_android/webview_flutter_android.dart';
Create a function addFileSelectionListener
and call it from initState
.
void addFileSelectionListener() async {
if (Platform.isAndroid) {
final androidController = controller.platform as AndroidWebViewController;
await androidController.setOnShowFileSelector(_androidFilePicker);
}
}
The Platform.isAndroid
will ensure that the code is executed on the Android platform only. In the code, we first get the AndroidWebViewController
and then call setOnShowFileSelector
function, whenever button with <input type="file">
is tapped.
Step 4: Handle setOnShowFileSelector callback
To handle file upload functionality, we will use file_picker library. Add it to your pubspec.yaml. Next, we will create a function call
Future<List<String>> _androidFilePicker(final FileSelectorParams params) async {
final result = await FilePicker.platform.pickFiles();
if (result != null && result.files.single.path != null) {
final file = File(result.files.single.path!);
return [file.uri.toString()];
}
return [];
}
FileSelectorParams
contains a parameter called acceptTypes
which contains a list of all accepted MIME types. It can be used to decide which type of file is requested by the webpage.
That’s it, now if you tap on the Choose File button, you will see that the Files app will open and you can select a file.
That’s it, now you should be able to upload files from Flutter WebView on Android. Please find the complete gist on GitHub.
Many Thanks.
great sir, thanks a lot, you save me.
Is there a way to do the same thing for ios?
How could I let the user select between capturing a photo or selecting files?
You can choose a library like file_picker and add a filter for it.