经验首页 前端设计 程序设计 Java相关 移动开发 数据库/运维 软件/图像 大数据/云计算 其他经验
当前位置:技术经验 » 移动开发 » Android » 查看文章
记一次腾讯TBS浏览服务集成实践
来源:cnblogs  作者:萧文翰  时间:2020/12/8 8:44:59  对本文有异议

这次的分享源于最近的实际开发工作。

项目需求是

  • 在原生Android应用中嵌入WebView,放置用于支撑音视频直播业务的Web页;

  • 另外还需提供Word、Excel、PowerPoint、PDF等常见文档格式的内容预览。

经过一番技术选型,最终选定集成腾讯TBS浏览服务进项目,支撑如上所述两个功能。

能力集成

  1. 首先进入下图所示网页,在该下载页下载SDK并保存。

  1. 下载成功后,将jar包放入要集成该能力的Module的libs目录下。随后,在Android Studio中以Project视图方式显示项目树形结构,找到这个jar包,单击右键,选择“Add as Library”。稍等片刻,即可完成库引入。

  2. 接着,打开Android原生项目的AndroidManifest.xml配置文件,声明如下权限(特别注意需要申请动态权限的权限,应另外做申请):

  1. <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
  2. <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
  3. <uses-permission android:name="android.permission.ACCESS_WIFI_STATE" />
  4. <uses-permission android:name="android.permission.INTERNET" />
  5. <uses-permission android:name="android.permission.READ_PHONE_STATE" />
  6. <uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />
  7. <uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
  8. <uses-permission android:name="android.permission.CAMERA" />
  9. <uses-permission android:name="android.permission.RECORD_AUDIO" />
  10. <uses-permission android:name="android.permission.MODIFY_AUDIO_SETTINGS" />
  11. <uses-feature android:name="android.hardware.camera" />
  12. <uses-feature android:name="android.hardware.camera.front" />
  1. 初始化SDK,分别在Java代码和AndroidManifest.xml中执行以下代码初始化腾讯TBS:
  1. HashMap map = new HashMap();
  2. map.put(TbsCoreSettings.TBS_SETTINGS_USE_SPEEDY_CLASSLOADER, true);
  3. map.put(TbsCoreSettings.TBS_SETTINGS_USE_DEXLOADER_SERVICE, true);
  4. QbSdk.initTbsSettings(map);
  1. <service
  2. android:name="com.tencent.smtt.export.external.DexClassLoaderProviderService"
  3. android:label="dexopt"
  4. android:process=":dexopt">
  5. </service>

到此,我们就可以和使用系统原生WebView API一样去使用腾讯TBS中的WebView了。在导包时,注意要导入以下包,而非系统原生:

  1. import com.tencent.smtt.sdk.WebSettings;
  2. import com.tencent.smtt.sdk.WebView;
  3. import com.tencent.smtt.sdk.WebViewClient;

载入网页并执行JS方法

基本实现

这一步比较简单,和使用系统原生WebView及相关API基本一致。我把要载入的网页放到了项目的assets目录下,因此我的这部分代码片段如下:

  1. WebSettings webSettings = videoPreviewWv.getSettings();
  2. webSettings.setJavaScriptEnabled(true);
  3. webSettings.setJavaScriptCanOpenWindowsAutomatically(true);
  4. webSettings.setUseWideViewPort(true);
  5. webSettings.setLoadWithOverviewMode(true);
  6. webSettings.setSupportZoom(true);
  7. webSettings.setBuiltInZoomControls(true);
  8. webSettings.setDisplayZoomControls(false);
  9. webSettings.setAllowFileAccess(true);
  10. webSettings.setDomStorageEnabled(true);
  11. webSettings.setDatabaseEnabled(true);
  12. webSettings.setAppCacheEnabled(true);
  13. videoPreviewWv.loadUrl(Environment.VIDEO_RECORD_URL);

注:videoPreviewWv为WebView对象。

除上述基本的加载网页外,我还希望在网页加载完成后调用里面的js方法,以便在网页加载完成后立刻开始直播。

因此,我增加了如下方法:

  1. videoPreviewWv.setWebViewClient(new WebViewClient() {
  2. @Override
  3. public void onPageFinished(WebView webView, String s) {
  4. super.onPageFinished(webView, s);
  5. String jsStr = "javascript:open('" + SharedPrefUtil.getToken(activity) + "', '" + Environment.VIDEO_IP + "', " + Integer.parseInt(sn) + ", '" + Environment.VIDEO_STUN_IP + "'" + ")";
  6. videoPreviewWv.evaluateJavascript(jsStr, null);
  7. }
  8. });

当网页加载完毕后,onPageFinished()方法被回调。

evaluateJavascript()则负责调用js方法,各位可以按照jsStr字符串的值作为格式参考,适配自己的js文件。

如上代码所示,当网页加载完毕后,我调用了js中的open()方法,传入了token、视频推流IP等参数。

对于无需任何参数的js方法,我以停止直播的方法为例:

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

怎么样?还算简单吧?不过,到此,网页还是显示不正常。

经过反复排查,我发现问题在于以下三点:

忽略SSL安全连接错误

在实际调试中,我发现只做完以上工作,网页并不能显示出来,原因是SSL安全连接错误。

当遇到这种问题时,我们希望忽略并继续加载网页。实现起来也很容易:

  1. videoPreviewWv.setWebViewClient(new com.tencent.smtt.sdk.WebViewClient() {
  2. @Override
  3. public void onReceivedSslError(WebView webView, com.tencent.smtt.export.external.interfaces.SslErrorHandler sslErrorHandler, com.tencent.smtt.export.external.interfaces.SslError sslError) {
  4. sslErrorHandler.proceed();
  5. }
  6. });

默认给予摄像头、麦克风权限

到此,网页可以显示了。但是,依然存在不足。

每次执行js的open()方法时,由于网页会请求摄像头和麦克风的权限,依然会有权限请求的对话框,而实际上用户已经在之前,被原生代码请求过权限需求了。这样一来,相当于重复请求权限。而且每次开启直播,都会请求一次。

那么,有没有办法让嵌入的WebView默认允许这些权限呢?

当然有,下面是自动给予权限的相关代码:

  1. videoPreviewWv.setWebChromeClientExtension(new IX5WebChromeClientExtension() {
  2. @Override
  3. public boolean onPermissionRequest(String s, long l, MediaAccessPermissionsCallback mediaAccessPermissionsCallback) {
  4. long allowed = 0;
  5. allowed = allowed | MediaAccessPermissionsCallback.ALLOW_AUDIO_CAPTURE;
  6. mediaAccessPermissionsCallback.invoke(s, allowed, true);
  7. return true;
  8. }
  9. }

网页默认白边的消除

经过上述一系列操作,我们想要的功能已经实现了。不过还有最后一点美中不足——网页有白边。

这个问题其实不是原生代码的问题,需要修改嵌入的Web页面(HTML)。加上如下代码:

  1. <style>
  2. body{
  3. margin:0px
  4. }
  5. </style>

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

常用类型文档预览

接下来,我们再来聊聊使用腾讯TBS进行常见类型文档的预览。

下载文档到本地

由于文档预览暂时不支持在线文件,因此需要我们先把文件下载到本地。网络下载不是本文的重点,这里就不再详述了。

不过,如果我们需要成功使用腾讯TBS的文件预览能力,需要在AndroidManifest.xml中做如下声明:

  1. <provider
  2. android:name="androidx.core.content.FileProvider"
  3. android:authorities="${applicationId}"
  4. android:exported="false"
  5. android:grantUriPermissions="true">
  6. <meta-data
  7. android:name="android.support.FILE_PROVIDER_PATHS"
  8. android:resource="@xml/provide_file_paths" />
  9. </provider>

其中,provide_file_paths内容如下:

  1. <?xml version="1.0" encoding="utf-8"?>
  2. <resources>
  3. <paths>
  4. <external-path
  5. name="sdcard"
  6. path="" />
  7. <files-path
  8. name="my_files"
  9. path="cache" />
  10. </paths>
  11. </resources>

关于provide_file_paths的定义规则,另请搜索:”FileProvider 路径配置策略”。

启动文件预览视图

文件下载成功后,执行下列代码打开文件预览界面。

  1. HashMap<String, String> params = new HashMap<String, String>();
  2. params.put("local", "true");
  3. params.put("style", "1");
  4. JSONObject Object = new JSONObject();
  5. try {
  6. Object.put("pkgName", activity.getApplicationContext().getPackageName());
  7. } catch (JSONException e) {
  8. e.printStackTrace();
  9. }
  10. params.put("menuData", Object.toString());
  11. QbSdk.openFileReader(activity, file.getAbsolutePath(), params, null);

好了,到此,我们就完成了网页的内嵌以及常见文档的预览。

本次分享到此就结束了,希望以上内容对你有所帮助。

原文链接:http://www.cnblogs.com/wenhanxiao/p/14060779.html

 友情链接:直通硅谷  点职佳  北美留学生论坛

本站QQ群:前端 618073944 | Java 606181507 | Python 626812652 | C/C++ 612253063 | 微信 634508462 | 苹果 692586424 | C#/.net 182808419 | PHP 305140648 | 运维 608723728

W3xue 的所有内容仅供测试,对任何法律问题及风险不承担任何责任。通过使用本站内容随之而来的风险与本站无关。
关于我们  |  意见建议  |  捐助我们  |  报错有奖  |  广告合作、友情链接(目前9元/月)请联系QQ:27243702 沸活量
皖ICP备17017327号-2 皖公网安备34020702000426号