使用腾讯TBS打开Office文件

2018-04-11  本文已影响2285人  huangasys

最近遇到个需求,需要在应用内打开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.具体实现

需要注意的几点:

@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;
    }

遇到的问题

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

 可能是so文件不支持;未提供x64的so
   ndk {
            //设置支持的SO库架构  ['arm64-v8a']
            abiFilters 'armeabi', "armeabi-v7a",  'x86'
        } 
原因: 
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地址
感谢
如有不足,请多指教!

上一篇下一篇

猜你喜欢

热点阅读