【问题标题】:Flutter - How to download files in WebView?Flutter - 如何在 WebView 中下载文件?
【发布时间】:2020-01-16 03:48:14
【问题描述】:

我正在使用flutter_webview_plugin: ^0.3.8,但webview_flutter: ^0.3.13 也有同样的问题。

在 webview 中,我想使用一个在成功完成验证码后触发文件下载的网站。但是,我完成了验证码,没有任何反应,没有下载。

Flutter 中有没有类似 webview 下载监听器(“webview.setDownloadListener”)的东西?我只在 Android 上需要这个。

如果没有,有没有办法从 Flutter 中的 webview 下载文件?

【问题讨论】:

  • 如果您是 html 和 js 端代码的所有者,请查看此答案 - stackoverflow.com/questions/56247542/…
  • 您在这里找到了解决方案,即使我也面临同样的问题。也尝试使用不同的包,但没有用,需要帮助!
  • 不,最后我只需要原生使用 webview。

标签: android flutter dart android-webview


【解决方案1】:

可以找到类似的问题here!

你可以使用我的插件flutter_inappwebview,这是一个Flutter插件,允许你添加内联WebViews或打开一个应用内浏览器窗口,并且有很多事件、方法和选项来控制WebViews。它可以识别Android(使用setDownloadListener)和iOS平台上的可下载文件!

我在这里报告了与类似问题相同的answer

为了能够识别可下载的文件,您需要设置useOnDownloadStart: true 选项,然后您才能监听onDownloadStart 事件!

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

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

然后,您需要使用permission_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 插件来获取我要保存文件的文件夹。

【讨论】:

  • 嗨@Lorenzo Pichilli,这不会将文件保存到下载文件夹。我该怎么做呢?
  • 这与flutter_inappwebview插件无关。我在这里写的只是一个例子。如果您需要指定另一个目录,请查看path_provider 插件文档!但是,Android 和 iOS 似乎不支持 getDownloadsDirectory 方法(参见 official doc
  • 好的,知道了!谢谢洛伦佐
【解决方案2】:

只需将此代码添加到您的 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>

并将此代码添加到您的 AndroidManifest.xml

对我有用

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2020-05-14
    • 2020-09-22
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-10-08
    • 2020-03-10
    相关资源
    最近更新 更多