博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
cordova插件之下载文件并打开
阅读量:6681 次
发布时间:2019-06-25

本文共 4785 字,大约阅读时间需要 15 分钟。

补充更新

cordova-plugin-file-opener2插件在android@7.0.0上会报编译错误,换成cordova-plugin-vha-fileopener2即可

前言

近期混合app项目中有文件预览的需求,因文件较多并涉及office、视频等文件格式,采用第三方app打开方案。

实现过程中出现一些android7.0+/8.0+的兼容性问题,特此记录。

采用此预览方案文件会被先下载到本地,cordova-plugin-file-opener2插件其实可以直接打开网络地址来实现预览,采用此方式是基于以下考虑:

  1. 避免重复下载(因app中还有下载功能)
  2. 避免有文件格式解析错误的情况,用户可以到本地再次进行查看
  3. 下载目录可控

框架

项目采用cordova + VUE + MintUI

安装插件

cordova plugin add cordova-plugin-filecordova plugin add cordova-plugin-file-transfercordova plugin add cordova-plugin-file-opener2

eg: cordova-plugin-file-openercordova-plugin-file-opener2这两个插件都可以打开文件,但cordova-plugin-file-opener2支持cdvfile://协议,兼容android7.0+以上,不会出现文件权限的问题

一、确认API环境

采用Cordova开发的应用在运行的时候,Cordova提供的通过HTML5调用Native功能并不是立即就能使用的,Cordova框架在读入HTML5代码之后,要进行HTML5和Native建立桥接,在未能完成这个桥接的初始的情况下,是不能调用Native功能的。在Cordova框架中,当这个桥接的初始化完成后,会调用他自身特有的事件,即deviceready事件。

deviceready事件是在每回读入HTML的时候都会被调用,而不只是应用启动时调用。

document.addEventListener("deviceready", function () {    // 现在可以安全的使用设备API    console.log('Device is Ready!')}, false);

二、创建有效的文件路径

关于路径的详细解释可以查看文章:

使用cordova-plugin-file插件创建有效的文件路径

Device Path cordova.file.* AndroidExtraFileSystems r/w? persistent? OS clears private
file:///android_asset/ applicationDirectory assets r N/A N/A Yes
/data/data/<app-id>/ applicationStorageDirectory - r/w N/A N/A Yes
   cache cacheDirectory cache r/w Yes Yes* Yes
   files dataDirectory files r/w Yes No Yes
      Documents documents r/w Yes No Yes
<sdcard>/ externalRootDirectory sdcard r/w Yes No No
   Android/data/<app-id>/ externalApplicationStorageDirectory - r/w Yes No No
      cache externalCacheDirectory cache-external r/w Yes No** No
      files externalDataDirectory files-external r/w Yes No No
  1. 当目标的WebView的客户(而不是浏览器)或本地应用程序(Windows),你不需要在使用持久性存储使用requestquota。
  2. 在沙盒目录结构中使用window.requestFileSystem
  3. 获取或操作系统文件/目录,可以使用window.resolveLocalFileSystemURL

Android7.0+遇到 android.os.FileUriExposedException: file:///storage/emulated.. exposed beyond app through Intent.getData()错误时,要使用window.resolveLocalFileSystemURLcordova.file.externalDataDirectory,不要使用沙盒目录结构

/** * desc: 创建文件方法 */window.resolveLocalFileSystemURL(  cordova.file.externalDataDirectory,  function(fs) {    fs.getFile(      _this.fileName, // 创建的文件名      { create: true, exclusive: true },      // create:创建新文件,exclusive:文件已存在时抛出异常      function(fileEntry) {        // 创建成功回调下载方法写入文件        _this.downloadFile(fileEntry);      },      function(err) {        // 失败回调        // 重新读取文件并打开        fs.getFile(          _this.fileName,          { create: false },          function(fileEntry) {            // 成功读取文件后调用cordova-plugin-file-opener2插件打开文件            _this.preView(fileEntry);          },          function(err) {            _this.toast('读取文件失败');          }        );      }    );  },  function(error) {    _this.toast('进入文件系统失败!');  });

三、下载文件

/** * desc: 文件下载方法 */function downloadFile(fileEntry) {  // 初始化进度条并显示  // 此处采用mint-ui的Progress组件  _this.progress = 0;  _this.showProgress = true;  //实例化  let fileTransfer = new FileTransfer();  //监听下载进度  fileTransfer.onprogress = function(e) {    if (e.lengthComputable) {      let progress = e.loaded / e.total;      // 显示下载进度      _this.progress = (progress * 100).toFixed(2);    }  };  // 使用fileTransfer.download开始下载  fileTransfer.download(    encodeURI(_this.savePath), //uri网络下载路径    fileEntry.toURL(), //文件本地存储路径    function(entry) {      // 下载完成执行本地预览      if (_this.progress > 1 || _this.progress === 1) {        _this.showProgress = false;        entry.file(data => {          _this.preView(fileEntry);          // 此处data.type可以直接得到文件的MIME-TYPE类型        });      }    },    function(error) {      _this.toast('下载失败!');    }  );}

四、打开文件

/** * desc: 文件打开方法 */function preview(fileEntry){    // 调用cordova-plugin-file-opener2插件实现用第三方app打开文件    cordova.plugins.fileOpener2.showOpenWithDialog(        // 此处必须填写cdvfile://地址,不然android7.0+会报文件权限错误        fileEntry.toInternalURL(), //文件本地地址转cdvfile://地址        fileTypeArr[_this.fileType], //文件类型,这里我是写了一个mime-Type类型合集fileTypeArr来调用         function onSuccess(data) {            console.log('成功预览:' + fileURL);        },        function onError(error) {            _this.toast(                '出错!请在' + cordova.file.externalDataDirectory + '目录下查看'            );        }    );}

五、Android8.0+打开apk文件权限问题

Android8.0+上打开apk文件时会报错android.os.FileUriExposedException: file:///storage/emulated/0/test.apk exposed beyond app through Intent.getData()

根据cordova官网提示 在android 8.0+上您的应用程序必须具有ACTION_INSTALL_PACKAGE权限,需要在config.xml添加如下配置:

注意安装文件的路径:在Android 7之前,您只能从“外部”分区安装APK。例如,您可以从中安装cordova.file.externalDataDirectory,但不能从中安装cordova.file.dataDirectory。Android 7+没有这个限制。

并在AndroidManifest.xml文件中修改SDK版本

cordova/ionic默认配置16-26 经过多次试,只支持16-23的sdk 版本。版本再高就报以上错误。

结语

至此,Android5.0+已全部兼容。

Android的版本真的是一个大坑,第一次开发混合app被版本搞的焦头烂额,希望能给各位看官一点帮助~

如有疑问,欢迎沟通~

转载地址:http://lniao.baihongyu.com/

你可能感兴趣的文章
Uboot分析(三)
查看>>
设计模式:桥接模式(Bridge Pattern)
查看>>
Codeforces 606-C:Sorting Railway Cars(LIS)
查看>>
eclipse ldt update resource
查看>>
java-HTML&javaSkcript&CSS&jQuery&ajax
查看>>
RESTful API 设计最佳实践
查看>>
移动端自动化==>什么是Appium
查看>>
antd递归渲染左侧菜单
查看>>
数塔(hdoj 2084,动态规划递推)
查看>>
IP通信基础第二周
查看>>
Theano mnist数据集格式
查看>>
字体图标的优缺点
查看>>
windows自带的压缩,解压缩命令
查看>>
一次有趣的XSS漏洞挖掘分析(1)
查看>>
BZOJ 4070 [Apio2015]雅加达的摩天楼 ——分块 SPFA
查看>>
经典最小二乘法
查看>>
Vue.js安装
查看>>
XNA 游戏 运行时编辑器
查看>>
.Net Core建站(1):EF Core+CodeFirst数据库生成
查看>>
UVA 12672 Eleven(DP)
查看>>