Android手把手编写儿童手机远程监控App之agentweb如何实现全屏

概述

上节完成嘟妈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 中判断并处理全屏退出逻辑,确保用户体验连贯。
相关推荐
星栈1 小时前
10 分钟跑起第一个 Dioxus 应用:`dx` CLI、`rsx!` 和热更新好不好用
前端·rust·前端框架
奋斗吧程序媛1 小时前
补充一个小知识点:有关@click.native
前端·vue.js
触底反弹1 小时前
🚀 手把手用 HTML5 Canvas 从零打造飞机大战游戏,代码全开源!
前端·javascript·canvas
DJ斯特拉1 小时前
axios快速使用
开发语言·前端·javascript
还有多久拿退休金1 小时前
Ant Design Tree 搜索定位避坑指南:虚拟滚动下如何实现高亮与精准定位
前端·react.js
小月土星2 小时前
CSS 3D 从入门到炫技:手把手教你写一个旋转立方体
前端·css
Hilaku2 小时前
AI 写代码越快,为什么 Code Review 越不能省?
前端·javascript·程序员
sugar__salt3 小时前
从网页小游戏到数据可视化:掌握 HTML5 Canvas 核心能力
前端·信息可视化·html5
北极星日淘3 小时前
前端 i18n 中日双语交互 + 翻译客服接口联动方案|日系海淘平台中文友好化开发实战
前端·交互