Hi I'm trying to create a reading app that allows user to save pages for offline use from my online learning website. It uses the web view widget to access the webpage.
import 'dart:async';
import 'package:flutter/material.dart';
import 'package:webview_flutter/webview_flutter.dart';
class ScholarshipsPage extends StatefulWidget {
@override
_ScholarshipsPageState createState() => _ScholarshipsPageState();
}
class _ScholarshipsPageState extends State<ScholarshipsPage> {
Completer<WebViewController> _controller = Completer<WebViewController>();
@override
Widget build(BuildContext context) {
return new Scaffold(
appBar: AppBar(
title: Text('Scholarship Research Program'),
backgroundColor: Colors.deepPurple,
elevation: 0,
centerTitle: true,
),
body: WebView(
initialUrl: 'https://mydigitalbackpack.net/scholarshipresearchprogram/',
javascriptMode: JavascriptMode.unrestricted,
onWebViewCreated: (WebViewController controller) {
_controller.complete(controller);
},
)
);
}
}
Please check this answer if you are the owner of the html page: https://stackoverflow.com/a/59899281/5513788
If not, see here: Flutter - How to download files in WebView? and here: https://github.com/flutter/flutter/issues/26373 . Basically it's not possible at the moment.
For my app, what I did was set this up natively in Android using Java and that worked very well.
This is not possible with the webview_flutter
plugin because those features are missing.
Instead, 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.
In your case, you can use the InAppWebViewController.android.saveWebArchive
method to save the current WebView as a web archive. At the moment, this method is available only for Android (it is implemented through the WebView#saveWebArchive official Android API)!
I will check how to implement the same thing for iOS if possible.
Instead, if you need to download files: 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.
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.