为什么需要在Android应用内打开PDF、Word、Excel等文档?

由于公司项目有一部分功能是能观看新闻,但是这些新闻的内容并不都是一个HTML或者链接直接可以使用Android WebView直接打开,而是这些新闻详情中含有各种类型的文档都存在比如:PDF、Word、Excel等等文档。由于之前赶项目的时候,处理方式是直接调用系统浏览器下载查看,项目快完结时,公司老大说我们需要将我们的新闻在我们自己的应用内部打开,这样显得我们专业,而且友好,让我们去想个方案,至此需求就出来。

我相信Android 开发的都是想打人的,为啥IOS直接使用系统WebView就能直接打开所有文档,而我们就不行。这话说来就要怪Google爸爸了,Google爸爸其实是有方案解决,就是使用Google Service。但是由于国内的网络原因,所以这种方法只能放弃了。

我相信这个可能有很多的解决方法,但是我这是只是记录一下我自己的解决方法,如果还有更好的方法,还希望各位给我指出,感谢。

先看看我的实现效果图:

解决方法


我这里是使用腾讯的TBS内核,来替换掉Android 原生的WebView。至于为什么使用X5内核呢?理由有几点:

腾讯大佬的东西(虽然讨论区还是有些BUG,但是不影响大局)

微信、QQ都是使用的TBS内核

使用的TBS内核的人多,讨论区热闹,有很多的解决方案。

TBS内核优点:

1. TBS(腾讯浏览服务)的优势

1) 速度快:相比系统webview的网页打开速度有30+%的提升;

2) 省流量:使用云端优化技术使流量节省20+%;

3) 更安全:安全问题可以在24小时内修复;

4) 更稳定:经过亿级用户的使用考验,CRASH率低于0.15%;

5) 兼容好:无系统内核的碎片化问题,更少的兼容性问题;

6) 体验优:支持夜间模式、适屏排版、字体设置等浏览增强功能;

7) 功能全:在Html5、ES6上有更完整支持;

8) 更强大:集成强大的视频播放器,支持视频格式远多于系统webview;

9) 视频和文件格式的支持x5内核多于系统内核

10) 防劫持是x5内核的一大亮点

2. 运行环境

1)手机ROM版本高于或等于2.2版本

2)手机RAM大于500M,该RAM值通过手机 /proc/meminfo 文件的MemTotal动态获取

注:如果不满足上述条件,SDK会自动切换到系统WebView,SDK使用者不用关心该切换过程。

3. SDK尺寸指标

1)SDK提供的JAR包约250K

不想听我啰嗦的可以直接戳这里:http://x5.tencent.com/tbs/guide.html

TBS内核的文件能力

APP在接入文件服务后,即可支持主流9种格式。升级文件服务后,可支持46种文件格式。

接入TBS


如果不想看我写的,可以直接看官网的接入流程。可以直接戳下面的链接直接看官网的SDK接入流程:TBS接入官网 https://x5.tencent.com/tbs/guide/sdkInit.html

1、导入Jar包

官网下载好Android Studio接入示例,将TBS jar包放入libs文件夹下面如图:

申请必要的权限:

<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.DOWNLOAD_WITHOUT_NOTIFICATION"/>
<uses-permission android:name="android.permission.ACCESS_DOWNLOAD_MANAGER"/>
<uses-permission android:name="android.permission.WRITE_SETTINGS"/>
<uses-permission android:name="android.permission.READ_PHONE_STATE"/>

2、初始化TBS

一般TBS的X5内核初始化是放在Application中进行,如图是我的项目中初始化地方:

下面是系统WebView的类和tbs内核的类的区别:


tbs的内核的类名和系统的基本一致,而且使用方法也是一致,这里就不赘述了。

3、64位手机

这个是TBS官网的解释:

x5内核暂时不提供64位的so文件,在64位手机上需要让APP以32位模式运行。具体操作如下:
1.如果使用是Eclipse则需要将所有的.so文件都放置在so加载目录:lib/armeabi文件夹下(没有该目录则新建一个,AP中没有使用到.so文件则需要拷贝任意一个32位的so文件到该目录下,如果没有合适的so可以到官网http://x5.tencent.com/tbs/sdk.html下载官网“SDK接入示例“,拷贝对应目录下的liblbs.so文件),lib文件夹下不要有其他以”armeabi“开头的文件夹。
2.如果使用的是 Android studio则需要进行两项配置,
(1)打开对应module中的build.gradle文件,在文件的android{}中的defaultConfig{}里(如果没有defaultConfig{}则手动添加)添加如下配置: ndk{abiFilters “armeabi”},如果配置后编译报错,那么需要在gradle.properties文件中加上Android.useDeprecatedNdk=true;
(2)找出build.gradle中配置的so加载目录:jniLibs.srcDir:customerDir,如果没有该项配置则so加载目录默认为:src/main/jniLibs,需要将.so文件都放置在so加载目录的armeabi文件夹下(没有该目录则新建一个,AP中没有使用到.so文件则需要拷贝任意一个32位的so文件到该目录下,如果没有合适的so可以到官网http://x5.tencent.com/tbs/sdk.html下载官网“SDK接入示例“,拷贝对应目录下的liblbs.so文件),so加载目录下不要有其他以”armeabi“开头的文件夹。

我就用我的接入的图片说明:

1.添加32位的so库

这个liblbs.so文件可以是任意的32位的so文件,我们一般自己难得去找,或者你有现成的更好,这里我直接拷贝示例里面的:

2.在 app/build.gradle 文件中对 libs 目录中 jar 文件的依赖

dependencies {compile fileTree(dir: 'libs', include: ['*.jar'])
}

3.**需要注意的是:**TBS 目前只提供 armeabi 类型 CPU 架构的 so 库。当然,也可以将 so 文件放置于 libs 目录下,只不过需要在 app/build.gradle 中额外修改 so 文件依赖配置:

sourceSets {main {jniLibs.srcDirs = ['libs']}}

那么我们要怎么确认是否这个TBS的X5内核已经加载成功了呢?
如下图,当你长按选择复制的时候出现下面的蓝色水滴状就表示tbs的X5内核加载成功:

4、下载文件到本地

下载文件到本地,我们就使用系统的http请求来下载文件,假如你开发中用的Okhttp或者其他的网络框架,直接使用网络框架下载就好了。代码如下:

/*** 下载文件并使用TBS打开文件** @param url 下载的路径* @param fileName  保存的文件的名字* @param fileType  我们需要打开的文件的类型  word类型 doc  excel类型xls  pdf类型 pdf等等,这个可以在官网上查* @throws IOException*/private void downLoadFile(URL url, String fileName, String fileType) throws IOException {new Thread(new Runnable() {@Overridepublic void run() {try {final HttpURLConnection connection = (HttpURLConnection) url.openConnection();//获取总的文件大小connection.setRequestMethod("GET");//试过POST 可能报错connection.setDoInput(true);connection.setConnectTimeout(10000);connection.setReadTimeout(10000);//实现连接connection.connect();if (connection.getResponseCode() == 200) {//获取内容长度int contentLength = connection.getContentLength();inputStream = connection.getInputStream();File dir = mContext.getExternalFilesDir(Environment.DIRECTORY_DOWNLOADS);file = new File(dir, fileName);if (file.exists()) {file.delete();}fileOutputStream = new FileOutputStream(file);byte[] bytes = new byte[1024];int tempLen;long totalReaded = 0;while ((tempLen = inputStream.read(bytes)) != -1) {// bytes[index]= (byte) temp_Len;// index++;totalReaded += tempLen;final int progress = (int) (totalReaded * 100 / contentLength);mContext.runOnUiThread(() -> binding.progress.setProgress(progress));fileOutputStream.write(bytes, 0, tempLen);}}} catch (Exception e) {Logger.e("文件下载异常");} finally {if (fileOutputStream != null) {try {fileOutputStream.close();} catch (IOException e) {e.printStackTrace();}}if (inputStream != null) {try {inputStream.close();} catch (IOException e) {e.printStackTrace();}}}}});}

5、TbsReaderView加载文件

创建TbsReaderView:

mTbsReaderView = new TbsReaderView(this, this);
RelativeLayout rootRl = (RelativeLayout) findViewById(R.id.rl_root);
rootRl.addView(mTbsReaderView, new RelativeLayout.LayoutParams(LayoutParams.MATCH_PARENT,
LayoutParams.MATCH_PARENT))

Activity 中实现 ReaderCallback 接口,并通过 Java 代码动态创建 TbsReaderView 对象,将其添加到 content view 当中。

实现ReaderCallback 接口,重写方法:

@Override
public void onCallBackAction(Integer integer, Object o, Object o1) {}

暂不知这个方法有什么用,我也没使用到,所以未深究。

可能你会有疑惑,为什么不将 TbsReaderView 放在 layout 布局文件中,而是在代码中手动 add 进去。经测试,这么做会报错,提示找不到这个类。然后我们查看 TbsReaderView 源码,发现只有这么一个构造函数:

public TbsReaderView(Context var1, TbsReaderView.ReaderCallback var2) {super(var1.getApplicationContext());if(!(var1 instanceof Activity)) {throw new RuntimeException("error: unexpect context(none Activity)");} else {this.d = var2;this.a = var1;this.e = new au(this);}
}

最后一步传入参数,打开文件即可:

private void displayFile() {Bundle bundle = new Bundle();bundle.putString("filePath", file.getPath());bundle.putString("tempPath", Environment.getExternalStorageDirectory().getPath());boolean result = mTbsReaderView.preOpen(fileType, false);if (result) {mTbsReaderView.openFile(bundle);}
}

说明下这里的fileType是一个字符串类型的,其实就是文件的后缀名,例如Word类型的是“doc” 、 PDF的类型是“pdf”,一般可以通过url来截取到类型。

总结

Android 应用中打开文件,上面只是我个人的项目使用的方法,当然还有其他的方法。欢迎大家都去尝试,其实一般这种按照官网的文档来做是没有什么问题的,但是说实话文档还是有点简陋,只有自己动手去做才比较清楚。还有点就是告诉大家:tbs的X5内核还是有问题的,并不是说腾讯的都没问题,可以去tbs的讨论区看看都有哪些问题,然后根据这些问题,确定自己的项目是否适合使用。

原创不易,如果觉得写得好,扫码关注一下点个赞,是我最大的动力。


关注我,一定会有意想不到的东西等你:
每天专注分享Android、JAVA干货


备注:程序圈LT

Android 应用内部打开PDF、Excel、Word文档你们Get了么?相关推荐

  1. python pdf open打开非常慢_openoffice打开大的word文档很慢而且兼容性极差

    你的位置: 问答吧 -> Debian -> 问题详情 openoffice打开大的word文档很慢而且兼容性极差 如题,各位碰到么?我只好用永中,但是永中对于有些图片类的中文(如一些专业 ...

  2. 办公知识:有关如何PDF转Word文档的方法分享

    现在我们从网上下载的资料文献大部分都是PDF格式,由于PDF格式无法自由编辑的性质,想要获取文档中的内容只能一字一句复制粘贴过去,这样做不仅耽误工作进度还耗费精力. 这时候其实可以将PDF转换为可编辑 ...

  3. PoiDocxDemo【Android将表单数据生成Word文档的方案之二(基于Poi4.0.0),目前只能java生成】...

    版权声明:本文为HaiyuKing原创文章,转载请注明出处! 前言 这个是<PoiDemo[Android将表单数据生成Word文档的方案之二(基于Poi4.0.0)]>的扩展,上一篇是根 ...

  4. PDF转Word文档怎么转?两招教你学会PDF转word

    最近小编发现周围的同事每天都被PDF转Word文档这个问题导致加班到很晚,原来老板前些天给了很多PDF格式的文件,还要求把这些PDF文件转成word文档的格式,他们不知道怎么转,竟然一个个对着PDF文 ...

  5. 《Python 编程快速上手 — 让繁琐工作自动化》读书笔记之【第13章 处理PDF和Word文档(1)】

    PDF 和 Word 文档是二进制文件. 1.  PDF 文档 PDF表示Portable Document Format(可移植文档格式),使用.pdf文件扩展名.用于处理PDF的模块是PyPDF2 ...

  6. 爬虫系列:读取 CSV、PDF、Word 文档

    上一期我们讲解了使用 Python 读取文档编码的相关问题,本期我们讲解使用 Python 处理 CSV.PDF.Word 文档相关内容. CSV 我们进行网页采集的时候,你可能会遇到 CSV 文件, ...

  7. 最全的PDF转换Word文档方法汇总(珍藏版)

    相信很多人经常使用到Word文档和PDF文档,也有PDF转换Word的需求,不过转换PDF文档也是难倒了很多人了. 今天小编就总结了有关于PDF转Word文档的所有方法,希望对需要的朋友有一定的帮助. ...

  8. 如何pdf转word文档?这几个小技巧你值得拥有

    关于怎么把pdf转word的方法,这里分享给你 想知道怎么把pdf转word?安利两个好用的pdf转word软件 怎么把pdf转word?这几个pdf转word工具帮你解决难题 实用转换小技巧:pdf ...

  9. 基于pdf2docx模块Python实现批量将PDF转Word文档(安装+完整代码教程)

    PDF文件是一种常见的文档格式,但是在编辑和修改时不太方便,因为PDF本质上是一种静态的文档格式.因此,有时候我们需要将PDF文件转换成Word格式,以便更好地编辑和修改文档.在本篇文章中,我们将介绍 ...

最新文章

  1. 后生可畏!中国军团称霸阅读理解竞赛RACE:微信AI称王,高中生力压腾讯康奈尔联队(附资料)...
  2. 10万点击率的“干货”,其实人人都写得出来
  3. mysql跨服务器查询语句_MySQL 跨服务器访问之-FEDERATED引擎
  4. python 数据分析工具之 numpy pandas matplotlib
  5. XML文件与实体类的互相转换
  6. 如何使用robots.txt[摘自网络]
  7. numpy练习100道题
  8. Arm发布移动端v9体系新架构,CPU、GPU、IP全囊括了!
  9. 不删除旧版本java_Linux 卸载旧版jdk 并安装新版jdk(转)
  10. C/C++——从ctime使用到随便测一样冒泡排序和堆排序的效率
  11. 分类算法----逻辑回归预测
  12. c# linux 效率,c# – linux / mono上的HTTP性能
  13. 施密特:下个千亿美元市值公司将出在哪个行业
  14. C#连接oracle数据库提示ORA-12154: TNS: 无法解析指定的连接标识符
  15. vue3 + typescript + echarts后端动态获取数据显示问题总结
  16. java 文件递归删除文件夹_JAVA利用递归删除文件和文件夹
  17. 洛谷试炼场---提高历练地 普及练习场 新手村 入门难度
  18. freeswitch java_freeSWITCH
  19. 如何在Mac设置开机自启程序项,教程在这!
  20. java操作excel表格(最简单的教程!一学即会)

热门文章

  1. 两个数和两数之和绝对值
  2. 【Hll】Hll HyperLogLog: Cardinality Estimation(基数估计算法源码解析)
  3. 手机连笔记本闪断闪连解决办法
  4. python实现云播放_云直播(KLS)
  5. ​16 个使用 App Bundle 发布应用和游戏的理由
  6. AES加密出现Error: Malformed UTF-8 data报错的解决方法
  7. 【3dmax】关于贴图老是不能显示透明底的情况的彻底解决方法
  8. android工厂模式源码,android 设计模式:工厂模式
  9. python龙旋风图形代码_python – Matplotlib:鼻子,龙卷风
  10. 机器学习、监督学习、非监督学习、强化学习、深度学习、迁移学习