這次的分享源于最近的實際開發作業,
專案需求是
-
在原生Android應用中嵌入WebView,放置用于支撐音視頻直播業務的Web頁;
-
另外還需提供Word、Excel、PowerPoint、PDF等常見檔案格式的內容預覽,
經過一番技術選型,最終選定集成騰訊TBS瀏覽服務進專案,支撐如上所述兩個功能,
能力集成
- 首先進入下圖所示網頁,在該下載頁下載SDK并保存,

-
下載成功后,將jar包放入要集成該能力的Module的libs目錄下,隨后,在Android Studio中以Project視圖方式顯示專案樹形結構,找到這個jar包,單擊右鍵,選擇“Add as Library”,稍等片刻,即可完成庫引入,
-
接著,打開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" />
- 初始化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了,在導包時,注意要匯入以下包,而非系統原生:
import com.tencent.smtt.sdk.WebSettings;
import com.tencent.smtt.sdk.WebView;
import com.tencent.smtt.sdk.WebViewClient;
載入網頁并執行JS方法
基本實作
這一步比較簡單,和使用系統原生WebView及相關API基本一致,我把要載入的網頁放到了專案的assets目錄下,因此我的這部分代碼片段如下:
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方法,以便在網頁加載完成后立刻開始直播,
因此,我增加了如下方法:
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);
好了,到此,我們就完成了網頁的內嵌以及常見檔案的預覽,
本次分享到此就結束了,希望以上內容對你有所幫助,
轉載請註明出處,本文鏈接:https://www.uj5u.com/yidong/229055.html
標籤:其他
