TBS 的接入和使用

TBS 的接入

腾讯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” 一项。

TBS 的使用

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的,但为了验证是否成功加载内核,还是有必要重写一下方法。同时软件需要获取以下权限:

    <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
<uses-permission android:name="android.permission.ACCESS_WIFI_STATE" />
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.READ_PHONE_STATE" />

注意动态权限读写内存和读取手机状态的获取。

2 TBS的两种使用

第一种是弹出式框使用

  filepath = "/storage/emulated/0/aaa.docx";
HashMap<String, String> params = new HashMap<String, String>();
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函数,否则再次打开会失败。结果如下:

TBS使用注意事项

笔者在使用时是创建demo的方式,还是遇到了不少问题,这里需要说明下:

1需要非安全http传输设置 即 manifest中networkSecurityConfig 和usesCleartextTraffic的两个属性。 2在Android10以上非专有文件读写需要设置,常用的方法是减低限制 ,在nanifest文件中requestLegacyExternalStorage`属性设置为true

3 manifest中provider

  <!-- 非AndroidX使用 android:name="android.support.v4.content.FileProvider"-->
<provider
android:name="androidx.core.content.FileProvider"
android:authorities="${applicationId}"
android:exported="false"
android:grantUriPermissions="true">
<meta-data
android:name="android.support.FILE_PROVIDER_PATHS"
android:resource="@xml/provider_file_paths"/>
</provider>

provider_file_path文件如下

<?xml version="1.0" encoding="utf-8"?>
<resources>
<paths>
<external-path path="" name="sdcard"/>
</paths>
</resources>

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);
}
TUIKit.init(this, GenerateTestUserSig.SDKAPPID, new ConfigHelper().getConfigs());

在加载内核失败后重新下载,最后log提示安装成功。

Android 开发学习进程0.28 腾讯TBS接入和相关问题的更多相关文章

  1. Android 开发学习进程0.16 layout_weight属性 R文件关联XML Module

    layout_weight属性 layout_weight属性我们常常用到,但有时候会发现它还有一些奇怪的属性,比如大多数使用时会把宽度设置成0,但要是宽度不设置成0会有什么效果? layout_we ...

  2. Android 开发学习进程0.19 webview 的使用

    Android 中的webview android 中的webview是可以在app内部打开HTML等的网页,不必再打开浏览器,有两种实现方法,即webviewclient webChromeclie ...

  3. Android开发学习进程0.18 SharePreference的使用 AIDL

    SharePreference SharePreference是一种持久化存储手段,使用场景很多,如第一次打开时加载的用户协议等.适合小数据单进程的应用.将数据以键值对的形式存储在XML中. 使用方式 ...

  4. Android 开发学习进程0.17 Android资源文件selector textview显示两种不同字体

    selector 是安卓资源文件的一种,它可以使按钮等实现不同状态下的不同UI,不用在代码中实现,而使用方式有两种,一种在color文件下 创建.xml可以使按钮等字体在不同状态下的变化,其二是在dr ...

  5. Android 开发学习进程0.15 adb cardview framelayout 控件设置状态获取焦点

    Android设备调试桥 即adb 使用adb进行无线调试的一些常用命令 adb tcpip 5555 设置调试端口为5555 防止冲突 adb shell ifconfig wlan0 查询局域网中 ...

  6. Android 开发学习进程0.27 kotlin使用 和viewbinding的使用

    kotlin-android-extensions 插件被废弃 笔者曾经尝试写过一部分的kotlin代码 主要是项目中一些代码是kotlin完成的,其中我认为 kotlin的kotlin-androi ...

  7. Android 开发学习进程0.32 dwonloadmanager使用

    downloadmanager时Android系统下载器,使用系统下载器可以避免用stream流读入内存可能导致的内存溢出问题.以下为downloadmanager初始化部分.apkurl为下载网络路 ...

  8. Android 开发学习进程0.14 Bindview recyclerview popwindow使用 window类属性使用

    BindView ButterKnife 优势 绑定组件方便,使用简单 处理点击事件方便,如adapter中的viewholder 同时父组件绑定后子组件无需绑定 注意 在setcontentview ...

  9. Android 开发学习进程0.13 Androidstudio快捷键 xmlns

    xmlns XML namespace xml命名空间 其中主要是定义xml文件定义位置 前缀有三种,android app tools 后面为唯一标识符URI android 表示为引用自安卓系统 ...

随机推荐

  1. 腾讯云TcaplusDB获新加坡MTCS最高等级安全认证

    近日,经过国际权威认证机构DNV GL的全面评估审核,TcaplusDB获得了新加坡多层云安全(以下简称"MTCS")T3级最高等级认证,这标志着TcaplusDB全面满足了新加坡 ...

  2. linux(11)配置环境变量

    前言 在自定义安装软件的时候,经常需要配置环境变量,下面进行详细解析 & nbsp; 环境变量配置文件 用户 配置文件 系统环境 /ect/profile /etc/bashrc /etc/e ...

  3. RAID 技术全解

    图文并茂 RAID 技术全解 – RAID0.RAID1.RAID5.RAID100-- RAID 技术相信大家都有接触过,尤其是服务器运维人员,RAID 概念很多,有时候会概念混淆.这篇文章为网络转 ...

  4. http post请求数组参数写法

    1.json形式 body如下(注意是中括号): [ *, *, * ] postman: fiddler: 2.x-www-form-urlencoded postman: fiddler: 3.服 ...

  5. 【.NET 与树莓派】让喇叭播放音乐

    如果你和老周一样,小时候特别喜欢搞破坏(什么电器都敢拆),那下面这样小喇叭你一定见过. 这种喇叭其实以前很多录音机都用,包括上小学时买来做英语听力的便携录音机.嗯,就是放录音带的那种,录音带也叫磁带或 ...

  6. K8S(03)核心插件-Flannel网络插件

    系列文章说明 本系列文章,可以基本算是 老男孩2019年王硕的K8S周末班课程 笔记,根据视频来看本笔记最好,否则有些地方会看不明白 需要视频可以联系我 K8S核心网络插件Flannel 目录 系列文 ...

  7. python函数传参

    之前一直没有注意过该问题,在leetcode144中写递归发现该问题,不知道递归函数传参是指针还是引用. 参考:http://c.biancheng.net/view/2258.html 如果是不可变 ...

  8. 微服务架构Day05-SpringBoot之Servlet

    旧版 配置嵌入式Servlet容器 SpringBoot默认使用Tomcat作为嵌入式Servlet容器 如何定制和修改Servlet容器相关配置 1.在配置文件中定制和修改Servlet容器有关的配 ...

  9. css background transparent All In One

    css background transparent All In One opacity ul { max-height: 100px; /* max-height: 187px; */ overf ...

  10. Trailing commas

    Trailing commas 尾逗号 https://caniuse.com/?search=trailing commas ESlint { "comma-dangle": [ ...