flutter 的 in_app_web_view实现下载功能

这篇具有很好参考价值的文章主要介绍了flutter 的 in_app_web_view实现下载功能。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

flutter与前端交互,利用in_app_web_view实现下载功能:

首先下载库,终端输入

flutter pub add flutter_inappwebview

之后导出

import 'package:flutter_inappwebview/flutter_inappwebview.dart';

即可使用。

创建in_app_web_view:

InAppWebView(
     initialOptions:
          InAppWebViewGroupOptions(
              crossPlatform:InAppWebViewOptions(
                useOnDownloadStart:true,
              ),
              android: AndroidInAppWebViewOptions()
          ),
      //老版本:initialUrl    新版本:initialUrlRequest
      initialUrlRequest: URLRequest(
        url: Uri.parse(widget.url),
      )
)

因为要下载文件,所以请务必手动设置 useOnDownloadStart 为 true(否则出发文件下载的监听)。

initialUrlRequest中可填写自己想首先打开的url地址。

可参考例子:flutter_inappwebview_examples/main.dart at main · pichillilorenzo/flutter_inappwebview_examples · GitHub

https://github.com/pichillilorenzo/flutter_inappwebview_examples/blob/main/file_download/lib/main.dart

填写自己需要的回调(例子中的一点错误,没有开启 useOnDownloadStart, 因此不会下载成功,在使用时请设置为true)

正常情况下,配合downloader和android_path_provider,普通https链接即可下载文件。

 文章来源地址https://www.toymoban.com/news/detail-474535.html

而遇到blob链接时,还需要进行更多操作来确保文件的下载:

可参考javascript - Flutter WebView blob pdf download - Stack Overflow

https://stackoverflow.com/questions/64865972/flutter-webview-blob-pdf-download/64902313#64902313

因为Android不支持blob链接下载,因此我们嵌套javascript处理下载链接,在in_app_web_view的build中重写onWebViewCreated方法,添加javascriptHandler:

onWebViewCreated: (InAppWebViewController controller) {
        if (mounted) {
          setState(() {
            _inAppWebCtrl = controller;
            _inAppWebCtrl!.addJavaScriptHandler(
              handlerName: 'blobToBase64Handler',
              callback: (data) async {
                if (data.isNotEmpty) {
                  final String receivedFileInBase64 = data[0];
                  final String receivedMimeType = data[1];

                  // NOTE: create a method that will handle your extensions
                  final String extension =
                  _mapMimeTypeToExtension(receivedMimeType);
                  String tmpFileName = 'tmpfile';
                  _createFileFromBase64(
                      receivedFileInBase64, tmpFileName, extension);
                }
              },
            );
          });
        }
      },

首先在assets中添加js文件夹,然后创建 base64.js 文件

var xhr = new XMLHttpRequest();
var blobUrl = "blobUrlPlaceholder";
console.log(blobUrl);
xhr.open('GET', blobUrl, true);
xhr.responseType = 'blob';
xhr.onload = function(e) {
  if (this.status == 200) {
    var blob = this.response;
    var reader = new FileReader();
    reader.readAsDataURL(blob);
    reader.onloadend = function() {
      var base64data = reader.result;
      var base64ContentArray = base64data.split(",");
      var mimeType = base64ContentArray[0].match(/[^:\s*]\w+\/[\w-+\d.]+(?=[;| ])/)[0];
      var decodedFile = base64ContentArray[1];
      console.log(mimeType);
      window.flutter_inappwebview.callHandler('blobToBase64Handler', decodedFile, mimeType);
    };
  };
};
xhr.send();

 

注意js中的callhander的名字参数,对应创建webview时addJavascriptHandler中的name。

另外是文件类型映射函数和文件下载函数:

  String _mapMimeTypeToExtension(String mimeType) {
    String extension = '';
    switch(mimeType) {
      case 'image/png': extension = 'png'; break;
      case 'application/msword': extension = 'doc'; break;
      case 'application/vnd.openxmlformats-officedocument.wordprocessingml.document':
        extension = 'docx';
        break;
      case 'image/jpeg': extension = 'jpg'; break;
      case 'image/gif': extension = 'gif'; break;
      case 'image/svg+xml': extension = 'svg'; break;
      case 'image/tiff': extension = 'tif'; break;
      case 'text/plain': extension = 'txt'; break;
      case 'application/vnd.ms-powerpoint': extension = 'ppt'; break;
      case 'application/vnd.openxmlformats-officedocument.presentationml.presentation':
        extension = 'pptx';
        break;
      case 'application/vnd.ms-excel': extension = 'xls'; break;
      case 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet':
        extension = 'xlsx';
        break;
      case 'application/zip': extension = 'zip'; break;
      case 'application/x-7z-compressed': extension = '7z'; break;
      case 'application/pdf': extension = 'pdf'; break;
    }
    return extension;
  }

  _createFileFromBase64(String base64content, String fileName, String yourExtension) async {
    var bytes = base64Decode(base64content.replaceAll('\n', ''));
    final file = File("$_localPath/$fileName.$yourExtension");
    await file.writeAsBytes(bytes.buffer.asUint8List());
    
  }

最后重写inappwebview中的下载请求方法:

      onDownloadStartRequest: (controller, downloadStartRequest) async {
          var jsContent = await rootBundle.loadString("assets/js/base64.js");
// 运行javascript代码解析blob
          await controller.evaluateJavascript(
              source: jsContent.replaceAll("blobUrlPlaceholder",
                  downloadStartRequest.url.toString()));
      },

总结:因为android本身不能解析blob,我们因此使用javascript作为翻译:运行顺序:

onDownloadStartRequest -> javascript文件 -> webviewController中的handler的callback,最后以流的方式写入文件。

 

到了这里,关于flutter 的 in_app_web_view实现下载功能的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • 移动端学习:实现App中的下载功能,在手机接管文件系统

    我感觉把学习中遇到的问题记录下来,写成文章,然后和很多人一起讨论,还是一个很不错的学习方法的。 请问有大佬知道vue2项目打包的apk的导出功能为什么失效了吗?网页,h5的应该还是可以下载的。我又不想导出功能和后端有交互,想纯前端下载,网页的下载写法好像打

    2024年02月22日
    浏览(38)
  • Java Web 实现文件上传和下载接口功能

    上传用post或者get请求都可以,这里代码中用post做的示例。 文件下载除了静态访问(及nginx、tomcat等服务器映射到后的文件web路径)下载以外 ,还可以通过流的方式下载,代码如下: 上传用post或者get请求都可以,这里代码中用post做的示例。  ForbiddenException 访问权限异常类

    2024年02月11日
    浏览(46)
  • uni-app web-view的使用

    在上一页点击需要跳转到app内置的浏览器里(app跳h5页面),uniapp提供了web-view 需要新建页面,在新页面里引用web-view,在新页面里才加上网址(h5) 1,在所需页面引入 1,在项目里(uni-app)运用(子传父) 3,html页面 https://gitee.com/dcloud/uni-app/raw/dev/dist/uni.webview.1.5.4.js

    2024年02月11日
    浏览(47)
  • uni-app之微信小程序实现‘下载+保存至本地+预览’功能

    目录 一、H5如何实现下载功能 二、微信小程序实现下载资源功能方面与H5有很大的不同 三、 微信小程序实现文件(doc,pdf等格式,非图片)下载(下载-保存-预览)功能 四、图片预览、保存、转发、收藏:uni.previewImage() 五、 我当前遇到‘关于文件预览uni.openDocument()’API的问

    2024年02月15日
    浏览(62)
  • uniapp 开发 APP 使用 web-view 引入H5 app与 h5 页面通信

    uniapp 可以同时兼容 APP 和 H5,但有时候有些功能在 APP 中实现不了而在 H5 中可以实现,就可以采用 web-view 的方式在 APP 模式下显示 H5 页面。但是 APP 和 H5 储存的参数是不能共享的,例如token,就涉及到 APP 与 H5 之间的参数传递。 H5 向 APP 传参:引入 webview.js ,调用 uni.postMes

    2024年02月13日
    浏览(45)
  • uni-app和web-view页面相互传参

    首先:这里说的是uni-app开发的APP项目,嵌入web-view页面,并进行相互传参,如果和您想了解的内容相符,请继续阅读。 一、说到web-view嵌入uni-app开发的APP,传参方面很多人首先会想到url传参。 这种方法是app向webview传参最简单的方式,但也存在许多弊端: 1.参数会被抓取,如

    2024年02月08日
    浏览(50)
  • 强大的Flutter App升级功能

    注意:无特殊说明,Flutter版本及Dart版本如下: Flutter版本: 1.12.13+hotfix.5 Dart版本: 2.7.0 应用程序升级功能是App的基础功能之一,如果没有此功能会造成用户无法升级,应用程序的bug或者新功能老用户无法触达,甚至损失这部分用户。 对于应用程序升级功能的重要性就无需赘

    2024年04月15日
    浏览(41)
  • uniapp web-view 小程序内嵌H5 打开地图 唤起APP

      uniapp开发小程序内嵌H5的场景中,有需求如下:   在已知某个地点经纬度的情况下,可以在H5打开地图查看该地点的位置,以及能够唤起手机上的地图APP进行导航等操作。   此时uni.openLocation在唤起导航的时候,是打开在线的导航链接,且会由于小程序的限制无法正常

    2024年02月16日
    浏览(58)
  • uni-app开发微信小程序 web-view通讯

    最近开发了一个微信小程序嵌套vue页面 vue页面 有时候会使用到微信小程序的api 但是有的api他h5是不支持的  官方文档中提供的两种方法 @message 内嵌的h5页面不支持 Window的postMessage 在h5端使用没啥问题,这该死的uni-app页面不管怎么弄都会报那个window的错  还是我太菜了。。。

    2024年02月19日
    浏览(60)
  • FlutterBoost 实现Flutter页面内嵌iOS view

    在使用Flutter混合开发中会遇到一些原生比Flutter优秀的控件,不想使用Flutter的控件,想在Flutter中使用原生控件。这时就会用到 Flutter页面中内嵌 原生view,这里简单介绍一个 内嵌 iOS 的view。 注:这里使用了 FlutterBoost。网上大部分都是代码执行不起来,本案例起码可以正常使

    2024年02月12日
    浏览(34)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包