記一次騰訊TBS瀏覽服務整合實踐
阿新 • • 發佈:2020-11-30
這次的分享源於最近的實際開發工作。
專案需求是
- 在原生Android應用中嵌入WebView,放置用於支撐音視訊直播業務的Web頁;
- 另外還需提供Word、Excel、PowerPoint、PDF等常見文件格式的內容預覽。
經過一番技術選型,最終選定整合騰訊TBS瀏覽服務進專案,支撐如上所述兩個功能。
# 能力整合
1. 首先進入下圖所示網頁,在該下載頁下載SDK並儲存。
![](https://img2020.cnblogs.com/blog/1595922/202011/1595922-20201130132211643-125260206.png)
2. 下載成功後,將jar包放入要整合該能力的Module的libs目錄下。隨後,在Android Studio中以Project檢視方式顯示專案樹形結構,找到這個jar包,單擊右鍵,選擇“Add as Library”。稍等片刻,即可完成庫引入。
3. 接著,開啟Android原生專案的AndroidManifest.xml配置檔案,宣告如下許可權(特別注意需要申請動態許可權的許可權,應另外做申請):
```xml
```
4. 初始化SDK,分別在Java程式碼和AndroidManifest.xml中執行以下程式碼初始化騰訊TBS:
```java
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);
```
```xml
```
到此,我們就可以和使用系統原生WebView API一樣去使用騰訊TBS中的WebView了。在導包時,注意要匯入以下包,而非系統原生:
```java
import com.tencent.smtt.sdk.WebSettings;
import com.tencent.smtt.sdk.WebView;
import com.tencent.smtt.sdk.WebViewClient;
```
# 載入網頁並執行JS方法
## 基本實現
這一步比較簡單,和使用系統原生WebView及相關API基本一致。我把要載入的網頁放到了專案的assets目錄下,因此我的這部分程式碼片段如下:
```java
WebSettings webSettings = videoPreviewWv.getSettings();
webSettings.setJavaScriptEnabled(true);
webSettings.setJavaScriptCanOpenWindowsAutomatically(true);
webSettings.setUseWideViewPort(true);
webSettings.setLoadWithOverviewMode(true);
webSettings.setSupportZoom(true);
webSettings.setBuiltInZoomControls(true);
webSettings.setDisplayZoomControls(false);
webSettings.setAllowFileAccess(true);
webSettings.setDomStorageEnabled(true);
webSettings.setDatabaseEnabled(true);
webSettings.setAppCacheEnabled(true);
videoPreviewWv.loadUrl(Environment.VIDEO_RECORD_URL);
```
注:videoPreviewWv為WebView物件。
除上述基本的載入網頁外,我還希望在網頁載入完成後呼叫裡面的js方法,以便在網頁載入完成後立刻開始直播。
因此,我增加了如下方法:
```java
videoPreviewWv.setWebViewClient(new WebViewClient() {
@Override
public void onPageFinished(WebView webView, String s) {
super.onPageFinished(webView, s);
String jsStr = "javascript:open('" + SharedPrefUtil.getToken(activity) + "', '" + Environment.VIDEO_IP + "', " + Integer.parseInt(sn) + ", '" + Environment.VIDEO_STUN_IP + "'" + ")";
videoPreviewWv.evaluateJavascript(jsStr, null);
}
});
```
當網頁載入完畢後,onPageFinished()方法被回撥。
evaluateJavascript()則負責呼叫js方法,各位可以按照jsStr字串的值作為格式參考,適配自己的js檔案。
如上程式碼所示,當網頁載入完畢後,我呼叫了js中的open()方法,傳入了token、視訊推流IP等引數。
對於無需任何引數的js方法,我以停止直播的方法為例:
```java
videoPreviewWv.evaluateJavascript("javascript:close()", null);
```
怎麼樣?還算簡單吧?不過,到此,網頁還是顯示不正常。
經過反覆排查,我發現問題在於以下三點:
## 忽略SSL安全連線錯誤
在實際除錯中,我發現只做完以上工作,網頁並不能顯示出來,原因是SSL安全連線錯誤。
當遇到這種問題時,我們希望忽略並繼續載入網頁。實現起來也很容易:
```java
videoPreviewWv.setWebViewClient(new com.tencent.smtt.sdk.WebViewClient() {
@Override
public void onReceivedSslError(WebView webView, com.tencent.smtt.export.external.interfaces.SslErrorHandler sslErrorHandler, com.tencent.smtt.export.external.interfaces.SslError sslError) {
sslErrorHandler.proceed();
}
});
```
## 預設給予攝像頭、麥克風許可權
到此,網頁可以顯示了。但是,依然存在不足。
每次執行js的open()方法時,由於網頁會請求攝像頭和麥克風的許可權,依然會有許可權請求的對話方塊,而實際上使用者已經在之前,被原生程式碼請求過許可權需求了。這樣一來,相當於重複請求許可權。而且每次開啟直播,都會請求一次。
那麼,有沒有辦法讓嵌入的WebView預設允許這些許可權呢?
當然有,下面是自動給予許可權的相關程式碼:
```java
videoPreviewWv.setWebChromeClientExtension(new IX5WebChromeClientExtension() {
@Override
public boolean onPermissionRequest(String s, long l, MediaAccessPermissionsCallback mediaAccessPermissionsCallback) {
long allowed = 0;
allowed = allowed | MediaAccessPermissionsCallback.ALLOW_AUDIO_CAPTURE;
mediaAccessPermissionsCallback.invoke(s, allowed, true);
return true;
}
}
```
## 網頁預設白邊的消除
經過上述一系列操作,我們想要的功能已經實現了。不過還有最後一點美中不足——網頁有白邊。
這個問題其實不是原生程式碼的問題,需要修改嵌入的Web頁面(HTML)。加上如下程式碼:
```html
```
好了,到此,WebView的嵌入就完成了。
# 常用型別文件預覽
接下來,我們再來聊聊使用騰訊TBS進行常見型別文件的預覽。
## 下載文件到本地
由於文件預覽暫時不支援線上檔案,因此需要我們先把檔案下載到本地。網路下載不是本文的重點,這裡就不再詳述了。
不過,如果我們需要成功使用騰訊TBS的檔案預覽能力,需要在AndroidManifest.xml中做如下宣告:
```xml
```
其中,provide_file_paths內容如下:
```xml
```
關於provide_file_paths的定義規則,另請搜尋:”FileProvider 路徑配置策略”。
## 啟動檔案預覽檢視
檔案下載成功後,執行下列程式碼開啟檔案預覽介面。
```java
HashMap params = new HashMap();
params.put("local", "true");
params.put("style", "1");
JSONObject Object = new JSONObject();
try {
Object.put("pkgName", activity.getApplicationContext().getPackageName());
} catch (JSONException e) {
e.printStackTrace();
}
params.put("menuData", Object.toString());
QbSdk.openFileReader(activity, file.getAbsolutePath(), params, null);
```
好了,到此,我們就完成了網頁的內嵌以及常見文件的預覽。
本次分享到此就結束了,希望以上內容對你有所幫助。