最近公司在 Android 端进行点对点视频通话,PC-Android,使用的是 webrtc ,所以 Android 这边的工作就变的非常简单,用个 WebView 加载下视频通话的页面就好了,但是,用原生的 WebView 只有很少的手机可以进行正常的视频通话,版本高的版本低的都有,要么没有 PC 端画面,要么 PC 端呼叫看不到 Android 端画面,问题蛮多的,我用微信加载了下视频通话链接,发现大多数手机都是正常的,并且会请求麦克风和摄像头权限,于是 怀疑是权限问题,BUT BUT Android 应用请求麦克风和摄像头对网页没用,所以让网页那边找权限问题,但是 , 没用 !!! 于是乎,开始了一段有趣的搜索旅程,为啥有趣,就是因为 在搜索 “为什么微信可以加载而 Android 自带 WebView 无法加载”的时候,居然没有人推荐使用腾讯 X5 WebView ,搜索 webrtc 找到了 找到了。。 要不是我今年开始写 H5 项目,也不会这样搜索,事实证明,多学一点 总是好的。
正文开始 ,主要是 腾讯 X5 WebView 的使用,问题不大的小伙伴 可以直接进 腾讯浏览服务 文档中心 快速接入 ,Other 可以继续看下去 ......
1、在自己的项目中引入依赖
api 'com.tencent.tbs.tbssdk:sdk:43903'
在 AndroidManifest.xml 中
<!-- 腾讯 X5 内核 冷启动优化 -->
<service
android:name="com.tencent.smtt.export.external.DexClassLoaderProviderService"
android:label="dexopt"
android:process=":dexopt"/>
添加配置
ndk {
//选择要添加的对应cpu类型的.so库。
abiFilters 'armeabi', 'armeabi-v7a', 'arm64-v8a', 'x86', 'x86_64', 'mips', 'mips64'
}
权限配置
<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" />
混淆配置
注意:如果自己项目没有混淆 这个就不需要
-dontwarn dalvik.**
-dontwarn com.tencent.smtt.**
-keep class com.tencent.smtt.** {
*;
}
-keep class com.tencent.tbs.** {
*;
}
2、在自己的 Application 中进行初始化
// 在调用TBS初始化、创建WebView之前进行如下配置
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);
// 初始化 腾讯X5n WebView
//搜集本地tbs内核信息并上报服务器,服务器返回结果决定使用哪个内核。
QbSdk.PreInitCallback cb = new QbSdk.PreInitCallback() {
@Override
public void onViewInitFinished(boolean arg0) {
// TODO Auto-generated method stub
//x5內核初始化完成的回调,为true表示x5内核加载成功,否则表示x5内核加载失败,会自动切换到系统内核。
isX5 = arg0;
Log.e("腾讯X5", " onViewInitFinished is " + arg0);
}
@Override
public void onCoreInitFinished() {
// TODO Auto-generated method stub
Log.e("腾讯X5", " onCoreInitFinished");
}
};
//x5内核初始化接口
QbSdk.initX5Environment(getApplicationContext(), cb);
至此,已完成 WebView 的初始化,可以在自己的项目中直接使用,BUT,(BUT 这个词是个不好的预兆哦,是我踩的坑),经过多次测试,发现很多手机其实在第一次的时候初始化是不成功的,当杀掉近程再次进入的时候就会正常了,后来度娘,说是因为腾讯内核在第一次使用的时候需要下载,如果用户打开应用时间不够的话,会初始化失败!!在onViewInitFinished()
会返回 腾讯 X5 WebView 是否加载成功,如果加载成功就使用 腾讯X5 WebView,如果加载失败就使用系统自带的 WebView.
后来发现在自己的
<!-- 腾讯 X5 android 6.0 以后系统 需要配置 FileProvider-->
<provider
android:name="com.tencent.smtt.utils.FileProvider"
android:authorities="${applicationId}.fileProvider"
android:exported="false"
android:grantUriPermissions="true">
<meta-data
android:name="android.support.FILE_PROVIDER_PATHS"
android:resource="@xml/x5webview_file_paths" />
</provider>
xml 配置:
<?xml version="1.0" encoding="utf-8"?>
<paths xmlns:android="http://schemas.android.com/apk/res/android">
<external-path
name="sdcard"
path="."/>
</paths>
使用示例:
这里使用 com.tencent.smtt.sdk.WebView 而不是使用系统的 WebView
<com.tencent.smtt.sdk.WebView
android:id="@+id/webview"
android:layout_width="match_parent"
android:layout_height="match_parent" />
com.tencent.smtt.sdk.WebSettings webSettings = webView.getSettings();
//设置JavaScrip
webSettings.setJavaScriptEnabled(true);
//5.0以上开启混合模式加载
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
webSettings.setMixedContentMode(WebSettings.MIXED_CONTENT_ALWAYS_ALLOW);
}
webSettings.setSupportMultipleWindows(true);
webSettings.setUseWideViewPort(true);//自适应手机屏幕
webSettings.setAllowContentAccess(true);
webSettings.setDomStorageEnabled(true);
webSettings.setLoadsImagesAutomatically(true);
webSettings.setLoadWithOverviewMode(true);
webSettings.setAppCacheEnabled(true);
webSettings.setBlockNetworkImage(true);
webSettings.setAllowFileAccess(true);
//
//加载本地html文件
// mWVmhtml.loadUrl("file:///android_asset/hello.html");
//加载网络URL
webView.loadUrl(“访问的url地址”);
// //设置在当前WebView继续加载网页
webView.setWebViewClient(new WebX5Activity.MyWebViewClient());
webView.setWebChromeClient(new WebX5Activity.MyWebChromeClient());
class MyWebViewClient extends WebViewClient {
@Override //WebView代表是当前的WebView
public boolean shouldOverrideUrlLoading(WebView view, String url) {
view.loadUrl(url);
return true;
}
@Override
public void onPageStarted(WebView view, String url, Bitmap favicon) {
super.onPageStarted(view, url, favicon);
Log.d("WebView", "开始访问网页");
}
@Override
public void onPageFinished(WebView view, String url) {
super.onPageFinished(view, url);
Log.d("WebView", "访问网页结束");
}
@Override
public void onReceivedError(WebView webView, int i, String s, String s1) {
Log.d("WebView", "***********onReceivedError***********");
super.onReceivedError(webView, i, s, s1);
}
@Override
public void onReceivedSslError(WebView view, SslErrorHandler handler, SslError error) {
handler.proceed(); // 等待证书响应
}
}
class MyWebChromeClient extends WebChromeClient {
@Override //监听加载进度
public void onProgressChanged(WebView view, int newProgress) {
super.onProgressChanged(view, newProgress);
}
@Override//接受网页标题
public void onReceivedTitle(WebView view, String title) {
super.onReceivedTitle(view, title);
//把当前的Title设置到Activity的title上显示
setTitle(title);
}
@Override
public void onPermissionRequest(final PermissionRequest request) {
WebX5Activity.this.runOnUiThread(new Runnable() {
@TargetApi(Build.VERSION_CODES.LOLLIPOP)
@Override
public void run() {
request.grant(request.getResources());
}
});
}
}
至此 WebView 的使用完成。
如果你有梦想,请一定为它勇敢一次。 ——— 致自己和看到的每一位
网友评论