Commit 1f825025 authored by 张宏's avatar 张宏

3

parent 8ff902b4
import 'package:flutter/material.dart';
import 'package:flutter/services.dart';
import 'package:flutter_screenutil/flutter_screenutil.dart';
import 'package:laki_icu_app/services/usb_camera_service.dart';
import 'camera_controls.dart';
......@@ -9,6 +10,7 @@ import 'camera_controls.dart';
/// 职责:
/// - 通过 AndroidView 嵌入 Android 原生 USBCameraTextureView 预览画面
/// - 底部控制栏:拍照、录像、刷新按钮
/// - 通过 [UsbCameraService] 与原生层通信
///
/// 涉及页面:首页监护舱页面
class MonitoringScreen extends StatefulWidget {
......@@ -32,6 +34,13 @@ class _MonitoringScreenState extends State<MonitoringScreen> {
bool _cameraReady = false;
@override
void dispose() {
// 退出页面时关闭摄像头
UsbCameraService.closeCamera();
super.dispose();
}
@override
Widget build(BuildContext context) {
return Container(
decoration: BoxDecoration(
......@@ -67,32 +76,20 @@ class _MonitoringScreenState extends State<MonitoringScreen> {
/// 构建 USB 摄像头预览画面(通过 PlatformView)
Widget _buildCameraPreview() {
// AndroidView 需要 Android API 20+,且仅在 Android 平台有效
// 在其他平台或未连接 USB 摄像头时显示占位符
try {
return ClipRRect(
borderRadius: BorderRadius.circular(20.r),
child: SizedBox.expand(
child: _buildAndroidView(),
return ClipRRect(
borderRadius: BorderRadius.circular(20.r),
child: SizedBox.expand(
child: AndroidView(
viewType: 'usb_camera_view',
onPlatformViewCreated: (_) {
setState(() {
_cameraReady = true;
});
},
creationParams: const <String, dynamic>{},
creationParamsCodec: const StandardMessageCodec(),
),
);
} catch (_) {
return const SizedBox.shrink();
}
}
/// 构建 Android 原生 PlatformView
Widget _buildAndroidView() {
// ignore: undefined_platform_specific_widget
return AndroidView(
viewType: 'usb_camera_view',
onPlatformViewCreated: (_) {
setState(() {
_cameraReady = true;
});
},
creationParams: const <String, dynamic>{},
creationParamsCodec: const StandardMessageCodec(),
),
);
}
......@@ -131,30 +128,23 @@ class _MonitoringScreenState extends State<MonitoringScreen> {
/// 拍照
Future<void> _onTakePhoto() async {
// 调用 Service 层拍照
final cameraService = await _getCameraService();
if (cameraService != null) {
final path = await cameraService.takePhoto();
if (path != null && mounted) {
_showSnackBar('拍照成功: $path');
}
final path = await UsbCameraService.takePhoto();
if (path != null && mounted) {
_showSnackBar('拍照成功: $path');
}
widget.onSnapshot?.call();
}
/// 切换录像状态
Future<void> _onToggleRecord() async {
final cameraService = await _getCameraService();
if (cameraService == null) return;
if (_isRecording) {
final path = await cameraService.stopRecord();
final path = await UsbCameraService.stopRecord();
if (path != null && mounted) {
_showSnackBar('录像已保存: $path');
}
setState(() => _isRecording = false);
} else {
final success = await cameraService.startRecord();
final success = await UsbCameraService.startRecord();
if (success) {
setState(() => _isRecording = true);
if (mounted) _showSnackBar('开始录像');
......@@ -163,18 +153,6 @@ class _MonitoringScreenState extends State<MonitoringScreen> {
widget.onRecord?.call();
}
/// 获取摄像头服务实例
Future<dynamic> _getCameraService() async {
// 延迟导入,避免在非 Android 平台导入时出现问题
try {
// 动态调用 UsbCameraService
// ignore: depend_on_referenced_packages
return _UsbCameraServiceProxy();
} catch (_) {
return null;
}
}
void _showSnackBar(String message) {
ScaffoldMessenger.of(context).showSnackBar(
SnackBar(
......@@ -189,41 +167,3 @@ class _MonitoringScreenState extends State<MonitoringScreen> {
);
}
}
/// USB 摄像头服务代理 —— 避免硬依赖导致非 Android 平台编译错误
class _UsbCameraServiceProxy {
Future<String?> takePhoto({String? path}) async {
// 通过 MethodChannel 直接调用(与 UsbCameraService 使用同一个 channel)
const channel = MethodChannel('usb_camera');
try {
final result = await channel.invokeMethod('takePhoto', {
if (path != null) 'path': path,
});
return result as String?;
} catch (_) {
return null;
}
}
Future<bool> startRecord({String? path}) async {
const channel = MethodChannel('usb_camera');
try {
final result = await channel.invokeMethod('startRecord', {
if (path != null) 'path': path,
});
return result == true;
} catch (_) {
return false;
}
}
Future<String?> stopRecord() async {
const channel = MethodChannel('usb_camera');
try {
final result = await channel.invokeMethod('stopRecord');
return result as String?;
} catch (_) {
return null;
}
}
}
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment