此次的分享源于最近的实际开发工做。javascript
项目需求是html
在原生Android应用中嵌入WebView,放置用于支撑音视频直播业务的Web页;java
另外还需提供Word、Excel、PowerPoint、PDF等常见文档格式的内容预览。android
通过一番技术选型,最终选定集成腾讯TBS浏览服务进项目,支撑如上所述两个功能。web
下载成功后,将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" />
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;
这一步比较简单,和使用系统原生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安全链接错误。
当遇到这种问题时,咱们但愿忽略并继续加载网页。实现起来也很容易:
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);
好了,到此,咱们就完成了网页的内嵌以及常见文档的预览。
本次分享到此就结束了,但愿以上内容对你有所帮助。