
鸿蒙跨端智能家庭安防系统开发指南 原创
鸿蒙跨端智能家庭安防系统开发指南
一、系统架构设计
基于HarmonyOS的AI能力和分布式技术,构建智能家庭安防系统:
视频采集层:通过摄像头实时监控
行为分析层:使用AI模型检测异常行为
报警处理层:触发报警并通知用户
跨端同步层:多设备间同步监控状态和报警信息
!https://example.com/harmony-security-system-arch.png
二、核心代码实现
安防监控服务
// SecurityService.ets
import ai from ‘@ohos.ai’;
import camera from ‘@ohos.multimedia.camera’;
import distributedData from ‘@ohos.distributedData’;
import { SecurityEvent, AlertLevel } from ‘./SecurityTypes’;
class SecurityService {
private static instance: SecurityService = null;
private modelManager: ai.ModelManager;
private dataManager: distributedData.DataManager;
private alertListeners: AlertListener[] = [];
private currentAlerts: SecurityEvent[] = [];
private constructor() {
this.initModelManager();
this.initDataManager();
public static getInstance(): SecurityService {
if (!SecurityService.instance) {
SecurityService.instance = new SecurityService();
return SecurityService.instance;
private initModelManager(): void {
try {
this.modelManager = ai.createModelManager(getContext());
// 加载行为识别模型
this.modelManager.loadModel({
modelName: 'behavior_detection',
modelPath: 'resources/rawfile/behavior_detection.model',
callback: (err, data) => {
if (err) {
console.error('加载行为模型失败:', JSON.stringify(err));
}
});
// 加载人脸识别模型
this.modelManager.loadModel({
modelName: 'face_recognition',
modelPath: 'resources/rawfile/face_recognition.model',
callback: (err, data) => {
if (err) {
console.error('加载人脸模型失败:', JSON.stringify(err));
}
});
catch (err) {
console.error('初始化模型管理器失败:', JSON.stringify(err));
}
private initDataManager(): void {
this.dataManager = distributedData.createDataManager({
bundleName: ‘com.example.security’,
area: distributedData.Area.GLOBAL,
isEncrypted: true
});
this.dataManager.registerDataListener('security_alert_sync', (data) => {
this.handleSyncData(data);
});
public async requestPermissions(): Promise<boolean> {
try {
const permissions = [
'ohos.permission.USE_AI',
'ohos.permission.CAMERA',
'ohos.permission.DISTRIBUTED_DATASYNC',
'ohos.permission.NOTIFICATION'
];
const result = await abilityAccessCtrl.requestPermissionsFromUser(
getContext(),
permissions
);
return result.grantedPermissions.length === permissions.length;
catch (err) {
console.error('请求权限失败:', JSON.stringify(err));
return false;
}
public async startMonitoring(): Promise<void> {
try {
await cameraService.startPreview();
// 开始分析视频流
cameraService.setFrameCallback((frame) => {
this.analyzeFrame(frame);
});
catch (err) {
console.error('启动监控失败:', JSON.stringify(err));
throw err;
}
public async stopMonitoring(): Promise<void> {
try {
await cameraService.stopPreview();
cameraService.setFrameCallback(null);
catch (err) {
console.error('停止监控失败:', JSON.stringify(err));
throw err;
}
private async analyzeFrame(frame: ArrayBuffer): Promise<void> {
try {
const input = {
data: frame,
width: 224,
height: 224,
format: ‘RGB’
};
// 检测异常行为
const behaviorOutput = await this.modelManager.runModel({
modelName: 'behavior_detection',
input: input
});
// 识别已知人脸
const faceOutput = await this.modelManager.runModel({
modelName: 'face_recognition',
input: input
});
// 检查是否有异常行为
if (behaviorOutput.result.abnormal) {
const event: SecurityEvent = {
id: Date.now().toString(),
type: behaviorOutput.result.type,
confidence: behaviorOutput.result.confidence,
timestamp: Date.now(),
frame: frame,
knownFace: faceOutput.result.known,
alertLevel: this.determineAlertLevel(
behaviorOutput.result.type,
faceOutput.result.known
)
};
this.handleSecurityEvent(event);
} catch (err) {
console.error('分析视频帧失败:', JSON.stringify(err));
}
private determineAlertLevel(eventType: string, isKnownFace: boolean): AlertLevel {
const dangerousEvents = [‘intrusion’, ‘violence’, ‘weapon’];
const warningEvents = [‘loitering’, ‘unusual_movement’];
if (dangerousEvents.includes(eventType)) {
return isKnownFace ? 'warning' : 'critical';
else if (warningEvents.includes(eventType)) {
return isKnownFace ? 'info' : 'warning';
return ‘info’;
private handleSecurityEvent(event: SecurityEvent): void {
// 添加到当前警报列表
this.currentAlerts = [...this.currentAlerts, event];
// 触发警报
this.triggerAlert(event);
// 同步警报信息
this.syncAlert(event);
private triggerAlert(event: SecurityEvent): void {
// 发送本地通知
notification.publish({
id: parseInt(event.id),
content: {
title: this.getAlertTitle(event.type),
text: this.getAlertText(event.type),
additionalText: 置信度: ${(event.confidence * 100).toFixed(1)}%,
tapAction: {
bundleName: 'com.example.security',
abilityName: 'MainAbility'
}
});
// 通知监听器
this.notifyAlertListeners(event);
private getAlertTitle(eventType: string): string {
const titles = {
'intrusion': '入侵检测',
'violence': '暴力行为',
'weapon': '武器检测',
'loitering': '可疑徘徊',
'unusual_movement': '异常行为'
};
return titles[eventType] || '安全警报';
private getAlertText(eventType: string): string {
const texts = {
'intrusion': '检测到可能的入侵行为',
'violence': '检测到可能的暴力行为',
'weapon': '检测到可能的武器',
'loitering': '检测到可疑人员在徘徊',
'unusual_movement': '检测到异常行为'
};
return texts[eventType] || '检测到安全事件';
private syncAlert(event: SecurityEvent): void {
this.dataManager.syncData('security_alert_sync', {
type: 'security_alert',
data: event,
timestamp: Date.now()
});
private handleSyncData(data: any): void {
if (!data || data.type !== 'security_alert') return;
this.currentAlerts = [...this.currentAlerts, data.data];
this.notifyAlertListeners(data.data);
private notifyAlertListeners(event: SecurityEvent): void {
this.alertListeners.forEach(listener => {
listener.onAlertTriggered?.(event);
});
public async acknowledgeAlert(alertId: string): Promise<void> {
this.currentAlerts = this.currentAlerts.filter(alert => alert.id !== alertId);
this.dataManager.syncData('alert_ack', {
type: 'alert_acknowledged',
data: { alertId },
timestamp: Date.now()
});
public addAlertListener(listener: AlertListener): void {
if (!this.alertListeners.includes(listener)) {
this.alertListeners.push(listener);
}
public removeAlertListener(listener: AlertListener): void {
this.alertListeners = this.alertListeners.filter(l => l !== listener);
}
interface AlertListener {
onAlertTriggered?(event: SecurityEvent): void;
export const securityService = SecurityService.getInstance();
相机服务封装
// CameraService.ets
import camera from ‘@ohos.multimedia.camera’;
import image from ‘@ohos.multimedia.image’;
class CameraService {
private static instance: CameraService = null;
private cameraManager: camera.CameraManager;
private cameraInput: camera.CameraInput;
private previewOutput: camera.PreviewOutput;
private captureSession: camera.CaptureSession;
private frameCallback: (frame: ArrayBuffer) => void = null;
private constructor() {
this.initCamera();
public static getInstance(): CameraService {
if (!CameraService.instance) {
CameraService.instance = new CameraService();
return CameraService.instance;
private initCamera(): void {
try {
const context = getContext() as common.Context;
this.cameraManager = camera.getCameraManager(context);
// 获取摄像头
const cameras = this.cameraManager.getSupportedCameras();
const cameraDevice = cameras.find(cam => cam.position === camera.CameraPosition.BACK);
if (!cameraDevice) {
throw new Error('未找到摄像头');
// 创建相机输入
this.cameraInput = this.cameraManager.createCameraInput(cameraDevice);
// 创建预览输出
const previewProfile = this.cameraManager.getSupportedOutputCapability(cameraDevice)
.previewProfiles[0];
this.previewOutput = this.cameraManager.createPreviewOutput(previewProfile);
// 创建捕获会话
this.captureSession = this.cameraManager.createCaptureSession();
this.captureSession.beginConfig();
this.captureSession.addInput(this.cameraInput);
this.captureSession.addOutput(this.previewOutput);
this.captureSession.commitConfig();
catch (err) {
console.error('初始化相机失败:', JSON.stringify(err));
}
public async startPreview(surfaceId?: string): Promise<void> {
try {
if (surfaceId) {
await this.previewOutput.start(surfaceId);
await this.captureSession.start();
// 开始捕获帧
this.startFrameCapture();
catch (err) {
console.error('启动预览失败:', JSON.stringify(err));
throw err;
}
public async stopPreview(): Promise<void> {
try {
await this.previewOutput.stop();
await this.captureSession.stop();
// 停止捕获帧
this.stopFrameCapture();
catch (err) {
console.error('停止预览失败:', JSON.stringify(err));
throw err;
}
public setFrameCallback(callback: (frame: ArrayBuffer) => void): void {
this.frameCallback = callback;
private startFrameCapture(): void {
// 模拟帧捕获(实际应用中应使用真实相机帧)
this.frameInterval = setInterval(async () => {
if (this.frameCallback) {
try {
const frame = await this.captureFrame();
this.frameCallback(frame);
catch (err) {
console.error('捕获帧失败:', JSON.stringify(err));
}
}, 1000 / 30); // 30fps
private stopFrameCapture(): void {
if (this.frameInterval) {
clearInterval(this.frameInterval);
this.frameInterval = null;
}
private async captureFrame(): Promise<ArrayBuffer> {
// 模拟捕获帧(实际应用中应从相机获取真实帧)
return new Promise((resolve) => {
setTimeout(() => {
resolve(new ArrayBuffer(224 224 3)); // RGB图像
}, 10);
});
public release(): void {
this.stopFrameCapture();
this.captureSession.stop();
this.cameraInput.release();
this.previewOutput.release();
this.captureSession.release();
}
export const cameraService = CameraService.getInstance();
主界面实现
// MainScreen.ets
import { securityService } from ‘./SecurityService’;
import { cameraService } from ‘./CameraService’;
import { SecurityEvent, AlertLevel } from ‘./SecurityTypes’;
@Component
export struct MainScreen {
@State hasPermission: boolean = false;
@State isMonitoring: boolean = false;
@State currentAlerts: SecurityEvent[] = [];
@State previewSurfaceId: string = ‘’;
@State showAlertDetails: boolean = false;
@State selectedAlert: SecurityEvent | null = null;
build() {
Column() {
// 标题栏
Row() {
Text(‘家庭安防’)
.fontSize(24)
.fontWeight(FontWeight.Bold)
.layoutWeight(1)
Button(this.hasPermission ? (this.isMonitoring ? '停止' : '开始') : '授权')
.width(100)
.onClick(() => {
if (this.hasPermission) {
this.toggleMonitoring();
else {
this.requestPermissions();
})
.padding(10)
.width('100%')
// 监控预览区域
Stack() {
if (this.hasPermission) {
// 相机预览Surface
Surface({
id: this.previewSurfaceId,
type: SurfaceType.SURFACE_TEXTURE,
width: '100%',
height: 300
})
.onAppear(() => {
this.previewSurfaceId = preview_${Date.now()};
})
// 监控状态指示器
Column() {
if (this.isMonitoring) {
Row() {
Circle()
.width(10)
.height(10)
.fillColor('#FF5252')
.margin({ right: 5 })
Text('监控中')
.fontSize(16)
.fontColor('#FF5252')
.padding(5)
.backgroundColor('rgba(0,0,0,0.5)')
.borderRadius(8)
}
.position({ x: '50%', y: 10 })
.margin({ left: -25 })
else {
Column() {
Text('需要权限')
.fontSize(18)
.margin({ bottom: 10 })
Text('请点击右上角"授权"按钮,允许应用访问相机和AI功能')
.fontSize(16)
.fontColor('#666666')
.padding(20)
.width('90%')
.backgroundColor('#F5F5F5')
.borderRadius(8)
.margin({ top: 50 })
}
.width('100%')
.height(300)
.margin({ bottom: 20 })
// 警报列表
Column() {
Text('安全警报')
.fontSize(18)
.fontWeight(FontWeight.Bold)
.margin({ bottom: 10 })
if (this.currentAlerts.length === 0) {
Column() {
Text('暂无警报')
.fontSize(16)
.margin({ bottom: 5 })
Text('系统检测到异常行为时会显示在这里')
.fontSize(14)
.fontColor('#666666')
.padding(20)
.width('90%')
.backgroundColor('#F5F5F5')
.borderRadius(8)
else {
List({ space: 10 }) {
ForEach(this.currentAlerts, (alert) => {
ListItem() {
Column() {
Row() {
Text(this.getAlertTitle(alert.type))
.fontSize(16)
.fontWeight(FontWeight.Bold)
.layoutWeight(1)
Text(this.formatTime(alert.timestamp))
.fontSize(14)
.fontColor('#666666')
.margin({ bottom: 5 })
Row() {
Text(this.getAlertLevelText(alert.alertLevel))
.fontSize(14)
.fontColor(this.getAlertLevelColor(alert.alertLevel))
Text(置信度: ${(alert.confidence * 100).toFixed(1)}%)
.fontSize(14)
.fontColor('#666666')
.margin({ left: 20 })
}
.padding(10)
.width('100%')
.backgroundColor('#FFFFFF')
.borderRadius(8)
.onClick(() => {
this.selectedAlert = alert;
this.showAlertDetails = true;
})
})
.height(200)
}
.width('100%')
.width(‘100%’)
.height('100%')
.padding(20)
// 警报详情对话框
if (this.showAlertDetails && this.selectedAlert) {
DialogComponent({
title: this.getAlertTitle(this.selectedAlert.type),
content: this.buildAlertDetailContent(),
confirm: {
value: '确认',
action: () => {
this.acknowledgeAlert(this.selectedAlert!.id);
this.showAlertDetails = false;
},
cancel: {
value: '取消',
action: () => {
this.showAlertDetails = false;
}
})
}
private buildAlertDetailContent(): void {
Column() {
Image(this.selectedAlert!.frame)
.width(‘100%’)
.height(200)
.objectFit(ImageFit.Contain)
.margin({ bottom: 15 })
Row() {
Text('警报级别:')
.fontSize(16)
.margin({ right: 10 })
Text(this.getAlertLevelText(this.selectedAlert!.alertLevel))
.fontSize(16)
.fontColor(this.getAlertLevelColor(this.selectedAlert!.alertLevel))
.margin({ bottom: 10 })
Row() {
Text('置信度:')
.fontSize(16)
.margin({ right: 10 })
Text(${(this.selectedAlert!.confidence * 100).toFixed(1)}%)
.fontSize(16)
.margin({ bottom: 10 })
Row() {
Text('时间:')
.fontSize(16)
.margin({ right: 10 })
Text(this.formatDateTime(this.selectedAlert!.timestamp))
.fontSize(16)
.margin({ bottom: 10 })
if (this.selectedAlert!.knownFace) {
Text('识别为已知人员')
.fontSize(16)
.fontColor('#4CAF50')
else {
Text('未识别到已知人员')
.fontSize(16)
.fontColor('#F44336')
}
.padding(20)
private getAlertTitle(eventType: string): string {
const titles = {
'intrusion': '入侵检测',
'violence': '暴力行为',
'weapon': '武器检测',
'loitering': '可疑徘徊',
'unusual_movement': '异常行为'
};
return titles[eventType] || '安全警报';
private getAlertLevelText(level: AlertLevel): string {
const texts = {
'critical': '严重',
'warning': '警告',
'info': '信息'
};
return texts[level] || '信息';
private getAlertLevelColor(level: AlertLevel): string {
const colors = {
'critical': '#F44336',
'warning': '#FF9800',
'info': '#2196F3'
};
return colors[level] || '#2196F3';
private formatTime(timestamp: number): string {
const date = new Date(timestamp);
return {date.getHours()}:{date.getMinutes().toString().padStart(2, '0')};
private formatDateTime(timestamp: number): string {
const date = new Date(timestamp);
return {date.getFullYear()}-{(date.getMonth() + 1).toString().padStart(2, '0')}-{date.getDate().toString().padStart(2, '0')} {date.getHours().toString().padStart(2, '0')}:${date.getMinutes().toString().padStart(2, '0')};
aboutToAppear() {
this.checkPermissions();
securityService.addAlertListener({
onAlertTriggered: (event) => {
this.handleAlertTriggered(event);
});
aboutToDisappear() {
securityService.removeAlertListener({
onAlertTriggered: (event) => {
this.handleAlertTriggered(event);
});
this.stopMonitoring();
private async checkPermissions(): Promise<void> {
try {
const permissions = [
'ohos.permission.USE_AI',
'ohos.permission.CAMERA',
'ohos.permission.DISTRIBUTED_DATASYNC',
'ohos.permission.NOTIFICATION'
];
const result = await abilityAccessCtrl.verifyPermissions(
getContext(),
permissions
);
this.hasPermission = result.every(perm => perm.granted);
catch (err) {
console.error('检查权限失败:', JSON.stringify(err));
this.hasPermission = false;
}
private async requestPermissions(): Promise<void> {
this.hasPermission = await securityService.requestPermissions();
if (!this.hasPermission) {
prompt.showToast({ message: '授权失败,无法使用安防功能' });
}
private async toggleMonitoring(): Promise<void> {
if (this.isMonitoring) {
await this.stopMonitoring();
else {
await this.startMonitoring();
}
private async startMonitoring(): Promise<void> {
try {
await cameraService.startPreview(this.previewSurfaceId);
await securityService.startMonitoring();
this.isMonitoring = true;
catch (err) {
console.error('启动监控失败:', JSON.stringify(err));
prompt.showToast({ message: '启动监控失败,请重试' });
}
private async stopMonitoring(): Promise<void> {
try {
await securityService.stopMonitoring();
await cameraService.stopPreview();
this.isMonitoring = false;
catch (err) {
console.error('停止监控失败:', JSON.stringify(err));
prompt.showToast({ message: '停止监控失败,请重试' });
}
private handleAlertTriggered(event: SecurityEvent): void {
this.currentAlerts = [event, …this.currentAlerts];
private async acknowledgeAlert(alertId: string): Promise<void> {
await securityService.acknowledgeAlert(alertId);
this.currentAlerts = this.currentAlerts.filter(alert => alert.id !== alertId);
}
类型定义
// SecurityTypes.ets
export type AlertLevel = ‘critical’ ‘warning’
‘info’;
export interface SecurityEvent {
id: string;
type: string;
confidence: number;
timestamp: number;
frame: ArrayBuffer;
knownFace: boolean;
alertLevel: AlertLevel;
三、项目配置与权限
权限配置
// module.json5
“module”: {
"requestPermissions": [
“name”: “ohos.permission.USE_AI”,
"reason": "使用AI模型检测异常行为"
},
“name”: “ohos.permission.CAMERA”,
"reason": "监控家庭环境"
},
“name”: “ohos.permission.DISTRIBUTED_DATASYNC”,
"reason": "同步警报信息"
},
“name”: “ohos.permission.NOTIFICATION”,
"reason": "发送安全警报"
],
"abilities": [
“name”: “MainAbility”,
"type": "page",
"visible": true
},
“name”: “CameraAbility”,
"type": "service",
"backgroundModes": ["camera"]
]
}
四、总结与扩展
本家庭安防系统实现了以下核心功能:
实时监控:持续监控家庭环境
智能分析:检测入侵、暴力等异常行为
即时报警:发现异常立即通知用户
多设备协同:多终端同步接收警报
历史记录:保存所有安全事件记录
扩展方向:
人脸识别:识别家庭成员与陌生人
声音检测:检测异常声音(如玻璃破碎)
智能门锁联动:与智能门锁系统联动
区域监控:重点监控特定区域
报警等级自定义:根据需求调整报警等级
云存储:将监控录像备份到云端
通过HarmonyOS的分布式技术,我们构建了一个智能化的家庭安防系统,能够实时监测家庭安全状况并在发现异常时及时报警,同时支持多设备间的协同工作,为家庭安全提供全方位保障。
