概述
上节完成嘟妈vant ui部署。Vant 是有赞团队开源的移动端 Vue UI 组件库,vant 专门针对移动端优化。适用场景:
- 手机 H5 页面
- 微信公众号
- 企业微信应用
- 钉钉应用
- UniApp H5 嘟宝是为监督孩子身边环境而创建的一套应用,它能够实现后台驻留长连接,随时接收嘟妈信令,建立音视频通道点对点通信,而不需要中转 服务器。嘟妈是一套WEB 应用,使用vue3编写,能够兼容app、小程序开发。目前为止,嘟宝完成的基本功能设计包括
- MQTT 基础通信
- 后台驻留
- SQLite数据存储
- 二维码显示身份识别码
- 开启自启动前台服务
- 任务栏消息发送与点击 嘟宝使用WebRtc与嘟妈建立音视频通信,它的核心需求包含以下部分:
- 嘟妈获取嘟宝摄像头、麦克风音视频流
- 获取嘟宝桌面共享内容
- 嘟妈与嘟宝建立音视频通话 嘟妈采用vue3编写,使用agentweb在Android终端渲染,发现在拉去嘟宝视频流观看时,无法全屏。
agentweb如何实现全屏
- 修改activity开启硬件加速,防止屏幕旋转时 Activity 重建
- 需要一个容器(比如 FrameLayout)来展示全屏时的视频画面
创建DuMaActivity用于渲染vue3
修改 Manifest 清单文件
clike
<activity
android:name=".DuMaActivity"
android:hardwareAccelerated="true"
android:configChanges="orientation|screenSize|keyboardHidden"
android:theme="@style/Theme.AppCompat.Light.NoActionBar"
android:exported="false" />
DuMaActivity源码
clike
package com.zilong.dubao;
import androidx.appcompat.app.AppCompatActivity;
import android.content.pm.ActivityInfo;
import android.os.Build;
import android.os.Bundle;
import android.view.KeyEvent;
import android.view.View;
import android.view.ViewGroup;
import android.webkit.WebSettings;
import android.webkit.WebView;
import android.widget.FrameLayout;
import android.widget.LinearLayout;
import com.just.agentweb.AgentWeb;
import com.just.agentweb.WebChromeClient;
public class DuMaActivity extends AppCompatActivity {
private AgentWeb mAgentWeb;
private FrameLayout mFullscreenContainer;
private View mCustomView;
private WebChromeClient.CustomViewCallback mCustomViewCallback;
// 2. 自定义 WebChromeClient
private WebChromeClient mWebChromeClient = new WebChromeClient() {
@Override
public void onShowCustomView(View view, CustomViewCallback callback) {
// 进入全屏
if (mCustomView != null) {
callback.onCustomViewHidden();
return;
}
mCustomView = view;
mCustomViewCallback = callback;
// 将全屏视频 View 添加到容器中
mFullscreenContainer.addView(view);
mFullscreenContainer.setVisibility(View.VISIBLE);
// 隐藏 AgentWeb 和标题栏等
mAgentWeb.getWebCreator().getWebView().setVisibility(View.GONE);
// 隐藏你的 Toolbar
// getSupportActionBar().hide();
// 可选:强制横屏
setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE);
}
@Override
public void onHideCustomView() {
// 退出全屏
if (mCustomView == null) {
return;
}
// 移除全屏视频 View
mFullscreenContainer.removeView(mCustomView);
mFullscreenContainer.setVisibility(View.GONE);
// 恢复 AgentWeb 和标题栏的显示
mAgentWeb.getWebCreator().getWebView().setVisibility(View.VISIBLE);
// 恢复显示你的 Toolbar
// getSupportActionBar().show();
// 恢复竖屏
setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_PORTRAIT);
// 通知 WebView 全屏已退出
mCustomViewCallback.onCustomViewHidden();
mCustomView = null;
mCustomViewCallback = null;
}
};
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_du_ma);
LinearLayout container = findViewById(R.id.web_container);
mFullscreenContainer = findViewById(R.id.fullscreen_container);
// 2. 构建 AgentWeb 实例
mAgentWeb = AgentWeb.with(this) // 传入 Activity
.setAgentWebParent(container, new LinearLayout.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.MATCH_PARENT)) // 设置父控件和布局参数
.useDefaultIndicator() // 使用默认进度条
.setWebChromeClient(mWebChromeClient)
.createAgentWeb() // 创建 AgentWeb 对象
.ready() // 准备就绪
.go(MyConfig.dumaURL);
// 注意:如果 HTML 中使用了 JavaScript,需要手动启用
if (mAgentWeb != null && mAgentWeb.getAgentWebSettings() != null) {
mAgentWeb.getAgentWebSettings().getWebSettings().setJavaScriptEnabled(true);
}
WebView webView = mAgentWeb.getWebCreator().getWebView();
WebSettings settings = webView.getSettings();
settings.setAllowFileAccess(true); // 允许访问文件
settings.setAllowFileAccessFromFileURLs(true); // 允许 file:// 下的跨文件访问
settings.setAllowUniversalAccessFromFileURLs(true); // 允许所有 file:// 下的跨文件访问
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) {
WebView.setWebContentsDebuggingEnabled(true);
}
}
@Override
public boolean onKeyDown(int keyCode, KeyEvent event) {
if (mAgentWeb.handleKeyEvent(keyCode, event)) {
return true;
}
return super.onKeyDown(keyCode, event);
}
@Override
protected void onDestroy() {
super.onDestroy();
if (mAgentWeb != null) {
mAgentWeb.getWebLifeCycle().onDestroy();
}
}
}
DuMaActivity xml文件
clike
<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".DuMaActivity">
<LinearLayout
android:id="@+id/web_container"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical" />
<FrameLayout
android:id="@+id/fullscreen_container"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:visibility="gone" />
</androidx.constraintlayout.widget.ConstraintLayout>
运行效果如下

总结
核心代码,继承 WebChromeClient 并重写 onShowCustomView 和 onHideCustomView 方法,以控制视频全屏时的界面切换。
- Manifest 配置是前提:hardwareAccelerated="true" 和 configChanges 这两个属性缺一不可,否则视频可能无法渲染或屏幕旋转导致播放中断
- 核心在于 WebChromeClient 的回调:onShowCustomView 负责接管视频视图并切换到全屏 UI,onHideCustomView 负责恢复
- 妥善管理生命周期:需要在 onBackPressed 中判断并处理全屏退出逻辑,确保用户体验连贯。