Android应用打开office和pdf文件。常用的有以下四种解决方案:
四种方案各有优劣,这里笔者选择了x5 sdk为主要手段,第三方应用辅助的这样一种解决方案
腾讯官方提供的x5内核有两个版本,这里选择具有文件能和的sdk:
接下来的集成可以参考x5内核接入文档,这里便不详述。集成的主要工作便是集成jar包和so文件,并在Application初始化时调用QbSdk.initX5Environment(context, callback)来完成初始化工作。
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/… ,共享出来,可以让有需要做类似功能的小伙伴少走些弯路。