本文共 6739 字,大约阅读时间需要 22 分钟。
腾讯TBS是X5内核的升级版,可以当作webview 来打开 网页,可以以用来打开docx doc pdf 等文件,这里主要使用的是文件功能。
依赖接入api 'com.tencent.tbs.tbssdk:sdk:43939'
这是笔者2021/2/25编辑时最新版本,最新可在官网查询。如果依赖文件下载有问题可手动下载jia包,本地依赖包可放在 app/libs 下,文件夹可自行创建,同时在 app/src/main/jniLibs/armeabi 下存放.so 文件。再module 的gradle文件defaultConfig下添加 ndk { abiFilters "armeabi", "x86", "mips", "armeabi-v7a" }
这是为了避免64位手机不兼容的情况,强制打包。部分博客仅添加了 “armeabi” 一项。
1 在继承的application中初始化
QbSdk.PreInitCallback cb = new QbSdk.PreInitCallback() { @Override public void onViewInitFinished(boolean arg0) { //x5內核初始化完成的回调,为true表示x5内核加载成功,否则表示x5内核加载失败,会自动切换到系统内核。 Log.e(TAG, "加载内核是否成功:" + arg0); } @Override public void onCoreInitFinished() { Log.e(TAG, "加载内核是否成功:"); } }; //x5内核初始化接口 QbSdk.initX5Environment(getApplicationContext(), cb);
这里解释下,initX5Environment初始化方法中回调是可以写做 null的,但为了验证是否成功加载内核,还是有必要重写一下方法。同时软件需要获取以下权限:
注意动态权限读写内存和读取手机状态的获取。
2 TBS的两种使用第一种是弹出式框使用filepath = "/storage/emulated/0/aaa.docx"; HashMapparams = new HashMap (); JSONObject jsonObject=new JSONObject(); try { jsonObject.put("pkgName", DocxActivity.this.getApplication().getPackageName()); } catch (JSONException e) { e.printStackTrace(); } params.put("style", "1"); params.put("local", "true"); //进入文件查看器 params.put("memuData", jsonObject.toString()); QbSdk.openFileReader(this,filepath, params,this);
结果如图所示
文件路径我使用的是根目录,目前TBS不支持网络预览文件,因此需要下载后才能打开。hashmap的参数说明如下,style是界面风格,详细可查看官方文档,local是是否进入本地文件管理器,memuData是菜单选项。由json写入。第二种是使用自己activity 创建自定义view,这种形式更加灵活,可定制性更强。public class MyTbsReadView extends FrameLayout implements TbsReaderView.ReaderCallback { private static final String TAG = "MyTbsReadView"; private TbsReaderView tbsReaderView; private int saveTime = -1; private Context context; private getFilepathListener getFilepathListener; public MyTbsReadView(@NonNull Context context) { this(context, null, 0); } public MyTbsReadView(@NonNull Context context, @Nullable AttributeSet attrs) { this(context, attrs, 0); } public MyTbsReadView(@NonNull Context context, @Nullable AttributeSet attrs, int defStyleAttr) { super(context, attrs, defStyleAttr); tbsReaderView = new TbsReaderView(context, this); this.addView(tbsReaderView, new LinearLayout.LayoutParams(-1, -1)); this.context = context; } public void show(){ if (getFilepathListener != null) { getFilepathListener.getFilePath(this); } } private TbsReaderView getTbsView(Context context) { return new TbsReaderView(context, this); } public void display(File file){ if (file != null&& !TextUtils.isEmpty(file.toString())) { String tempfilefolder="/storage/emulated/0/TbsReaderTemp"; File tempfile=new File(tempfilefolder); if (!tempfile.exists()) { boolean flag= tempfile.mkdir(); if (flag) { Log.e(TAG, "display: success" ); } else { Log.e(TAG, "display: faile" ); } } Bundle bundle =new Bundle(); bundle.putString("filePath", file.toString()); bundle.putString("tempPath", Environment.getExternalStorageDirectory()+"/"+"TbsReaderTemp"); if (tbsReaderView == null) { this.tbsReaderView=getTbsView(context); } if (this.tbsReaderView.preOpen(getFileType(file.toString()),false)) { this.tbsReaderView.openFile(bundle); } }else { Log.e(TAG, "display: file path doesn't exists" ); } } private String getFileType(String toString) { String str=""; if (TextUtils.isEmpty(toString)) { return str; } int i=toString.lastIndexOf("."); if (i <= -1) { return str; } str=toString.substring(i+1); return str; } public void setGetFilepathListener(getFilepathListener listener) { this.getFilepathListener = listener; } @Override public void onCallBackAction(Integer integer, Object o, Object o1) { Log.e(TAG, "onCallBackAction: "+integer ); } public void onStop(){ if (tbsReaderView != null) { tbsReaderView.onStop(); } } public interface getFilepathListener { void getFilePath(MyTbsReadView myTbsReadView); }}
这里是自定义view代码 。继承framelayout。使用回调填充TbsReaderView,关键代码为以下:
Bundle bundle =new Bundle(); bundle.putString("filePath", file.toString()); bundle.putString("tempPath", Environment.getExternalStorageDirectory()+"/"+"TbsReaderTemp"); if (tbsReaderView == null) { this.tbsReaderView=getTbsView(context); } if (this.tbsReaderView.preOpen(getFileType(file.toString()),false)) { this.tbsReaderView.openFile(bundle); }
tbsReaderView 传入bundle值,分别为文件路径和临时文件路径,需要注意的是TbsReaderTemp文件夹需要事先创建,但只要手机有腾讯系软件如QQ,微信,此文件夹会事先存在。
在activity中使用代码如下:filepath = "/storage/emulated/0/aaa.docx"; File myfile=new File(filepath); Log.e(TAG, "initView: "+myfile.length() ); myTbsReadView.setGetFilepathListener(new MyTbsReadView.getFilepathListener() { @Override public void getFilePath(MyTbsReadView myTbsReadView) { myTbsReadView.display(myfile); } }); myTbsReadView.show();
添加文件导入监听,触发时使用show函数,需要注意的是需要在activity销毁时调用组件的onStop函数,否则再次打开会失败。结果如下:
笔者在使用时是创建demo的方式,还是遇到了不少问题,这里需要说明下:
1需要非安全http传输设置 即 manifest中networkSecurityConfig 和
usesCleartextTraffic的两个属性。 2在Android10以上非专有文件读写需要设置,常用的方法是减低限制 ,在nanifest文件中
requestLegacyExternalStorage`属性设置为true3 manifest中provider provider_file_path文件如下
4 X5内核加载失败,具体表现为 “ not supported by:doc” 这个问题困扰笔者许久,最后的解决方式是在继承的application文件中,即初始化X5中添加
QbSdk.setTbsListener(new TbsListener() { @Override public void onDownloadFinish(int i) { } @Override public void onInstallFinish(int i) { Log.e(TAG, "onInstallFinish: 内核下载安装成功" ); } @Override public void onDownloadProgress(int i) { } }); boolean needDownload = TbsDownloader.needDownload(this, TbsDownloader.DOWNLOAD_OVERSEA_TBS); Log.e(TAG, "onCreate: "+needDownload ); if (needDownload) { TbsDownloader.startDownload(this); }
在加载内核失败后重新下载,最后log提示安装成功。
转载地址:http://kcpkz.baihongyu.com/