Android應用整合Office檔案能力完全攻略
Android應用開啟office和pdf檔案。常用的有以下四種解決方案:
- 線上網頁開啟檔案方案:通過微軟或谷歌提供的線上頁面開啟office和pdf檔案
- 整合相關文件處理開源庫:通過整合開源庫類似於AndroidPdfViewer
- 通過系統中的第三方應用開啟文件
- 整合騰訊x5 sdk檔案能力
四種方案各有優劣,這裡筆者選擇了x5 sdk為主要手段,第三方應用輔助的這樣一種解決方案
二、整合x5核心
騰訊官方提供的x5核心有兩個版本,這裡選擇具有檔案能和的sdk:

接下來的整合可以參考x5核心接入文件,這裡便不詳述。整合的主要工作便是整合jar包和so檔案,並在Application初始化時呼叫QbSdk.initX5Environment(context, callback)來完成初始化工作。
三、整合TbsReader
x5核心中提供了TbsReaderView,讓我們可以通過這個類在App中顯示文件。考慮到TbsReaderView這個類具有生命週期的方法,我們把它封裝在一個Fragment中,方便我們的呼叫。TbsReaderView的主要方法有兩個,一個是preOpen(String, boolean),另一個是openFile(Bundle)。preOpen(String, boolean)是用來檢測x5檔案能力是否成功初始化和是否支援開啟檔案的格式,當符合開啟檔案的條件時該方法返回true;openFile(Bundle)則是在preOpen(String, boolean)的返回值為true的情況進行呼叫,顧名思義這個方法是用來開啟檔案的,其中bundle用來傳入檔案路徑。
String path = file.getPath(); String format = parseFormat(path); boolean preOpen = mReaderView.preOpen(format, false); // 該狀態標誌x5檔案能力是否成功初始化並支援開啟檔案的格式 if (preOpen) { // 使用x5核心開啟office檔案 Bundle bundle = new Bundle(); bundle.putString("filePath", path); bundle.putString("tempPath", StorageUtils.getTempDir(context).getPath()); mReaderView.openFile(bundle); } 複製程式碼
有了這部分核心程式碼,TbsReaderView基本上就能開啟Office和PDF檔案了。

四、完善檔案能力
市面上的安卓手機各式各樣,雖然集成了TbsReaderView,但是還是會收到使用者反饋說無法開啟Office檔案。這是因為使用者手機上的x5檔案能力沒有初始化成功,至於為什麼沒有初始化成功,原因還無法確定。針對這部分使用者,我們需要在他們無法使用TbsReaderView瀏覽Office檔案的情況下,提供另外的途徑去開啟Office檔案。大致思路是檢測到TbsReaderView無法開啟Office或PDF時,跳轉到第三方應用去開啟。這裡x5的jar包提供了這樣一個api:openFileReader(Context, String, HashMap<String, String>, ValueCallback)用來使用第三方應用開啟檔案,並且支援前往下載具有Office瀏覽功能的QQ瀏覽器,這樣的功能對使用者比較友好,我們可以直接拿來用。

然而,x5的jar包中使用第三方應用開啟時呼叫了Uri.fromFile(file),這個生成檔案Uri的方法在Android7.0以下有效,但在Android7.0及以上會造成崩潰,這是Android7.0的檔案許可權管理導致。為了使Android7.0及以上的使用者可以正常跳轉到第三方應用開啟,我們需要使用FileProvider去獲取Uri,但程式碼在Jar包中寫死了。幸運的是,經過多次嘗試,發現可以將跳轉到第三方應用開啟的這部分程式碼複製出來,修正Uri.fromFile(file)的程式碼以正常呼叫,免去了要修改jar的麻煩。這裡筆者把這部分程式碼封裝在一個叫TbsReaderAssist的類中,輔助呼叫。
這樣一來,一個比較完善的開啟Office和PDF的功能就算做完成。
String path = file.getPath(); String format = parseFormat(path); boolean preOpen = mReaderView.preOpen(format, false); // 該狀態標誌x5檔案能力是否成功初始化並支援開啟檔案的格式 if (preOpen) { // 使用x5核心開啟office檔案 Bundle bundle = new Bundle(); bundle.putString("filePath", path); bundle.putString("tempPath", StorageUtils.getTempDir(context).getPath()); mReaderView.openFile(bundle); } else { // 開啟檔案失敗,可能是由於x5核心未成功初始化引起 if (QbSdk.isSuportOpenFile(format, 1)) { // 再次檢查檔案是否支援 HashMap<String, String> params = new HashMap<>(); params.put("style", "1"); params.put("local", "false"); TbsReaderAssist.openFileReader(context, path, params, null); } } 複製程式碼
五、總結
這裡筆者寫了一個App開啟Office或PDF檔案的解決方案,個人認為對於一個App來說是相對完善的處理。這裡是demo的地址: github.com/windinwork/… ,共享出來,可以讓有需要做類似功能的小夥伴少走些彎路。