美文网首页
使用腾讯TBS打开Office文件

使用腾讯TBS打开Office文件

作者: huangasys | 来源:发表于2018-04-11 18:55 被阅读2285次

    最近遇到个需求,需要在应用内打开Office文件,Android在这方面的功能远远没有 iOS 系统方便得多.所以想到了使用腾讯浏览服务(TBS,Tencent Browsing Service); 腾讯TBS服务官网介绍

    1.官网下载所需SDK
    TBS下载页.jpg
    2.导入jar包
    jar包.png

    然后添加add in library即可

    设置ndk支持

    x5暂时不提供64位so文件,为了保证64位手机能正常加载x5内核,进行以下两项设置:
    打开对应module中的build.gradle文件,在文件的android{}中的defaultConfig{}里(如果没有defaultConfig{}则手动添加)添加如下配置: ndk{abiFilters "armeabi"}


    image.png
    3.导入so文件
    image2.png

    在这里要注意的是,详细文档,so文件以及demo都在第一个SDK文件里面;建议两个SDK都下载下来解压查看;


    image3.png
    4.具体实现

    需要注意的几点:

    • 加载文件主要实现类是TbsReaderView,但是文档没明确写明白,在这里感谢这篇文章的帮助:简书链接
    • TBS目前只支持加载本地文件。所以加载文件需要先下载到本地,然后才能进行下载。
    • 显示文件的界面,退出界面以后需要销毁,否则再次加载文件无法加载成功,会一直显示加载文件进度条。
    @Override
        protected void onDestroy() {
            super.onDestroy();
            mTbsReaderView.onStop();
        }
    

    1.布局页面

    
    <RelativeLayout
        android:id="@+id/tbsView"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        app:layout_constraintRight_toRightOf="parent"
        app:layout_constraintLeft_toLeftOf="parent"
        app:layout_constraintTop_toTopOf="parent"
        app:layout_constraintBottom_toBottomOf="parent"
        >
    
    1. 主要代码
            mTbsReaderView = new TbsReaderView(this, this);
            mRelativeLayout = findViewById(R.id.tbsView);
            mRelativeLayout.addView(mTbsReaderView,new RelativeLayout.LayoutParams(-1,-1));
    

    为什么不将 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 az(this);
            }
        }
    

    3.根据url获取文件名.打开本地或者下载至本地;

      private void initDoc() {
            int i = docUrl.lastIndexOf("/");
            String docName = docUrl.substring(i, docUrl.length());
            Log.d("print", "---substring---" + docName);
    
            //判断是否在本地/[下载/直接打开]
            File docFile = new File(download, docName);
            if (docFile.exists()) {
                //存在本地;
                Log.d("print", "本地存在");
                displayFile(docFile.toString(),  docName);
            } else {
    //本地不存在,则下载;使用的OkGo2.x;
                OkGo.get(docUrl)//
                        .tag(this)//
                        .execute(new FileCallback(download, docName) {  //文件下载时,可以指定下载的文件目录和文件名
                            @Override
                            public void onSuccess(File file, Call call, Response response) {
                                // file 即为文件数据,文件保存在指定目录
                                Log.d("print", "下载文件成功");
                                displayFile(download+file.getName(), file.getName());
                                Log.d("print", "" + file.getName());
                            }
    
                            @Override
                            public void downloadProgress(long currentSize, long totalSize, float progress, long networkSpeed) {
                                //这里回调下载进度(该回调在主线程,可以直接更新ui)
                                Log.d("print", "总大小---" + totalSize + "---文件下载进度---" + progress);
                            }
                        });
            }
        }
    

    4.打开文件

    private String tbsReaderTemp = Environment.getExternalStorageDirectory() + "/TbsReaderTemp";
        private void displayFile(String filePath, String fileName) {
    
            //增加下面一句解决没有TbsReaderTemp文件夹存在导致加载文件失败
            String bsReaderTemp = tbsReaderTemp;
            File bsReaderTempFile =new File(bsReaderTemp);
            if (!bsReaderTempFile.exists()) {
                Log.d("print","准备创建/TbsReaderTemp!!");
                boolean mkdir = bsReaderTempFile.mkdir();
                if(!mkdir){
                    Log.d("print","创建/TbsReaderTemp失败!!!!!");
                }
            }
            Bundle bundle = new Bundle();
            bundle.putString("filePath", filePath);
            bundle.putString("tempPath", tbsReaderTemp);
            boolean result = mTbsReaderView.preOpen(getFileType(fileName), false);
            Log.d("print","查看文档---"+result);
            if (result) {
                mTbsReaderView.openFile(bundle);
            }else{
    
            }
        }
    
        private String getFileType(String paramString) {
            String str = "";
    
            if (TextUtils.isEmpty(paramString)) {
                Log.d("print", "paramString---->null");
                return str;
            }
            Log.d("print", "paramString:" + paramString);
            int i = paramString.lastIndexOf('.');
            if (i <= -1) {
                Log.d("print", "i <= -1");
                return str;
            }
    
            str = paramString.substring(i + 1);
            Log.d("print", "paramString.substring(i + 1)------>" + str);
            return str;
        }
    

    遇到的问题

    • 1.TbsReader: Set reader view exception:Cannot add a null child view to a ViewGroup
      TbsReaderView: OpenFile failed!

    bundle.putString("filePath", filePath); 可能是文件的路径错误 检查一下filePath的路径;

    • 2.插件加载失败
     可能是so文件不支持;未提供x64的so
       ndk {
                //设置支持的SO库架构  ['arm64-v8a']
                abiFilters 'armeabi', "armeabi-v7a",  'x86'
            } 
    
    • 3.TbsReaderView: not supported by:XXX
    原因: 
    1. 本身不支持这种格式,具体可查看TBS文档有详细支持文档格式列表;
    2. 因为是公司的测试机,未安装微信.QQ;所以手机并没有X5的内核.TBS文档内也有说明;
    
    image4.png

    但是后面安装了微信并安装文档走了一遍流程发现还是有这个错误.在Application加了这段代码才解决的

    //初始化X5内核
           QbSdk.initX5Environment(this, new QbSdk.PreInitCallback() {
               @Override
               public void onCoreInitFinished() {
                   //x5内核初始化完成回调接口,此接口回调并表示已经加载起来了x5,有可能特殊情况下x5内核加载失败,切换到系统内核。
    
               }
    
               @Override
               public void onViewInitFinished(boolean b) {
                   //x5內核初始化完成的回调,为true表示x5内核加载成功,否则表示x5内核加载失败,会自动切换到系统内核。
                   Log.e("print","加载内核是否成功:"+b);
               }
           });
    

    Github地址
    感谢
    如有不足,请多指教!

    相关文章

      网友评论

          本文标题:使用腾讯TBS打开Office文件

          本文链接:https://www.haomeiwen.com/subject/xjwnhftx.html