腾讯TBS浏览服务打开本地文档(word.pdf.ppt)踩过的坑

记录一下安卓使用腾讯tbs浏览本地文档(word.pdf.ppt)踩过的坑,以方便以后自己面查阅跟供他人参考。
腾讯TBS服务官网介绍


 



遇到的坑:
1、按照文档接入sdk,并在DemoApplication 初始化加载tbs内核不成功,(周五、周六、周日)通常是初始化加载不成功,其他时间段没问题

2、tbs初始化加载成功,添加显示具体文档的时候,一直提示 "插件加载失败"

处理办法:
问题1:按照sdk流程初始化初始化加载tbs内核,加载内核不成功重新调用下载方法:

TbsDownloader.startDownload();

10次都加载不成功,直接手动加载安装本地tbs内核资源(本地tbs资源可以放在自己的服务器上):

QbSdk.installLocalTbsCore()  


问题2: 根据官网常见问题做对应的修改即可:
腾讯浏览服务  3.7 targetAPI为Android P时无法下载内核?


下面附上代码段:

package com.demo.tbsloadfile;

import android.app.Application;
import android.util.Log;
import android.widget.Toast;

import com.tencent.smtt.export.external.TbsCoreSettings;
import com.tencent.smtt.sdk.QbSdk;
import com.tencent.smtt.sdk.QbSdk.PreInitCallback;
import com.tencent.smtt.sdk.TbsDownloader;
import com.tencent.smtt.sdk.TbsListener;

import java.io.File;
import java.util.HashMap;

public class DemoApplication extends Application {

    private static final String TAG = "DemoApplication";

    @Override
    public void onCreate() {
        super.onCreate();

        initTBS();
        //targetSdkVersion > 27 ,需要参考文档   3.7 targetAPI为Android P时无法下载内核?添加xml
        // https://x5.tencent.com/docs/questions.html


        //复制文件到sdkcard
        FileCopyAssetToSD.getInstance(getApplicationContext()).copyAssetsToSD("sources" , FileCopyAssetToSD.getDiskCacheDir(getApplicationContext()).toString()).setFileOperateCallback(new FileCopyAssetToSD.FileOperateCallback() {
            @Override
            public void onSuccess() {
            }

            @Override
            public void onFailed(String error) {

            }
        });

        // tbs内核本地加载
//        FileCopyAssetToSD.getInstance(getApplicationContext()).copyAssetsToSD("apk" , FileCopyAssetToSD.getDiskCacheDir(getApplicationContext()).toString()).setFileOperateCallback(new FileCopyAssetToSD.FileOperateCallback() {
//            @Override
//            public void onSuccess() {
//                String filePath = FileCopyAssetToSD.getDiskCacheDir(getApplicationContext()).toString() + File.separator + "x5.apk";
//                initLocalTbsCore(filePath);
//                Toast.makeText(getApplicationContext() , "复制成功"+filePath , Toast.LENGTH_LONG).show();
//
//            }
//
//            @Override
//            public void onFailed(String error) {
//
//            }
//        });

    }


    private boolean isDownTbsSuccess = false;//TBS X5插件是否下载成功
    private int downTbsCount = 0;//尝试下载次数
    /**
     * 腾讯TBS初始化流程
     */
    public void initTBS() {
        /********************************TBS服务器下发版本开始*********************************/
        if (QbSdk.getTbsVersion(getApplicationContext()) == 0) {//获取不到版本号,说明插件没有加载成功,重新跑流程
            //判断是否是x5内核未下载成功,存在缓存 重置化sdk,这样就清除缓存继续下载了
            QbSdk.reset(getApplicationContext());
            HashMap map = new HashMap();
            map.put(TbsCoreSettings.TBS_SETTINGS_USE_SPEEDY_CLASSLOADER, true);
            map.put(TbsCoreSettings.TBS_SETTINGS_USE_DEXLOADER_SERVICE, true);
            QbSdk.initTbsSettings(map);
            /* 设置允许移动网络下进行内核下载。默认不下载,会导致部分一直用移动网络的用户无法使用x5内核 */
            QbSdk.setDownloadWithoutWifi(true);



            /* SDK内核初始化周期回调,包括 下载、安装、加载 */
            QbSdk.setTbsListener(new TbsListener() {
                /**
                 * @param progress 110: 表示当前服务器认为该环境下不需要下载
                 */
                @Override
                public void onDownloadFinish(int progress) {
                    Log.i(TAG, "onDownloadFinished: " + progress);
                    //下载结束时的状态,下载成功时errorCode为100,其他均为失败,外部不需要关注具体的失败原因
                    if (isDownTbsSuccess) {
                        return;
                    }
                    if (progress < 100) {
                        return;
                    }
                    if (progress != 100) {//回调里面还是没有成功,那就再次尝试下载
                        if (downTbsCount < 10) {//尝试下载10次,失败就开始从自己的服务器端下载
                            downTbs();
                        } else {//加载从自己的服务器端下载的x5内核
                            FileCopyAssetToSD.getInstance(getApplicationContext()).copyAssetsToSD("apk" , FileCopyAssetToSD.getDiskCacheDir(getApplicationContext()).toString()).setFileOperateCallback(new FileCopyAssetToSD.FileOperateCallback() {
                                @Override
                                public void onSuccess() {
                                    String filePath = FileCopyAssetToSD.getDiskCacheDir(getApplicationContext()).toString() + File.separator + "x5.apk";
                                    initLocalTbsCore(filePath);
                                    Toast.makeText(getApplicationContext() , "复制成功" , Toast.LENGTH_LONG).show();
                                    Log.i(TAG,"复制成功:"+filePath);

                                }

                                @Override
                                public void onFailed(String error) {

                                }
                            });
                        }
                        downTbsCount++;
                    }
                    if (progress == 100) {
                        isDownTbsSuccess = true;
                    }
                }

                /**initX5Environment
                 * @param stateCode 200、232安装成功
                 */
                @Override
                public void onInstallFinish(int stateCode) {
                    Log.i(TAG, "onInstallFinished: " + stateCode);
                }

                /**
                 * 首次安装应用,会触发内核下载,此时会有内核下载的进度回调。
                 * @param progress 0 - 100
                 */
                @Override
                public void onDownloadProgress(int progress) {
                    Log.i(TAG, "Core Downloading: " + progress);
                }
            });



            /* 此过程包括X5内核的下载、预初始化,接入方不需要接管处理x5的初始化流程,希望无感接入 */
            QbSdk.initX5Environment(this, new PreInitCallback() {
                @Override
                public void onCoreInitFinished() {
                    // 内核初始化完成,可能为系统内核,也可能为系统内核
                }

                /**
                 * 预初始化结束
                 * 由于X5内核体积较大,需要依赖wifi网络下发,所以当内核不存在的时候,默认会回调false,此时将会使用系统内核代替
                 * 内核下发请求发起有24小时间隔,卸载重装、调整系统时间24小时后都可重置
                 * @param isX5 是否使用X5内核
                 */
                @Override
                public void onViewInitFinished(boolean isX5) {
                    Log.i(TAG, "onViewInitFinished: " + isX5);
                }
            });
        }
    }




    /**
     * 下载TBS插件 通过腾讯端下发
     */
    public void downTbs() {
        //判断是否是x5内核未下载成功,存在缓存 重置化sdk,这样就清除缓存继续下载了
        QbSdk.reset(getApplicationContext());
        //开始下载x5内核
        TbsDownloader.startDownload(getApplicationContext());
    }


    /**
     * tbs内核本地加载
     */
    public void initLocalTbsCore(String filePath) {
        QbSdk.reset(getApplicationContext());
        QbSdk.setTbsListener(new TbsListener() {
            @Override
            public void onDownloadFinish(int i) {

            }

            @Override
            public void onInstallFinish(int i) {
                int tbsVersion = QbSdk.getTbsVersion(getApplicationContext());
            }

            @Override
            public void onDownloadProgress(int i) {
            }
        });
        QbSdk.installLocalTbsCore(getApplicationContext(), 44197, filePath);
    }

}
 
package com.demo.tbsloadfile;

import androidx.appcompat.app.AppCompatActivity;
import pub.devrel.easypermissions.EasyPermissions;

import android.Manifest;
import android.content.Context;
import android.os.Bundle;
import android.os.Environment;
import android.text.TextUtils;
import android.util.Log;
import android.view.View;
import android.view.ViewGroup;
import android.widget.LinearLayout;

import com.tencent.smtt.sdk.TbsReaderView;

import java.io.File;
import java.util.logging.Logger;

public class MainActivity extends AppCompatActivity implements  TbsReaderView.ReaderCallback{

    String TAG = "MainActivity";
    String mFilePath = "";
    LinearLayout llBoard;

    TbsReaderView tbsReaderView;
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        checkPermission();
        mFilePath = FileCopyAssetToSD.getDiskCacheDir(this)+ File.separator + "安全教育(1).ppt";

        llBoard = findViewById(R.id.llBoard);
        findViewById(R.id.btnAdd).setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {


                try {
                    tbsReaderView = new TbsReaderView(MainActivity.this, MainActivity.this);
                    tbsReaderView.setFocusable(false);
                    llBoard.addView(tbsReaderView, new LinearLayout.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.MATCH_PARENT));

                    String tbsReaderTemp = getDiskCacheDir(MainActivity.this).toString() + "/" + "TbsReaderTemp";
                    File tbsReaderTempFile = new File(tbsReaderTemp);

                    if (!tbsReaderTempFile.exists()) {
                        tbsReaderTempFile.mkdir();
                    }

                    Bundle localBundle = new Bundle();
                    localBundle.putString(TbsReaderView.KEY_FILE_PATH, mFilePath);
                    localBundle.putString(TbsReaderView.KEY_TEMP_PATH, tbsReaderTemp);
                    boolean bool = tbsReaderView.preOpen(getFileType(mFilePath), false);
                    if (bool) {
                        tbsReaderView.openFile(localBundle);
                    } else {
                        Log.i(TAG,"X5内核加载课件失败,需要重新加载");
                        //加载本地x5so 执行 DemoApplication  initLocalTbsCore();
                    }
                } catch (Exception e) {
                    e.printStackTrace();
                }
            }
        });
    }


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





    /***
     * 获取文件类型
     *
     * @param paramString
     * @return
     */
    private String getFileType(String paramString) {
        String str = "";

        if (TextUtils.isEmpty(paramString)) {
            return str;
        }
        int i = paramString.lastIndexOf('.');
        if (i <= -1) {
            return str;
        }


        str = paramString.substring(i + 1);
        return str;
    }

    //    /路径例如: /SD卡/Android/data/程序的包名/cache/uniqueName
    public static File getDiskCacheDir(Context context) {//获取缓目录
        String cachePath;
        if (Environment.MEDIA_MOUNTED.equals(Environment.getExternalStorageState())
                || !Environment.isExternalStorageRemovable()) {
            cachePath = context.getExternalCacheDir().getPath();
        } else {
            cachePath = context.getCacheDir().getPath();
        }

        File file = new File(cachePath + File.separator + "tbs");
        if (!file.exists()) {
            file.mkdirs();
        }
        return file;
    }

    public void checkPermission(){

        String[] perms = {Manifest.permission.CAMERA, Manifest.permission.WRITE_EXTERNAL_STORAGE,
                Manifest.permission.RECORD_AUDIO, Manifest.permission.READ_EXTERNAL_STORAGE};
        if (EasyPermissions.hasPermissions(this, perms)) {

        } else {
            // Do not have permissions, request them now
            EasyPermissions.requestPermissions(this, "需要先获取相关权限",
                    0x01, perms);
        }
    }

    @Override
    protected void onDestroy() {
        super.onDestroy();
        if (tbsReaderView != null)
            tbsReaderView.onStop();
    }
}

参考:
腾讯TBS浏览服务打开word.pdf.ppt等文档的使用_Huang_SS的博客-CSDN博客

Android实现复制Assets文件到SD卡 - 码农教程


demo地址:
https://gitee.com/woshiluchi/tbsloadfile.git

安卓腾讯TBS加载本地文件(word.pdf.ppt)-Android文档类资源-CSDN下载

  • 1
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 5
    评论
### 回答1: 腾讯的开源协议栈f-stack.pdf是在DPDK技术峰会上推出的一项重要技术创新。DPDK技术峰会是一个技术交流平台,旨在推动数据平面开发工具包(DPDK)技术的发展和应用。f-stack.pdf腾讯开源的一套协议栈,它通过与DPDK集成,提供了高性能的网络数据包处理能力。 f-stack.pdf具有以下几个特点:高性能、轻量级和易使用。它基于零拷贝技术,能够以卓越的性能处理数据包。同时,f-stack.pdf采用了轻量级设计,只依赖于DPDK的核心功能,避免了不必要的复杂性,使得使用起来更加简单和灵活。 f-stack.pdf在应用层提供了一系列网络协议的支持,例如TCP、UDP和IP等。它提供了高度可扩展和定制化的接口,使得开发者可以根据具体需求进行定制和优化。另外,f-stack.pdf还提供了丰富的功能和工具,方便开发者进行网络应用的开发和调试。 该协议栈不仅适用于云服务器、网络设备和高速存储等领域,还可以广泛应用于物联网、5G通信和金融等行业。它的高性能和低延迟使得在大规模并发场景下的数据处理更加高效和稳定。 腾讯的开源协议栈f-stack.pdf在DPDK技术峰会上的推出,标志着中国企业在高性能网络技术领域的一次重要突破。它的出现将有助于促进我国网络技术的创新和发展,并提升我国在全球高性能网络领域的竞争力。 ### 回答2: 腾讯的开源协议栈f-stack是DPDK技术峰会上推出的一项重要的技术成果。该技术是基于DPDK(Data Plane Development Kit)开发的一套网络数据包处理框架,旨在提供高性能的网络数据包处理和协议栈功能。 f-stack的特点可以从以下几个方面来描述。首先,它采用了用户态的网络协议栈设计,将协议处理功能从内核态迁移到用户态,避免了内核态和用户态的频繁切换,提高了数据包处理的效率。其次,f-stack提供了一套完整的网络协议栈功能,包括TCP/IP协议栈、套接字接口、事件驱动机制等,可以支持常见的网络应用开发。此外,f-stack还提供了网络收发模块、队列管理、内存池等高性能的数据结构和算法,以进一步提升数据包处理的吞吐量和延迟。 通过使用f-stack,开发者可以轻松地构建高性能的网络应用,无论是在云计算、大数据分析还是边缘计算等场景中,都能够获得更好的性能和响应速度。与传统的网络协议栈相比,f-stack具有更低的延迟、更高的吞吐量和更好的可扩展性,能够更好地满足现代网络应用对于高性能数据处理的需求。 最后,开源协议栈f-stack的推出也体现了腾讯在网络技术领域的创新能力和开放合作的精神。通过开源的方式,腾讯可以与其他行业的开发者和研究机构共同探索和推进网络技术的发展,形成合力并推动整个行业的进步。 总的来说,腾讯的开源协议栈f-stack在DPDK技术峰会上的推出,为高性能网络数据包处理和协议栈开发提供了一个有力的工具和平台,对于促进网络技术的创新和发展具有重要意义。 ### 回答3: 腾讯的开源协议栈f-stack.pdf是关于dpdk技术峰会的一个重要文档。DPDK技术峰会是一个旨在促进DPDK技术发展和交流的会议,汇集了众多DPDK技术领域的专家和爱好者。 在f-stack.pdf中,腾讯团队分享了他们开发的开源协议栈f-stack的技术细节和应用场景。f-stack是一个高性能、可扩展的协议栈,基于DPDK技术开发,旨在提供更好的网络性能和更高的数据包处理能力。 f-stack的设计目标主要包括:轻量级、高性能、可扩展和易用性。它采用了一系列的优化技术,如零拷贝、多队列和事件驱动等,以提高数据包的处理效率。f-stack支持多种协议,如TCP、UDP和IP等,可以满足不同应用场景的需求。 此外,f-stack还提供了一些额外的功能,如高效的内存管理、负载均衡和安全性等。这些功能使得f-stack在网络应用程序的开发中更加方便和灵活。 f-stack已经在腾讯内部得到广泛的应用和验证,取得了良好的性能和稳定性。它已经成为了腾讯云和腾讯游戏等业务的核心组件。 总的来说,f-stack的出现充分展示了腾讯在DPDK技术领域的创新能力和技术实力。它为广大开发者提供了一个高效、可扩展的协议栈解决方案,有助于进一步推动DPDK技术的应用和发展。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 5
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值