cordova打开文件_cordova插件之下载文件并打开

补充更新

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

前言

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

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

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

避免重复下载(因app中还有下载功能)

避免有文件格式解析错误的情况,用户可以到本地再次进行查看

下载目录可控

框架

项目采用cordova + VUE + MintUI

安装插件

cordova plugin add cordova-plugin-file

cordova plugin add cordova-plugin-file-transfer

cordova plugin add cordova-plugin-file-opener2

eg: cordova-plugin-file-opener和cordova-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//

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

/

externalRootDirectory

sdcard

r/w

Yes

No

No

Android/data//

externalApplicationStorageDirectory

-

r/w

Yes

No

No

cache

externalCacheDirectory

cache-external

r/w

Yes

No**

No

files

externalDataDirectory

files-external

r/w

Yes

No

No

当目标的WebView的客户(而不是浏览器)或本地应用程序(Windows),你不需要在使用持久性存储使用requestquota。

在沙盒目录结构中使用window.requestFileSystem

获取或操作系统文件/目录,可以使用window.resolveLocalFileSystemURL

Android7.0+遇到 android.os.FileUriExposedException: file:///storage/emulated.. exposed beyond app through Intent.getData()错误时,要使用window.resolveLocalFileSystemURL和cordova.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被版本搞的焦头烂额,希望能给各位看官一点帮助~

如有疑问,欢迎沟通~

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值