当前位置:   article > 正文

安卓使用腾讯tbs查看pdf/word文件(解决x5内核下载问题)_tencent.tbs打开wps

tencent.tbs打开wps

 

     

 引言: 项目需要预览pdf、word等文件,但是用户不一定安装了wps这样的软件,因此需要在项目里支持查看这些文件。笔者本身是不想使用webview的,因此尝试了很多原生的,但是对于doc文件基本没有什么好的方式,到最后还是用了腾讯的tbs文件游览服务。接入tbs坑较多,主要是x5内核的下载和各种配置问题,花费了两天才整理好,因此分享出来防止大家踩坑。

一、首先梳理一下选择tbs的理由

      对于doc,docx文件,除tbs外似乎只有一种方式,利用poi解析doc,然后自己渲染成html。笔者尝试了这种方式,发现其原理是读取doc文件后,再把相关元素加上html的标签,用本地webview加载,html标签与doc文件毕竟有很大差距,因此展示效果很差,只能选择tbs。

     然后是关于pdf的查看,这种方式略多,下面大致介绍下:

  1.   pdf.js  这是火狐推出的可以在安卓上使用,并且文件并不大,使用难度相对不大
  2. 安卓原生的pdfRender,笔者使用感觉还可以,因为使用安卓自带的pdfRender,不需要额外导入文件,加载速度也还好,如果只需要显示pdf,推荐
  3. github上开源的pdfviewer,功能较为强大,但是因为会导致包至少增大无法被接受,项目地址https://github.com/barteksc/AndroidPdfViewer
  4. 采用外部链接在线预览,但是目前基本是国外链接,会被墙,不考虑

     最后能够良好展示word文件的只有tbs,因此只能用它了。

二、tbs接入及踩坑

     首先说一下坑的问题,实际上在本地利用tbs打开文件腾讯的文档是没有写的,因为腾讯想让我们优先使用他们的QbSdk,这样会优先打开QQ浏览器,现在的本地打开的方法是各路大神从源码找出来的,可能有各种疏忽,所以坑多。(不过腾讯的文档也怪扯淡的)

     1.初始配置

           先上官方文档: 腾讯浏览器tbs接入文档

           下面进行大致梳理

             1. 导入依赖

                 在app的build.gradle文件中增加依赖

api 'com.tencent.tbs.tbssdk:sdk:43939'

           2.增加权限混淆,首次启动初始化冷启动优化(一定要加混淆,不然release版本不能用的

                这里不做详细介绍,直接看官方文档,照着来就可以了。另外官方文档的异常上报措施可忽略。官方文档还有一个替换webview的,这种是指如果你项目本来使用了webview,但是现在你想换成使用腾讯的x5内核,那么就需要按照腾讯的做法替换,如果不想替换,那可以不用变,因为接入腾讯x5内核后,安卓原生的webview仍然是可以用的。

            3、使用

            从这里开始文档就相当坑爹了,腾讯文档被没有讲如何初始化x5内核,甚至x5内核到底初始化成功了都没有介绍。

             首先介绍一下x5内核,x5内核就是QQ浏览器的内核,对安卓的webview做了一层封装,在你的手机各个app可以共享,比如qq、QQ游览器,微信之间一个初始化了,其他的就可以使用。(但是笔者实践,只有你安装了QQ浏览器才可以共享,QQ微信无效)。

             然后是x5内核的初始化代码:(建议放在Application中)

  1. QbSdk.initX5Environment(this, new QbSdk.PreInitCallback() {
  2. @Override
  3. public void onCoreInitFinished() {
  4. }
  5. @Override
  6. public void onViewInitFinished(boolean b) {
  7. //这里被回调,并且b=true说明内核初始化并可以使用
  8. //如果b=false,内核会尝试安装,你可以通过下面监听接口获知
  9. //另外第一次安装app不会被调用
  10. }
  11. });
  12. QbSdk.setTbsListener(new TbsListener() {
  13. @Override
  14. public void onDownloadFinish(int i) {
  15. //tbs内核下载完成回调
  16. //但是只有i等于100才算完成,否则失败
  17. //此时大概率可能由于网络问题
  18. //如果失败可增加网络监听器
  19. }
  20. @Override
  21. public void onInstallFinish(int i) {
  22. //内核安装完成回调,通常到这里也算安装完成,但是在
  23. //极个别情况也会出现加载失败,比如笔者在公司内网下偶现,可以忽略
  24. }
  25. @Override
  26. public void onDownloadProgress(int i) {
  27. //下载进度监听
  28. }
  29. });

             上面的代码会自动对x5内核进行初始化,如果没有x5内核会自动下载。

             之后就是使用sdk打开文件了,首先是腾讯文档写的打开文件方式:(坑较少,同时不是本文的目的,不做过多介绍)

  1. //优先打开QQ浏览器,如果没有则利用X5内核软件内打开,
  2. //如果X5内核也没有就弹窗让别的软件打开
  3. QbSdk.openFileReader(getContext(),filepath,null,null);

                然后就是使用TbsReaderView在软件内打开:

  

  1. Bundle bundle = new Bundle();
  2. //指定文件路径
  3. bundle.putString("filePath", filePath);
  4. //指定腾讯文件缓存路径
  5. bundle.putString("tempPath", Environment.getExternalStorageDirectory()
  6. .getPath()+"/dsadsa");
  7. //预加载,判断格式是否正确,其中的parseFile方法是获取文件后缀
  8. boolean result = mTbsView.preOpen(parseFileType(filePath), false);
  9. if (result) {
  10. mTbsView.openFile(bundle);
  11. } else {
  12. Log.e(TAG, "Type is not support");
  13. }

                    这里再附上获取文件后缀方法,parseFileType

  1. private String parseFileType(String path) {
  2. if (TextUtils.isEmpty(path)) {
  3. return "";
  4. } else {
  5. return path.substring(path.lastIndexOf(".")+1);
  6. }
  7. }

                上面的基本就是按照文档的说法了,但是离真正打开还有十万八千里,下面开始踩坑。

三、踩坑

      1.provider

        当你运行尝试打开文件后,会报错:找不到com.tencent.smtt.utils.FileProvider或者找不到provider,官方文档竟然一点没提,气愤呀。

         在AndroidManifest.xml文件中增加:

         

  1. <provider
  2. android:name="com.tencent.smtt.utils.FileProvider"
  3. android:authorities="${applicationId}.provider"
  4. android:exported="false"
  5. android:grantUriPermissions="true">
  6. <meta-data
  7. android:name="android.support.FILE_PROVIDER_PATHS"
  8. android:resource="@xml/x5webview_file_paths" />
  9. </provider>

       然后在res的xml文件夹下新建文件夹x5webview_file_paths.xml (文件名自己定,只要和上面的meta_data的resource对应上即可),内容如下:

          

  1. <?xml version="1.0" encoding="utf-8"?>
  2. <paths>
  3. <external-path name="sdcard" path="."/>
  4. </paths>

             2.X5内存下载

                在使用过程中,经常会报各种类找不到,然后在使用tbs打开文件时,明明是支持的文件,但是却说不支持,都是由于X5内核没有下载导致的。(因为内部很多方法使用了反射,X5的代码没有下载,因此会出现各种类找不到)

                下面说一下X5初始化出现的各种问题:

  1.    网络要求,由于X5内核30M,通常在wifi下下载 (根据项目需要决定,后来我们最终决定在流量下也可以下载)
  2.    继续下载问题,在上一次下载失败后,下一次由于有缓存,会导致即不能用,也不能重新下载 
  3.   初始化是否完成,官方没有提供相关的方法

     也就是说,只要一次性没下载完,以后下载就没戏了,除非卸载重装,而且网络不符合要求也会中止下载

                然后是我的解决总结,再详细阐述解释:

    reset重置+布尔值记录初始结果+网路监听器+进度监听

              上面2.1.3介绍了X5下载问题,sdk会自动判断是否初始化并下载,但是用户网络不一定符合要求,而且用户也可能打开接着关闭导致存在缓存无法再次初始化,甚至在初始化过程中调用tbsReadview的相关代码也会导致缓存问题,真的是恶心呀。

              通过各种搜索百度谷歌,发现下面几个方法:

  1. //重置化sdk,这样就清除缓存继续下载了
  2. QbSdk.reset(context);
  3. //手动开始下载,此时需要先判定网络是否符合要求
  4. TbsDownloader.startDownload(context);
  5. //是否需要下载内核,作用比较奇葩
  6. //该方法会在完全没下载的时候返回true,在
  7. //加载完成和存在缓存无法继续下载时返回flase
  8. //这个方法可以用来判断是否存在缓存需要重置
  9. boolean need =TbsDownloader.needDownload(context, false)

接下来就结合上面的方法和具体x5下载的流程,详细分析。

        首先是每次启动前调用sdk初始化加速流程:

  1. private static void BeforeSdk(Context context) {
  2. // 在调用TBS初始化、创建WebView之前进行如下配置
  3. HashMap<String, Object> map = new HashMap<>();
  4. map.put(TbsCoreSettings.TBS_SETTINGS_USE_SPEEDY_CLASSLOADER, true);
  5. map.put(TbsCoreSettings.TBS_SETTINGS_USE_DEXLOADER_SERVICE, true);
  6. QbSdk.initTbsSettings(map);
  7. QbSdk.setDownloadWithoutWifi(!mOnlyWifi);
  8. QbSdk.disableAutoCreateX5Webview();
  9. //强制使用系统内核,看你需求
  10. //QbSdk.forceSysWebView();
  11. }
 

   然后就是下载过程,在这里我们设置了几个变量记录是否初始化成功

  1. private static boolean mOnlyWifi = false;
  2. //记录是否加载完成
  3. private static boolean mInit = false;
  4. //网络接收器是用来处理网络中断导致的加载问题
  5. private static ConnectReceiver mConnectionReceiver;
  6. //这个key是sp存储的,用来记录上一次是否加载成功
  7. //因为有的时候需要立刻用到tbs展示文件,但是tbs可能还没加载好
  8. //因此我们在sp里面做记录,看是否需要等待加载
  9. //如果上次加载好了,那这次肯定也很快,可以等待
  10. //如果上次没加载好,那还是提示用户过一会再用吧
  11. private static String TBS_INIT_KEY = "tbs_init_key";
  12. //该方法是用来判断tbs是否加载完成的,供外部调用
  13. public static boolean initFinish() {
  14. //如果上次加载成功,那么便认为当前的未加载成功由于还未加载完等
  15. //不做额外处理
  16. if(SPUtils.getBoolean(TBS_INIT_KEY,false)){
  17. return mInit;
  18. }
  19. //上次没加载完,那就根据状态判断是否重置
  20. if (!mInit && !TbsDownloader.isDownloading()) {
  21. QbSdk.reset(mContext);
  22. resetSdk(mContext);
  23. if (!mOnlyWifi || NetUtils.isWifiConnection(mContext))
  24. TbsDownloader.startDownload(mContext);
  25. }
  26. return mInit;
  27. }

     接着就是具体的下载设置:

  1. resetSdk(context);
  2. QbSdk.setTbsListener(new TbsListener() {
  3. @Override
  4. public void onDownloadFinish(int i) {
  5. //成功时i为100
  6. if (i != 100) {
  7. //此处存在一种情况,第一次启动app,init不会自动回调,
  8. // 此处额外加一层,判断网络监听器是否为空并作出处理
  9. if (mConnectionReceiver == null)
  10. initNetWorkCallBack();
  11. else {
  12. initFinish();
  13. }
  14. }
  15. Log.d(TAG, "load" + i);
  16. //tbs内核下载完成回调
  17. }
  18. @Override
  19. public void onInstallFinish(int i) {
  20. //只要运行到这里,我们就认为加载完成了
  21. //但是也发现一些异常,在公司内网运行到这里也加载失败了,先忽略
  22. mInit = true;
  23. if (mConnectionReceiver != null) {
  24. mContext.unregisterReceiver(mConnectionReceiver);
  25. mConnectionReceiver = null;
  26. }
  27. Log.d(TAG, "finish" + i);
  28. //内核安装完成回调,
  29. }
  30. @Override
  31. public void onDownloadProgress(int i) {
  32. //下载进度监听
  33. Log.d(TAG, "progress" + i);
  34. }
  35. });
  36. QbSdk.initX5Environment(context, new QbSdk.PreInitCallback() {
  37. @Override
  38. public void onCoreInitFinished() {
  39. //x5内核初始化完成回调接口,此接口回调并表示已经加载起来了x5,有可能特殊情况下x5内核加载失败,切换到系统内核。
  40. }
  41. @Override
  42. public void onViewInitFinished(boolean b) {
  43. //x5內核初始化完成的回调,为true表示x5内核加载成功,否则表示x5内核加载失败,会自动切换到系统内核。
  44. //该方法在第一次安装app打开不会回调
  45. mInit = b;
  46. Log.e(TAG, "加载内核是否成功:" + b);
  47. if (!mInit) {
  48. initNetWorkCallBack();
  49. }
  50. if (!mInit && TbsDownloader.needDownload(context, false) && !TbsDownloader.isDownloading()) {
  51. initFinish();
  52. }
  53. SPUtils.putBoolean(TBS_INIT_KEY, mInit).apply();
  54. }
  55. });

至此tbs的初始化基本完成,代码示例中的SPUtils就是SharedPreferences,自己实现即可

 

     3.使用

     tbsview你在同一时间只能加载一处,因此请做好回收工作,可以设置成静态的,也可以将加载的activity设置成instance的,具体看你。

    另外展示的时候会有最近文件字样,以及可能底色有问题,都可以通过逐层分析子view更改,具体百度即可。

 

项目地址     https://github.com/qieting/TbsUserDemo      

这个项目地址和上面博客讲的略有出入,因为博客是后期补充完善的,但是项目没改

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/花生_TL007/article/detail/175033
推荐阅读
相关标签
  

闽ICP备14008679号