该应用基于银河E5定制开发,理论上其它龙鹰一号无高阶智驾车型,也可通用,其它车型不兼容。支持同时从最多 4 个摄像头进行视频录制与拍照,支持远程发送录制、拍照指令进行远程监看。
- 🎨 仿FlymeAuto官方UI - 仿照FlymeAuto官方界面设计,美观且符合车机使用习惯
- 🎥 视频录制与照片抓拍 - 支持多摄像头同步录制和实时拍照功能
- 👁️ 千里眼远程监看 - 通过钉钉机器人实现远程查看摄像头画面和远程控制
- 🚗 不受车速限制 - 随时可开启录制功能,突破官方30km/h车速限制
- 🔄 自启动与后台保活 - 开机自启动 + 前台服务 + WorkManager + 无障碍服务多重保活机制
- 💾 视频本地存储 - 录制内容自动保存至本地DCIM目录,方便管理和导出
- 开发语言: Java
- 最低版本: Android 9.0 (API 28)
- 目标版本: Android 14+ (API 36)
- 摄像头API: Camera2 API
- 构建工具: Gradle 8.x (Kotlin DSL)
- UI组件: Material Design Components
- 图片加载: Glide 4.16.0
- 网络库: OkHttp 4.12.0
- 钉钉集成: DingTalk Stream SDK 1.3.12
- 后台任务: WorkManager 2.9.0
- JDK: 17 或更高版本(推荐 JDK 25)
- Android Studio: Hedgehog (2023.1.1) 或更高版本
- Gradle: 8.0+
- 测试设备: Android 9.0+ 的真机(建议具有多个摄像头)
git clone https://github.com/your-username/EVCam.git
cd EVCam项目提供了便捷的批处理脚本用于配置 JDK 25:
# 使用提供的脚本构建(自动设置 JAVA_HOME)
build-with-jdk25.bat或者手动配置环境变量:
set JAVA_HOME=C:\Program Files\Java\jdk-25.0.2
set PATH=%JAVA_HOME%\bin;%PATH%如需使用远程控制功能,需要配置钉钉机器人:
- 创建钉钉企业内部应用(Stream模式)
- 获取
Client ID(原 AppKey/SuiteKey)和Client Secret(原 AppSecret/SuiteSecret) - 创建
app/src/main/java/com/kooo/evcam/dingtalk/DingTalkConfig.java:
package com.kooo.evcam.dingtalk;
public class DingTalkConfig {
// 钉钉应用凭证(新版参数)
public static final String CLIENT_ID = "你的Client ID";
public static final String CLIENT_SECRET = "你的Client Secret";
// 上传模式配置
public static final boolean ENABLE_UPLOAD = true; // 是否启用上传
}注意:
- 钉钉已将旧版的 AppKey/AppSecret 更名为 Client ID/Client Secret
- 如果不需要钉钉功能,可以在
MainActivity.java中注释掉相关代码
# Windows
gradlew.bat assembleDebug
# Linux/macOS
./gradlew assembleDebug输出位置: app\build\outputs\apk\debug\app-debug.apk
项目已配置 AOSP 公共测试签名,可直接构建:
# Windows
gradlew.bat assembleRelease
# Linux/macOS
./gradlew assembleRelease输出位置: app\build\outputs\apk\release\app-release.apk
# 安装 Debug 版本
gradlew.bat installDebug
# 或使用 adb 手动安装
adb install app\build\outputs\apk\debug\app-debug.apk-
授予权限 - 请务必使用“应用管家”或其它权限管理软件,授予EVCam所有需要的权限
-
摄像头预览 - 权限授予后,应用会自动初始化摄像头并显示预览
-
检查日志 - 点击底部"显示日志"按钮,查看摄像头初始化状态
- 点击 "开始录制" 按钮
- 所有摄像头同步开始录制
- 录制过程中可以拍照(点击"拍照"按钮)
- 点击 "停止录制" 结束录制
视频存储位置: /sdcard/DCIM/EVCam_Video/
文件命名格式: yyyyMMdd_HHmmss_{position}.mp4(例如:20260125_153045_front.mp4)
- 在预览或录制状态下,点击 "拍照" 按钮
- 照片同时从所有活动摄像头抓拍
照片存储位置: /sdcard/DCIM/EVCam_Photo/
文件命名格式: yyyyMMdd_HHmmss_{position}.jpg
应用内置了回放和相册功能:
- 点击左上角菜单图标(☰)
- 选择 "视频回放" 或 "照片回放"
- 点击缩略图可全屏查看/播放
配置钉钉机器人后,可通过钉钉发送命令:
拍照- 远程拍照并上传录制 <时长>- 开始录制指定时长(秒)状态- 查询应用运行状态预览- 获取当前摄像头预览截图
EVCam/
├── MainActivity.java # 主界面,UI控制器
├── camera/ # 摄像头管理模块
│ ├── MultiCameraManager.java # 多摄像头编排器
│ ├── SingleCamera.java # 单摄像头封装(Camera2 API)
│ ├── VideoRecorder.java # 视频录制器(MediaRecorder)
│ ├── CameraCallback.java # 摄像头事件回调接口
│ └── RecordCallback.java # 录制事件回调接口
├── dingtalk/ # 钉钉集成模块
│ ├── DingTalkStreamManager.java # Stream客户端管理
│ ├── DingTalkCommandReceiver.java # 命令解析与执行
│ ├── PhotoUploadService.java # 照片上传服务
│ └── VideoUploadService.java # 视频上传服务
├── KeepAliveManager.java # 保活管理器
├── CameraForegroundService.java # 前台服务
├── PlaybackFragment.java # 视频回放界面
└── PhotoPlaybackFragment.java # 照片浏览界面
1. 权限检查 → 请求相机、音频、存储权限
2. TextureView 就绪 → 等待4个 TextureView 完成初始化
3. 摄像头探测 → 查询 CameraManager 获取可用摄像头
4. 自适应配置 → 根据摄像头数量分配:
- 4+ 摄像头: 独立使用4个摄像头
- 2-3 摄像头: 复用摄像头到多个 TextureView
- 1 摄像头: 所有 TextureView 显示同一摄像头
5. 顺序打开 → 遵循系统限制顺序打开摄像头
6. 预览启动 → 建立 CaptureSession 开始预览
用户点击"开始录制"
↓
MultiCameraManager 为每个摄像头创建 VideoRecorder
↓
VideoRecorder.prepare() 配置 MediaRecorder 并返回 Surface
↓
SingleCamera 将录制 Surface 添加到 CaptureSession
↓
所有录制器同步启动
↓
用户点击"停止录制"
↓
所有录制器停止 → 清除 Surface → 重建预览 Session
- 主线程: UI 更新、按钮响应、TextureView 回调
- Camera HandlerThread: 每个 SingleCamera 独立的后台线程处理 Camera2 API 调用
- Logcat 读取线程: 独立线程读取系统日志
- 钉钉 Stream 线程: WebSocket 连接和消息处理
- WorkManager 后台任务: 定时保活任务
# 查看摄像头相关日志(详细)
adb logcat -v time -s CameraService:V Camera3-Device:V Camera3-Stream:V Camera3-Output:V camera3:V MainActivity:D MultiCameraManager:D SingleCamera:D VideoRecorder:D
# 查看应用日志
adb logcat -v time | findstr "com.kooo.evcam"
# 清空日志缓冲区
adb logcat -c# 列出连接的设备
adb devices
# 卸载应用
adb uninstall com.kooo.evcam
# 手动授予权限
adb shell pm grant com.kooo.evcam android.permission.CAMERA
adb shell pm grant com.kooo.evcam android.permission.RECORD_AUDIO
adb shell pm grant com.kooo.evcam android.permission.WRITE_EXTERNAL_STORAGE# 查看视频列表
adb shell ls -la /sdcard/DCIM/EVCam_Video/
# 拉取视频到本地
adb pull /sdcard/DCIM/EVCam_Video/ ./recordings/
# 查看照片列表
adb shell ls -la /sdcard/DCIM/EVCam_Photo/
# 拉取照片到本地
adb pull /sdcard/DCIM/EVCam_Photo/ ./photos/# 单元测试
gradlew.bat test
# 设备测试(需要连接设备)
gradlew.bat connectedAndroidTest可能原因:
- TextureView 未就绪就尝试打开摄像头
- 权限未授予(检查 logcat 中的 "Missing permission" 错误)
- 设备无可用摄像头
- 超出系统同时打开摄像头数量限制
解决方案:
- 确保 TextureView 已触发
onSurfaceTextureAvailable回调 - 在设置中手动授予权限,或重新安装应用
- 使用
adb shell dumpsys media.camera查看设备摄像头信息 - 降低
maxOpenCameras配置(默认为4)
可能原因:
- DCIM/EVCam_Video 目录不可写
- 摄像头未打开或预览未启动
- MediaRecorder 配置与摄像头能力不匹配
- 存储空间不足
解决方案:
- 检查存储权限是否授予
- 确保摄像头预览正常后再开始录制
- 查看 logcat 中的 MediaRecorder 错误信息
- 清理设备存储空间
可能原因:
- TextureView 尺寸为零
- SurfaceTexture 不可用
- 摄像头预览分辨率不支持
- Camera2 API 报错
解决方案:
- 检查布局文件中 TextureView 的宽高设置
- 确认
onSurfaceTextureAvailable回调已触发 - 查看日志中的分辨率协商过程
- 使用
adb logcat -s CameraService:V查看底层错误
解决方案:
- 启用前台服务(应用会显示通知)
- 在系统设置中关闭电池优化
- 允许应用自启动
- 启用无障碍服务(设置 → 无障碍 → EVCam保活服务)
可能原因:
- AppKey/AppSecret 配置错误
- 网络连接问题
- Stream 连接未建立
解决方案:
- 检查
DingTalkConfig.java配置 - 确保设备联网
- 查看日志中的 WebSocket 连接状态
- 重启应用重新建立连接
- 添加视频清晰度选择(高清/标清/流畅)
- 实现时间戳水印功能
- 车外扬声器喊话功能
- 更多远程车控功能(空调、车窗、车门等)
- 根据指定车辆状态自动启动录制
- 手动上传功能(选择性上传录制内容)
- 更多个性化设置项(录制时长、存储路径等)
欢迎贡献代码、报告问题或提出新功能建议!
- Fork 本仓库
- 创建特性分支 (
git checkout -b feature/AmazingFeature) - 提交更改 (
git commit -m 'Add some AmazingFeature') - 推送到分支 (
git push origin feature/AmazingFeature) - 提交 Pull Request
本项目采用 双重许可 模式:
- 📜 CC BY-NC-SA 4.0(知识共享署名-非商业性使用-相同方式共享 4.0)
- ✅ 允许个人学习、研究、非商业使用
- ✅ 允许修改和分发(需保持相同许可)
- ❌ 禁止任何商业用途
- 💼 如需商业授权,请联系作者获取商业许可证
详细条款请参阅 LICENSE 文件。
本项目100% Vibe Coding,已耗费数百元AI Agent订阅成本。如果这个项目对你有帮助,欢迎打赏支持!
- wechat: greenteacher46 (请备注来意)

