如何通过Flutter中的WebView下载/创建PDF



我已经创建了一个WebView -Scaffold,但是从WebView浏览时无法从中下载任何内容,但是当我单击按钮时,它无能为力。我不知道从哪里开始,例如在可以下载和预览的其他浏览器中,我正在尝试在这里实现同样的事情。

class AppState extends State<App> {

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      body: Stack(
        children: <Widget>[
          Align(
            alignment: Alignment(1, 1),
            child: Container(
              child: Web(), // it is a statefulwidget that have WebviewScaffold, i have created it on a new page and imported/used here
            ),
          ),
          Column(
            mainAxisAlignment: MainAxisAlignment.end,
            children: <Widget>[
              Padding(
                padding: EdgeInsets.only(top: 20.0),
              )
            ],
          ),
          Align(
            alignment: Alignment(0.7, -0.93),
            child: FloatingActionButton(
                tooltip: "Share",
                child: Icon(
                  Icons.share,
                  color: Colors.amberAccent,
                ),
                onPressed: () {
                  _onShareTap();
                }),
          ),
        ],
      ),
    );
  }

我希望,当我单击WebView中的打印或下载按钮时,它应该像其他任何浏览器一样工作。

您可以使用我的插件Flutter_InappWebView,这是一个乱七八糟的插件,可让您添加Inline WebView或打开应用程序内浏览器窗口,并具有许多事件,方法和选项到控制WebViews。

要识别可下载的文件,您需要设置useOnDownloadStart: true选项,然后您可以收听onDownloadStart事件!

另外,例如,在Android上,您需要在AndroidManifest.xml文件中添加写入权限:

<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>

然后,您需要使用climermission_handler插件询问权限。相反,要有效下载文件,您可以使用Flutter_Downloader插件。

这是一个完整的示例,使用http://ovh.net/files/(尤其是http://ovh.net/files/1mio.dat作为URL(来测试下载:

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)
              );
            },
          ))
        ])),
      ),
    );
  }
}

您可以看到,我还使用path_provider插件来获取我要保存文件的文件夹。

如果您是HTML页面的所有者,则可以检查对我有用的解决方案。在您的 html页面的来源中

function downloadpdf() {
      var currentHref = window.location.href;
      window.history.pushState(null, null, '/app/somepdf.pdf');
      setTimeout(() => window.location.replace(currentHref), 1000);
}

在Flutter代码中添加侦听器:

StreamSubscription<String> _onWebViewUrlChanged;
_onWebViewUrlChanged =
    FlutterWebviewPlugin().onUrlChanged.listen((String url) {
      if (url.contains('.pdf')) {
        launchURL(url);
      }
});

启动器将在外部浏览器窗口中打开预定义的URL。因此,您可以从flutter_webview_plugin下载pdf/etc。

您应该添加一些特定应用的JS/Flutter Magic

最新更新