不一樣於iOS,Android的webView不支持打開office和pdf文檔,因此當咱們遇到在應用內打開office和pdf文檔的需求時,每每沒法從系統原生功能去支持。這篇文章的寫下筆者在Android應用中集成office和pdf文件能力的心得,附上demo地址:github.com/windinwork/…html
Android應用打開office和pdf文件。經常使用的有如下四種解決方案:git
四種方案各有優劣,這裏筆者選擇了x5 sdk爲主要手段,第三方應用輔助的這樣一種解決方案github
騰訊官方提供的x5內核有兩個版本,這裏選擇具備文件能和的sdk:web
接下來的集成能夠參考x5內核接入文檔,這裏便不詳述。集成的主要工做即是集成jar包和so文件,並在Application初始化時調用QbSdk.initX5Environment(context, callback)來完成初始化工做。api
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文件了。bash
市面上的安卓手機各式各樣,雖然集成了TbsReaderView,可是仍是會收到用戶反饋說沒法打開Office文件。這是由於用戶手機上的x5文件能力沒有初始化成功,至於爲何沒有初始化成功,緣由還沒法肯定。針對這部分用戶,咱們須要在他們沒法使用TbsReaderView瀏覽Office文件的狀況下,提供另外的途徑去打開Office文件。大體思路是檢測到TbsReaderView沒法打開Office或PDF時,跳轉到第三方應用去打開。這裏x5的jar包提供了這樣一個api:openFileReader(Context, String, HashMap<String, String>, ValueCallback)用來使用第三方應用打開文件,而且支持前往下載具備Office瀏覽功能的QQ瀏覽器,這樣的功能對用戶比較友好,咱們能夠直接拿來用。ide
然而,x5的jar包中使用第三方應用打開時調用了Uri.fromFile(file),這個生成文件Uri的方法在Android7.0如下有效,但在Android7.0及以上會形成崩潰,這是Android7.0的文件權限管理致使。爲了使Android7.0及以上的用戶能夠正常跳轉到第三方應用打開,咱們須要使用FileProvider去獲取Uri,但代碼在Jar包中寫死了。幸運的是,通過屢次嘗試,發現能夠將跳轉到第三方應用打開的這部分代碼複製出來,修正Uri.fromFile(file)的代碼以正常調用,免去了要修改jar的麻煩。這裏筆者把這部分代碼封裝在一個叫TbsReaderAssist的類中,輔助調用。ui
這樣一來,一個比較完善的打開Office和PDF的功能就算作完成。spa
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/…,共享出來,可讓有須要作相似功能的小夥伴少走些彎路。