Android 開發學習程序0.28 騰訊TBS接入和相關問題
阿新 • • 發佈:2021-02-25
##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的,但為了驗證是否成功載入核心,還是有必要重寫一下方法。同時軟體需要獲取以下許可權:
```
```
注意動態許可權讀寫記憶體和讀取手機狀態的獲取。
2 TBS的兩種使用
第一種是彈出式框使用
```
filepath = "/storage/emulated/0/aaa.docx";
HashMap params = 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函式,否則再次開啟會失敗。結果如下:
###TBS使用注意事項
筆者在使用時是建立demo的方式,還是遇到了不少問題,這裡需要說明下:
1需要非安全http傳輸設定 即 manifest中`networkSecurityConfig 和`usesCleartextTraffic`的兩個屬性。
2在Android10以上非專有檔案讀寫需要設定,常用的方法是減低限制 ,在nanifest檔案中`requestLegacyExternalStorage`屬性設定為true
3 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);
}
TUIKit.init(this, GenerateTestUserSig.SDKAPPID, new ConfigHelper().getConfigs());
```
在載入核心失敗後重新下載,最後log提示安裝