Flutter - How to download files in WebView?
A similar issue can be found here!
You can use my plugin flutter_inappwebview, which is a Flutter plugin that allows you to add inline WebViews or open an in-app browser window and has a lot of events, methods, and options to control WebViews. It can recognize downloadable files in both Android (using setDownloadListener
) and iOS platforms!
I report here the same answer that I gave to the similar issue:
To be able to recognize downloadable files, you need to set the useOnDownloadStart: true
option, and then you can listen the onDownloadStart
event!
Also, for example, on Android you need to add write permission inside your AndroidManifest.xml
file:
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
Then, you need to ask permission using the permission_handler plugin. Instead, to effectively download your file, you can use the flutter_downloader plugin.
Here is a complete example using http://ovh.net/files/ (in particular, the http://ovh.net/files/1Mio.dat as URL) to test the download:
import 'dart:async';import 'package:flutter/material.dart';import 'package:flutter_inappwebview/flutter_inappwebview.dart';import 'package:flutter_downloader/flutter_downloader.dart';import 'package:path_provider/path_provider.dart';import 'package:permission_handler/permission_handler.dart';Future main() async { WidgetsFlutterBinding.ensureInitialized(); await FlutterDownloader.initialize( debug: true // optional: set false to disable printing logs to console ); await Permission.storage.request(); runApp(new MyApp());}class MyApp extends StatefulWidget { @override _MyAppState createState() => new _MyAppState();}class _MyAppState extends State<MyApp> { InAppWebViewController webView; @override void initState() { super.initState(); } @override void dispose() { super.dispose(); } @override Widget build(BuildContext context) { return MaterialApp( home: Scaffold( appBar: AppBar( title: const Text('InAppWebView Example'), ), body: Container( child: Column(children: <Widget>[ Expanded( child: InAppWebView( initialUrl: "http://ovh.net/files/1Mio.dat", initialHeaders: {}, initialOptions: InAppWebViewGroupOptions( crossPlatform: InAppWebViewOptions( debuggingEnabled: true, useOnDownloadStart: true ), ), onWebViewCreated: (InAppWebViewController controller) { webView = controller; }, onLoadStart: (InAppWebViewController controller, String url) { }, onLoadStop: (InAppWebViewController controller, String url) { }, onDownloadStart: (controller, url) async { print("onDownloadStart $url"); final taskId = await FlutterDownloader.enqueue( url: url, savedDir: (await getExternalStorageDirectory()).path, showNotification: true, // show download progress in status bar (for Android) openFileFromNotification: true, // click on notification to open downloaded file (for Android) ); }, )) ])), ), ); }}
Here, as you can see, I'm using also the path_provider plugin to get the folder where I want to save the file.
just add this code to your AndroidManifest.xml
<provider android:name="vn.hunghd.flutterdownloader.DownloadedFileProvider" android:authorities="${applicationId}.flutter_downloader.provider" android:exported="false" android:grantUriPermissions="true"> <meta-data android:name="android.support.FILE_PROVIDER_PATHS" android:resource="@xml/provider_paths"/> </provider>
and add this code to your AndroidManifest.xml
it works to me