简体   繁体   中英

How do I enable my Android Application users to download a WebView for later use dart and Flutter

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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM