記一次騰訊TBS瀏覽服務集成實踐

此次的分享源於最近的實際開發工做。javascript

項目需求是html

  • 在原生Android應用中嵌入WebView,放置用於支撐音視頻直播業務的Web頁;java

  • 另外還需提供Word、Excel、PowerPoint、PDF等常見文檔格式的內容預覽。android

通過一番技術選型,最終選定集成騰訊TBS瀏覽服務進項目,支撐如上所述兩個功能。web

能力集成

  1. 首先進入下圖所示網頁,在該下載頁下載SDK並保存。

  1. 下載成功後,將jar包放入要集成該能力的Module的libs目錄下。隨後,在Android Studio中以Project視圖方式顯示項目樹形結構,找到這個jar包,單擊右鍵,選擇「Add as Library」。稍等片刻,便可完成庫引入。安全

  2. 接着,打開Android原生項目的AndroidManifest.xml配置文件,聲明以下權限(特別注意須要申請動態權限的權限,應另外作申請):網絡

<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" />
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
<uses-permission android:name="android.permission.CAMERA" />
<uses-permission android:name="android.permission.RECORD_AUDIO" />
<uses-permission android:name="android.permission.MODIFY_AUDIO_SETTINGS" />
<uses-feature android:name="android.hardware.camera" />
<uses-feature android:name="android.hardware.camera.front" />
  1. 初始化SDK,分別在Java代碼和AndroidManifest.xml中執行如下代碼初始化騰訊TBS:
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);
<service
    android:name="com.tencent.smtt.export.external.DexClassLoaderProviderService"
    android:label="dexopt"
    android:process=":dexopt">
</service>

到此,咱們就能夠和使用系統原生WebView API同樣去使用騰訊TBS中的WebView了。在導包時,注意要導入如下包,而非系統原生:app

import com.tencent.smtt.sdk.WebSettings;
import com.tencent.smtt.sdk.WebView;
import com.tencent.smtt.sdk.WebViewClient;

載入網頁並執行JS方法

基本實現

這一步比較簡單,和使用系統原生WebView及相關API基本一致。我把要載入的網頁放到了項目的assets目錄下,所以個人這部分代碼片斷以下:ide

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對象。ui

除上述基本的加載網頁外,我還但願在網頁加載完成後調用裏面的js方法,以便在網頁加載完成後馬上開始直播。

所以,我增長了以下方法:

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方法,我以中止直播的方法爲例:

videoPreviewWv.evaluateJavascript("javascript:close()", null);

怎麼樣?還算簡單吧?不過,到此,網頁仍是顯示不正常。

通過反覆排查,我發現問題在於如下三點:

忽略SSL安全鏈接錯誤

在實際調試中,我發現只作完以上工做,網頁並不能顯示出來,緣由是SSL安全鏈接錯誤。

當遇到這種問題時,咱們但願忽略並繼續加載網頁。實現起來也很容易:

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默認容許這些權限呢?

固然有,下面是自動給予權限的相關代碼:

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)。加上以下代碼:

<style>
	 body{
        margin:0px
    }
</style>

好了,到此,WebView的嵌入就完成了。

經常使用類型文檔預覽

接下來,咱們再來聊聊使用騰訊TBS進行常見類型文檔的預覽。

下載文檔到本地

因爲文檔預覽暫時不支持在線文件,所以須要咱們先把文件下載到本地。網絡下載不是本文的重點,這裏就再也不詳述了。

不過,若是咱們須要成功使用騰訊TBS的文件預覽能力,須要在AndroidManifest.xml中作以下聲明:

<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/provide_file_paths" />
</provider>

其中,provide_file_paths內容以下:

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

關於provide_file_paths的定義規則,另請搜索:」FileProvider 路徑配置策略」。

啓動文件預覽視圖

文件下載成功後,執行下列代碼打開文件預覽界面。

HashMap<String, String> params = new HashMap<String, String>();
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);

好了,到此,咱們就完成了網頁的內嵌以及常見文檔的預覽。

本次分享到此就結束了,但願以上內容對你有所幫助。

相關文章
相關標籤/搜索