鸿蒙智能饮水提醒应用开发指南 原创

进修的泡芙
发布于 2025-6-22 17:05
浏览
0收藏

鸿蒙智能饮水提醒应用开发指南

一、系统架构设计

基于HarmonyOS的AI能力和分布式技术,我们设计了一套智能饮水提醒系统,主要功能包括:
人脸检测:通过摄像头检测用户面部特征

脱水分析:AI分析面部特征判断脱水状态

饮水记录:记录用户饮水时间和量

多设备同步:跨设备同步健康数据和提醒

健康建议:根据脱水程度提供饮水建议

!https://example.com/harmony-hydration-arch.png

二、核心代码实现
人脸检测服务

// FaceDetectionService.ets
import camera from ‘@ohos.multimedia.camera’;
import image from ‘@ohos.multimedia.image’;
import face from ‘@ohos.ai.face’;

class FaceDetectionService {
private static instance: FaceDetectionService;
private cameraManager: camera.CameraManager;
private faceDetector: face.FaceDetector;
private cameraInput: camera.CameraInput | null = null;
private previewOutput: camera.PreviewOutput | null = null;

private constructor() {
this.cameraManager = camera.getCameraManager();
this.faceDetector = face.createFaceDetector();
public static getInstance(): FaceDetectionService {

if (!FaceDetectionService.instance) {
  FaceDetectionService.instance = new FaceDetectionService();

return FaceDetectionService.instance;

public async initCamera(previewSurfaceId: string): Promise<void> {

const cameras = this.cameraManager.getSupportedCameras();
if (cameras.length === 0) {
  throw new Error('No camera available');

this.cameraInput = this.cameraManager.createCameraInput(cameras[0]);

await this.cameraInput.open();

const previewProfile = this.cameraManager.getSupportedOutputCapability(
  cameras[0],
  camera.ProfileMode.PROFILE_MODE_DEFAULT
).previewProfiles[0];

this.previewOutput = this.cameraManager.createPreviewOutput(
  previewProfile,
  previewSurfaceId
);

public async detectFace(image: image.Image): Promise<FaceDetectionResult> {

const detectionOptions = {
  featureType: face.FeatureType.FEATURE_TYPE_ALL,
  processMode: face.ProcessMode.PROCESS_MODE_FAST
};

return new Promise((resolve, reject) => {
  this.faceDetector.detect(image, detectionOptions, (err, result) => {
    if (err) {
      reject(err);

else {

      resolve(this.processFaceResult(result));

});

});

private processFaceResult(rawData: any): FaceDetectionResult {

if (!rawData || rawData.faces.length === 0) {
  return { faceDetected: false };

const face = rawData.faces[0];

return {
  faceDetected: true,
  boundingBox: face.boundingBox,
  landmarks: face.landmarks,
  skinTone: face.skinTone,
  skinMoisture: face.skinMoisture,
  darkCircles: face.darkCircles,
  confidence: face.confidence
};

}

export const faceDetectionService = FaceDetectionService.getInstance();

脱水分析服务

// HydrationAnalysisService.ets
import http from ‘@ohos.net.http’;

class HydrationAnalysisService {
private static instance: HydrationAnalysisService;
private httpClient: http.HttpRequest;
private apiKey = ‘YOUR_HYDRATION_API_KEY’;

private constructor() {
this.httpClient = http.createHttp();
public static getInstance(): HydrationAnalysisService {

if (!HydrationAnalysisService.instance) {
  HydrationAnalysisService.instance = new HydrationAnalysisService();

return HydrationAnalysisService.instance;

public async analyzeHydration(faceData: FaceDetectionResult): Promise<HydrationStatus> {

return new Promise((resolve, reject) => {
  this.httpClient.request(
    'https://hydration-api.example.com/analyze',

method: ‘POST’,

      header: { 'Content-Type': 'application/json' },
      extraData: JSON.stringify({
        skin_moisture: faceData.skinMoisture,
        skin_tone: faceData.skinTone,
        dark_circles: faceData.darkCircles,
        api_key: this.apiKey
      })
    },
    (err, data) => {
      if (err) {
        reject(err);

else {

        const result = JSON.parse(data.result);
        resolve(this.processHydrationResult(result));

}

  );
});

private processHydrationResult(rawData: any): HydrationStatus {

return {
  hydrationLevel: rawData.hydration_level || 'normal',
  dehydrationScore: rawData.dehydration_score || 0,
  suggestedWaterIntake: rawData.suggested_water_intake || 200,
  symptoms: rawData.symptoms || [],
  timestamp: Date.now()
};

public calculateDailyRequirement(userProfile: UserProfile): number {

// 基础水需求量计算(毫升)
let baseRequirement = userProfile.weight * 30; // 30ml/kg

// 根据活动量调整
if (userProfile.activityLevel === 'low') {
  baseRequirement *= 0.9;

else if (userProfile.activityLevel === ‘high’) {

  baseRequirement *= 1.2;

// 根据气候调整

if (userProfile.environment === 'hot') {
  baseRequirement *= 1.3;

else if (userProfile.environment === ‘cold’) {

  baseRequirement *= 0.9;

return Math.round(baseRequirement);

}

export const hydrationService = HydrationAnalysisService.getInstance();

多设备同步服务

// HydrationSyncService.ets
import distributedData from ‘@ohos.data.distributedData’;
import deviceManager from ‘@ohos.distributedHardware.deviceManager’;

class HydrationSyncService {
private static instance: HydrationSyncService;
private kvManager: distributedData.KVManager;
private kvStore: distributedData.KVStore;

private constructor() {
this.initKVStore();
private async initKVStore(): Promise<void> {

const config = {
  bundleName: 'com.example.hydrationReminder',
  userInfo: { userId: 'currentUser' }
};

this.kvManager = distributedData.createKVManager(config);
this.kvStore = await this.kvManager.getKVStore('hydration_store', {
  createIfMissing: true
});

this.kvStore.on('dataChange', (data) => {
  this.handleRemoteUpdate(data);
});

public static getInstance(): HydrationSyncService {

if (!HydrationSyncService.instance) {
  HydrationSyncService.instance = new HydrationSyncService();

return HydrationSyncService.instance;

public async syncHydrationRecord(record: HydrationRecord): Promise<void> {

await this.kvStore.put(hydration_${record.id}, JSON.stringify(record));

public async getHydrationRecords(date: string): Promise<HydrationRecord[]> {

const entries = await this.kvStore.getEntries('hydration_');
return Array.from(entries)
  .map(([_, value]) => JSON.parse(value))
  .filter(record => record.date === date);

public async syncUserProfile(profile: UserProfile): Promise<void> {

await this.kvStore.put('user_profile', JSON.stringify(profile));

public async getUserProfile(): Promise<UserProfile | null> {

const value = await this.kvStore.get('user_profile');
return value ? JSON.parse(value) : null;

public async syncHydrationStatus(status: HydrationStatus): Promise<void> {

await this.kvStore.put('hydration_status', JSON.stringify(status));

public async getHydrationStatus(): Promise<HydrationStatus | null> {

const value = await this.kvStore.get('hydration_status');
return value ? JSON.parse(value) : null;

private handleRemoteUpdate(data: distributedData.ChangeInfo): void {

if (data.deviceId === deviceInfo.deviceId) return;

const key = data.key as string;
if (key.startsWith('hydration_')) {
  const record = JSON.parse(data.value);
  EventBus.emit('hydrationRecordUpdated', record);

else if (key === ‘user_profile’) {

  const profile = JSON.parse(data.value);
  EventBus.emit('userProfileUpdated', profile);

else if (key === ‘hydration_status’) {

  const status = JSON.parse(data.value);
  EventBus.emit('hydrationStatusUpdated', status);

}

export const hydrationSyncService = HydrationSyncService.getInstance();

三、主界面实现
人脸检测界面

// FaceDetectionView.ets
@Component
struct FaceDetectionView {
@State previewSurfaceId: string = ‘’;
@State faceResult: FaceDetectionResult | null = null;
@State hydrationStatus: HydrationStatus | null = null;
@State isAnalyzing: boolean = false;

aboutToAppear() {
this.initCamera();
build() {

Stack() {
  // 相机预览
  XComponent({
    id: 'faceCameraPreview',
    type: 'surface',
    libraryname: 'libcamera.so',
    controller: this.previewController
  })
  .onLoad(() => {
    this.previewSurfaceId = this.previewController.getXComponentSurfaceId();
    faceDetectionService.initCamera(this.previewSurfaceId);
  })
  .width('100%')
  .height('100%')
  
  // 人脸检测框
  if (this.faceResult?.faceDetected) {
    Rect()
      .width(this.faceResult.boundingBox.width)
      .height(this.faceResult.boundingBox.height)
      .position({
        x: this.faceResult.boundingBox.x,
        y: this.faceResult.boundingBox.y
      })
      .borderWidth(2)
      .borderColor('#4CAF50')

// 检测按钮

  Button('检测水分状态')
    .onClick(() => this.detectAndAnalyze())
    .position({ x: '50%', y: '90%' })
  
  // 分析状态
  if (this.isAnalyzing) {
    LoadingProgress()
      .position({ x: '50%', y: '50%' })

// 结果显示

  if (this.hydrationStatus) {
    HydrationStatusView({ status: this.hydrationStatus })
      .position({ x: '50%', y: '30%' })

}

private async detectAndAnalyze(): Promise<void> {

this.isAnalyzing = true;
const image = await faceDetectionService.captureFaceImage();
this.faceResult = await faceDetectionService.detectFace(image);

if (this.faceResult.faceDetected) {
  this.hydrationStatus = await hydrationService.analyzeHydration(this.faceResult);
  await hydrationSyncService.syncHydrationStatus(this.hydrationStatus);
  
  // 根据状态决定是否提醒
  if (this.hydrationStatus.hydrationLevel === 'dehydrated') {
    EventBus.emit('hydrationAlert', this.hydrationStatus);

}

this.isAnalyzing = false;

}

@Component
struct HydrationStatusView {
private status: HydrationStatus;

build() {
Column() {
Text(this.getStatusTitle())
.fontSize(20)
.fontColor(this.getStatusColor())

  Text(建议饮水量: ${this.status.suggestedWaterIntake}ml)
    .fontSize(16)
    .margin({ top: 8 })
  
  if (this.status.symptoms.length > 0) {
    Text(症状: ${this.status.symptoms.join(', ')})
      .fontSize(14)
      .margin({ top: 8 })

Button(‘记录饮水’)

    .onClick(() => this.recordWaterIntake())
    .margin({ top: 16 })

.padding(16)

.backgroundColor('#FFFFFF')
.borderRadius(8)

private getStatusTitle(): string {

switch (this.status.hydrationLevel) {
  case 'dehydrated': return '脱水状态!需要立即补水';
  case 'normal': return '水分状态正常';
  case 'hydrated': return '水分充足';
  default: return '未知状态';

}

private getStatusColor(): string {
switch (this.status.hydrationLevel) {
case ‘dehydrated’: return ‘#FF5722’;
case ‘normal’: return ‘#4CAF50’;
case ‘hydrated’: return ‘#2196F3’;
default: return ‘#000000’;
}

private async recordWaterIntake(): Promise<void> {
const record: HydrationRecord = {
id: generateId(),
amount: this.status.suggestedWaterIntake,
timestamp: Date.now(),
status: this.status.hydrationLevel
};

await hydrationSyncService.syncHydrationRecord(record);
EventBus.emit('waterIntakeRecorded', record);

}

function generateId(): string {
return Math.random().toString(36).substring(2) + Date.now().toString(36);

饮水记录界面

// HydrationHistoryView.ets
@Component
struct HydrationHistoryView {
@State records: HydrationRecord[] = [];
@State dailyGoal: number = 2000;
@State consumed: number = 0;

aboutToAppear() {
this.loadRecords();
this.loadUserProfile();
EventBus.on(‘hydrationRecordUpdated’, () => this.loadRecords());
build() {

Column() {
  // 今日饮水进度
  Text('今日饮水')
    .fontSize(24)
    .fontWeight(FontWeight.Bold)
    .margin({ top: 16 })
  
  Progress({
    value: this.consumed,
    total: this.dailyGoal,
    type: ProgressType.PROGRESS_TYPE_LINEAR
  })
  .width('90%')
  .height(20)
  .margin({ top: 16 })
  
  Text({this.consumed} / {this.dailyGoal} ml)
    .fontSize(16)
    .margin({ top: 8 })
  
  // 快速记录按钮
  Row() {
    Button('+200ml')
      .onClick(() => this.recordIntake(200))
    
    Button('+500ml')
      .onClick(() => this.recordIntake(500))
      .margin({ left: 16 })

.margin({ top: 24 })

  // 记录列表
  if (this.records.length === 0) {
    Text('暂无饮水记录')
      .fontSize(16)
      .margin({ top: 32 })

else {

    List({ space: 10 }) {
      ForEach(this.records, (record) => {
        ListItem() {
          HydrationRecordItem({ record })

})

.layoutWeight(1)

}

.padding(16)

private async loadRecords(): Promise<void> {

const today = new Date().toISOString().split('T')[0];
this.records = await hydrationSyncService.getHydrationRecords(today);
this.consumed = this.records.reduce((sum, r) => sum + r.amount, 0);

private async loadUserProfile(): Promise<void> {

const profile = await hydrationSyncService.getUserProfile();
if (profile) {
  this.dailyGoal = hydrationService.calculateDailyRequirement(profile);

}

private async recordIntake(amount: number): Promise<void> {
const record: HydrationRecord = {
id: generateId(),
amount,
timestamp: Date.now(),
status: ‘manual’
};

await hydrationSyncService.syncHydrationRecord(record);

}

@Component
struct HydrationRecordItem {
private record: HydrationRecord;

build() {
Row() {
Column() {
Text(${this.record.amount}ml)
.fontSize(18)

    Text(formatTime(this.record.timestamp))
      .fontSize(14)
      .fontColor('#666666')
      .margin({ top: 4 })

.layoutWeight(1)

  if (this.record.status === 'dehydrated') {
    Text('脱水状态')
      .fontSize(14)
      .fontColor('#FF5722')

}

.padding(12)

}

function formatTime(timestamp: number): string {
const date = new Date(timestamp);
return {date.getHours()}:{date.getMinutes().toString().padStart(2, ‘0’)};

健康报告界面

// HealthReportView.ets
@Component
struct HealthReportView {
@State hydrationData: HydrationData[] = [];
@State userProfile: UserProfile | null = null;

aboutToAppear() {
this.loadData();
this.loadUserProfile();
build() {

Column() {
  if (this.userProfile) {
    Text(${this.userProfile.name}的健康报告)
      .fontSize(24)
      .fontWeight(FontWeight.Bold)
      .margin({ top: 16 })
    
    // 本周饮水趋势
    Text('本周饮水趋势')
      .fontSize(20)
      .margin({ top: 24 })
    
    if (this.hydrationData.length > 0) {
      Row() {
        ForEach(this.hydrationData, (day) => {
          Column() {
            Text('')
              .width(20)
              .height(day.amount / 50) // 比例缩放
              .backgroundColor('#2196F3')
            
            Text(day.day)
              .fontSize(12)
              .margin({ top: 4 })

.margin({ right: 8 })

        })

.height(100)

      .margin({ top: 8 })

// 脱水状态统计

    Text('脱水状态统计')
      .fontSize(20)
      .margin({ top: 24 })
    
    if (this.hydrationData.some(d => d.dehydratedCount > 0)) {
      Row() {
        Text(脱水次数: ${this.hydrationData.reduce((sum, d) => sum + d.dehydratedCount, 0)})
          .fontSize(16)
        
        Text(最严重: ${Math.max(...this.hydrationData.map(d => d.dehydrationScore))}分)
          .fontSize(16)
          .margin({ left: 16 })

.margin({ top: 8 })

else {

      Text('本周未检测到脱水状态')
        .fontSize(16)
        .margin({ top: 8 })

// 健康建议

    Text('健康建议')
      .fontSize(20)
      .margin({ top: 24 })
    
    if (this.hydrationData.length > 0) {
      const avgIntake = this.hydrationData.reduce((sum, d) => sum + d.amount, 0) / this.hydrationData.length;
      const requirement = this.userProfile ? 
        hydrationService.calculateDailyRequirement(this.userProfile) : 2000;
      
      if (avgIntake < requirement * 0.8) {
        Text('您的平均饮水量低于建议值,建议增加每日饮水量')
          .fontSize(16)
          .margin({ top: 8 })

else if (avgIntake > requirement * 1.2) {

        Text('您的饮水量充足,继续保持')
          .fontSize(16)
          .margin({ top: 8 })

else {

        Text('您的饮水量在正常范围内,继续保持良好习惯')
          .fontSize(16)
          .margin({ top: 8 })

}

}

.padding(16)

private async loadData(): Promise<void> {

// 获取最近7天数据
const entries = await hydrationSyncService.getHydrationRecords();
const now = new Date();

this.hydrationData = Array.from({ length: 7 }, (_, i) => {
  const date = new Date(now);
  date.setDate(date.getDate() - i);
  const dateStr = date.toISOString().split('T')[0];
  const dayRecords = entries.filter(r => r.date === dateStr);
  
  return {
    day: ['日', '一', '二', '三', '四', '五', '六'][date.getDay()],
    date: dateStr,
    amount: dayRecords.reduce((sum, r) => sum + r.amount, 0),
    dehydratedCount: dayRecords.filter(r => r.status === 'dehydrated').length,
    dehydrationScore: dayRecords.reduce((max, r) => 
      r.dehydrationScore ? Math.max(max, r.dehydrationScore) : max, 0
    )
  };
}).reverse();

private async loadUserProfile(): Promise<void> {

this.userProfile = await hydrationSyncService.getUserProfile();

}

四、高级功能实现
多设备协同提醒

// CollaborativeReminderService.ets
class CollaborativeReminderService {
private static instance: CollaborativeReminderService;

private constructor() {}

public static getInstance(): CollaborativeReminderService {
if (!CollaborativeReminderService.instance) {
CollaborativeReminderService.instance = new CollaborativeReminderService();
return CollaborativeReminderService.instance;

public async syncReminderToDevices(reminder: HydrationReminder): Promise<void> {

const devices = await deviceManager.getTrustedDevices();
await Promise.all(devices.map(device => 
  this.sendReminderToDevice(device.id, reminder)
));

private async sendReminderToDevice(deviceId: string, reminder: HydrationReminder): Promise<void> {

const ability = await featureAbility.startAbility({
  bundleName: 'com.example.hydrationReminder',
  abilityName: 'HydrationReminderAbility',
  deviceId
});

await ability.call({
  method: 'receiveReminder',
  parameters: [reminder]
});

public async syncEmergencyAlert(status: HydrationStatus): Promise<void> {

if (status.hydrationLevel !== 'dehydrated') return;

const devices = await deviceManager.getTrustedDevices();
await Promise.all(devices.map(device => 
  this.sendAlertToDevice(device.id, status)
));

private async sendAlertToDevice(deviceId: string, status: HydrationStatus): Promise<void> {

const ability = await featureAbility.startAbility({
  bundleName: 'com.example.hydrationReminder',
  abilityName: 'HydrationAlertAbility',
  deviceId
});

await ability.call({
  method: 'receiveEmergencyAlert',
  parameters: [status]
});

}

export const collaborativeReminderService = CollaborativeReminderService.getInstance();

智能饮水计划

// HydrationPlanService.ets
import reminderAgent from ‘@ohos.reminderAgent’;

class HydrationPlanService {
private static instance: HydrationPlanService;

private constructor() {}

public static getInstance(): HydrationPlanService {
if (!HydrationPlanService.instance) {
HydrationPlanService.instance = new HydrationPlanService();
return HydrationPlanService.instance;

public async createDailyPlan(userProfile: UserProfile): Promise<void> {

const dailyRequirement = hydrationService.calculateDailyRequirement(userProfile);
const intervals = this.calculateOptimalIntervals(dailyRequirement);

await this.cancelAllReminders();

for (const interval of intervals) {
  await this.scheduleReminder(interval.time, interval.amount);

}

private calculateOptimalIntervals(total: number): { time: string; amount: number }[] {
// 将总水量分配到一天中的最佳时间点
const intervals = [
time: ‘08:00’, amount: Math.round(total * 0.2) },

time: ‘11:00’, amount: Math.round(total * 0.2) },

time: ‘14:00’, amount: Math.round(total * 0.2) },

time: ‘17:00’, amount: Math.round(total * 0.2) },

time: ‘20:00’, amount: Math.round(total * 0.2) }

];

return intervals;

private async scheduleReminder(time: string, amount: number): Promise<void> {

const [hours, minutes] = time.split(':').map(Number);
const reminderTime = new Date();
reminderTime.setHours(hours, minutes, 0, 0);

const reminderRequest: reminderAgent.ReminderRequest = {
  reminderType: reminderAgent.ReminderType.REMINDER_TYPE_TIMER,
  actionButton: [{ title: '已饮水' }, { title: '稍后提醒' }],
  wantAgent: {
    pkgName: 'com.example.hydrationReminder',
    abilityName: 'HydrationReminderAbility'
  },
  ringDuration: 60,
  snoozeTimes: 2,
  triggerTime: reminderTime.getTime(),
  repeatInterval: 24  60  60 * 1000, // 每天重复
  title: '饮水提醒',
  content: 该喝水了!建议饮水量: ${amount}ml,
  expiredContent: "饮水提醒已过期"
};

await reminderAgent.publishReminder(reminderRequest);

public async cancelAllReminders(): Promise<void> {

const reminders = await reminderAgent.getValidReminders();
await Promise.all(reminders.map(rem => 
  reminderAgent.cancelReminder(rem.id)
));

}

export const hydrationPlanService = HydrationPlanService.getInstance();

环境因素分析

// EnvironmentAnalysisService.ets
import geolocation from ‘@ohos.geolocation’;
import sensor from ‘@ohos.sensor’;

class EnvironmentAnalysisService {
private static instance: EnvironmentAnalysisService;
private geoLocationManager: geolocation.GeoLocationManager;
private temperatureSensor: sensor.Sensor | null = null;

private constructor() {
this.geoLocationManager = geolocation.createGeoLocationManager();
public static getInstance(): EnvironmentAnalysisService {

if (!EnvironmentAnalysisService.instance) {
  EnvironmentAnalysisService.instance = new EnvironmentAnalysisService();

return EnvironmentAnalysisService.instance;

public async startMonitoring(): Promise<void> {

// 获取当前位置
const location = await this.geoLocationManager.getCurrentLocation();

// 获取天气数据
const weather = await this.getWeatherData(location.latitude, location.longitude);

// 启动温度传感器
this.temperatureSensor = await sensor.getSensor(sensor.SensorType.SENSOR_TYPE_AMBIENT_TEMPERATURE);
this.temperatureSensor.on('change', (data) => {
  this.handleTemperatureChange(data);
});

EventBus.emit('environmentDataUpdated', {
  location,
  weather,
  indoorTemperature: null
});

private async getWeatherData(lat: number, lon: number): Promise<WeatherData> {

const httpClient = http.createHttp();
return new Promise((resolve, reject) => {
  httpClient.request(
    https://weather-api.example.com/current?lat={lat}&lon={lon},

method: ‘GET’ },

    (err, data) => {
      if (err) {
        reject(err);

else {

        resolve(JSON.parse(data.result));

}

  );
});

private handleTemperatureChange(data: sensor.SensorData): void {

const temperature = data.value;
let environmentType: 'hot' 'normal'

‘cold’ = ‘normal’;

if (temperature > 28) {
  environmentType = 'hot';

else if (temperature < 15) {

  environmentType = 'cold';

EventBus.emit(‘temperatureUpdated’, {

  temperature,
  environmentType
});

public adjustHydrationPlan(environment: EnvironmentData, currentPlan: HydrationPlan): HydrationPlan {

let adjustmentFactor = 1.0;

// 根据环境温度调整
if (environment.temperature > 30) {
  adjustmentFactor *= 1.3;

else if (environment.temperature < 10) {

  adjustmentFactor *= 0.9;

// 根据湿度调整

if (environment.humidity < 40) {
  adjustmentFactor *= 1.2;

else if (environment.humidity > 70) {

  adjustmentFactor *= 0.9;

// 根据活动量调整

if (environment.activityLevel === 'high') {
  adjustmentFactor *= 1.2;

return {

  ...currentPlan,
  dailyGoal: Math.round(currentPlan.dailyGoal * adjustmentFactor),
  intervals: currentPlan.intervals.map(i => ({
    ...i,
    amount: Math.round(i.amount * adjustmentFactor)
  }))
};

}

export const environmentService = EnvironmentAnalysisService.getInstance();

五、总结

本智能饮水提醒应用实现了以下核心价值:
精准检测:通过面部特征分析准确判断脱水状态

个性化计划:根据用户特征和环境因素定制饮水计划

智能提醒:在最佳时间提醒用户补充水分

多设备协同:跨设备同步健康数据和提醒

健康追踪:长期记录和分析用户饮水习惯

扩展方向:
集成智能水杯数据

增加水分摄入来源分析(食物、饮料等)

开发家庭共享模式

增加健康知识推送

注意事项:
需要申请ohos.permission.CAMERA权限

面部检测准确率受光线和角度影响

脱水分析结果仅供参考,不能替代医学诊断

多设备协同需保持网络连接

环境数据需要位置权限和网络连接

©著作权归作者所有,如需转载,请注明出处,否则将追究法律责任
收藏
回复
举报
回复
    相关推荐