cordova-plugin-file-opener2
插件在android@7.0.0
上會報編譯錯誤,換成cordova-plugin-vha-fileopener2
便可javascript
近期混合app項目中有文件預覽的需求,因文件較多並涉及office、視頻等文件格式,採用第三方app打開方案。
實現過程當中出現一些android7.0+/8.0+的兼容性問題,特此記錄。html
採用此預覽方案文件會被先下載到本地,cordova-plugin-file-opener2
插件其實能夠直接打開網絡地址來實現預覽,採用此方式是基於如下考慮:java
項目採用cordova + VUE + MintUI
android
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+
以上,不會出現文件權限的問題shell
採用Cordova開發的應用在運行的時候,Cordova提供的經過HTML5調用Native功能並非當即就能使用的,Cordova框架在讀入HTML5代碼以後,要進行HTML5和Native創建橋接,在未能完成這個橋接的初始的狀況下,是不能調用Native功能的。在Cordova框架中,當這個橋接的初始化完成後,會調用他自身特有的事件,即deviceready
事件。瀏覽器
deviceready事件是在每回讀入HTML的時候都會被調用,而不僅是應用啓動時調用。
安全
document.addEventListener("deviceready", function () { // 如今能夠安全的使用設備API console.log('Device is Ready!') }, false);
關於路徑的詳細解釋能夠查看文章:
官網API
cordova-plugin-file 文件操做整理系列網絡
使用cordova-plugin-file
插件建立有效的文件路徑app
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 |
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
文件時會報錯android.os.FileUriExposedException: file:///storage/emulated/0/test.apk exposed beyond app through Intent.getData()
根據cordova官網提示 在android 8.0+
上您的應用程序必須具備ACTION_INSTALL_PACKAGE
權限,須要在config.xml
添加以下配置:
<platform name="android"> <config-file parent="/manifest" target="AndroidManifest.xml" xmlns:android="http://schemas.android.com/apk/res/android"> <uses-permission android:name="android.permission.REQUEST_INSTALL_PACKAGES" /> </config-file> </platform>
注意安裝文件的路徑:在Android 7以前,您只能從「外部」分區安裝APK。例如,您能夠從中安裝cordova.file.externalDataDirectory
,但不能從中安裝cordova.file.dataDirectory
。Android 7+沒有這個限制。
並在AndroidManifest.xml
文件中修改SDK
版本
<uses-sdk android:minSdkVersion="16" android:targetSdkVersion="23" />
cordova/ionic默認配置16-26 通過屢次試,只支持16-23的sdk 版本。版本再高就報以上錯誤。
至此,Android5.0+已所有兼容。
Android的版本真的是一個大坑,第一次開發混合app被版本搞的焦頭爛額,但願能給各位看官一點幫助~若有疑問,歡迎溝通~