# FlutterSDK **Repository Path**: yucheng_3/flutter-sdk ## Basic Information - **Project Name**: FlutterSDK - **Description**: 玉成Flutter的SDK - **Primary Language**: Dart - **License**: MulanPSL-2.0 - **Default Branch**: master - **Homepage**: None - **GVP Project**: No ## Statistics - **Stars**: 1 - **Forks**: 3 - **Created**: 2024-08-22 - **Last Updated**: 2025-07-22 ## Categories & Tags **Categories**: Uncategorized **Tags**: None ## README # 1. 插件集成 ## 1.1 代码集成 ```yaml yc_product_plugin: git: url: https://gitee.com/yucheng_3/yc_product_plugin.git path: code/ ``` ## 1.2 平台配置 AndroidManifest.xml增加dfu服务 ```xml ``` # 2. 插件初始化 * 方法 ```dart /// 插件初始化 /// isReconnectEnable 是否设置回连 /// isLogEnable 是否开启回连 Future initPlugin({bool isReconnectEnable = true, bool isLogEnable = false}; /// 插件结果 class PluginResponse { /// 结果状态 PluginState final int statusCode; /// 结果列表 final T data; } /// 插件API的状态 class PluginState { static const int succeed = 0; // 执行成功 static const int failed = 1; // 执行失败 static const int unavailable = 2; // 设备不支持 } ``` * 说明 * 初始化只要在程序启动时,执行一次。 * 示例 ```dart // init plugin YcProductPlugin().initPlugin(isReconnectEnable: false, isLogEnable: true); ``` # 3. 设备连接与断开 ## 3.1 搜索设备 * 方法 ```dart /// 扫描设备 Future?> scanDevice({int time = 6}) ``` * 说明 * 通过指定不同的搜索时间来搜索设备 * 示例 ```dart // 搜索设备 YcProductPlugin().scanDevice(time: 3).then((devices) { debugPrint("=== 设备 $devices"); // devices?.sort((a, b) => (b?.rssiValue.toInt() ?? 0) - (a?.rssiValue.toInt() ?? 0)); // _devices = devices ?? []; }); ``` ## 3.2 连接设备 * 方法 ```dart Future connectDevice(BluetoothDevice device); ``` * 说明 * 示例 ```dart YcProductPlugin().connectDevice(item).then((value) { if (value == true) { debugPrint("Connected"); } else { debugPrint("Connect failed"); } }); ``` ## 3.3 断开设备 * 方法 ```dart Future disconnectDevice(); ``` * 说明 * 要以通过结果来判断是否断开成功 * 示例 ```dart YcProductPlugin().disconnectDevice(); ``` ## 3.4 获取当前连接状态 * 方法 ```dart Future getBluetoothState(); ``` * 说明 * 获取当前蓝牙状态,返回值 BluetoothState。 * 示例 ```dart YcProductPlugin().getBluetoothState().then((value) { if (value == BluetoothState.connected) { } } ``` ## 3.5 监听蓝牙状态变化 * 方法 ```dart /// 开启监听 void onListening(void Function(dynamic event) onData); /// 原生传递事件类型 class NativeEventType { /// 蓝牙状态变化 static const String bluetoothStateChange; /// 设备拍照状态变化 static const String deviceControlPhotoStateChange; /// 设备找手机状态变化 static const String deviceControlFindPhoneStateChange; /// 设备一键测量状态变化 static const String deviceHealthDataMeasureStateChange; /// 设备运动状态变化 static const String deviceSportStateChange; /// 设备表盘切换变更 static const String deviceWatchFaceChange; /// 杰理表盘切换变更 static const String deviceJieLiWatchFaceChange; // MARK: - 实时数据 /// 计步 static const String deviceRealStep; /// 运动 static const String deviceRealSport; /// 心率 static const String deviceRealHeartRate; /// 血压 static const String deviceRealBloodPressure; /// 血氧 static const String deviceRealBloodOxygen; /// 温度 static const String deviceRealTemperature; /// 实时ECG数据 static const String deviceRealECGData; /// 实时ECG数据滤波数据 static const String deviceRealECGFilteredData; /// 实时PPG数据 static const String deviceRealPPGData; /// 实时RR数据 static const String deviceRealECGAlgorithmRR; /// 实时HRV数据 static const String deviceRealECGAlgorithmHRV; } ``` * 说明 * 蓝牙状态发送变化,插件会主动将状态广播出来。 * 监听设备会返回一个Map, Map中的信息类型在 NativeEventType 有定义说明。 * 示例 ```dart YcProductPlugin().onListening((event) { if (event.keys.contains(NativeEventType.bluetoothStateChange)) { final int st = event[NativeEventType.bluetoothStateChange]; debugPrint('蓝牙状态变化 $st'); setState(() { // .... }); } }); ``` # 4. 健康历史数据 * 可以获操作的数据类型如下 ```dart /// 健康数据类型 class HealthDataType { static const step = 0; // 步数(步数、距离、卡咱里) static const sleep = 1; // 睡眠 static const heartRate = 2; // 心率 static const bloodPressure = 3; // 血压 static const combinedData = 4; // 组合数据(体温、血氧、呼吸率、血糖等) static const invasiveComprehensiveData = 5; // 血脂和尿酸 static const sportHistoryData = 6; // 运动历史记录 } ``` * 步数数据 * 这是历史步数,每半小时产生一条记录,与表盘上显示的实时步数会存在半小时的差异。 ```dart /// 步数 class StepDataInfo { // 开始时间 int startTimeStamp = 0; // 结束时间 int endTimeStamp = 0; // 步数 int step = 0; // 距离 (米) int distance = 0; // 卡路里 (千卡) int calories = 0; @override String toString(); } ``` * 睡眠数据 * 睡眠数据会跨天存储,设备是从晚上的20:00开始监测,直到第二天的12:00结束,如果中途产生了一条或多条睡眠记录也是正常的。 * 睡眠数据中如果`isNewSleepProtocol`是true则使用的新格式,包含四种睡眠状态,反之只有深睡和浅睡两种状态。 ```dart /// 睡眠状态 class SleepType { /// 深睡状态 static const int deepSleep = 0xF1; /// 浅睡状态 static const int lightSleep = 0xF2; /// 快速眼动 static const int rem = 0xF3; /// 清醒状态 static const int awake = 0xF4; } /// 睡眠的详细状态 class SleepDetailDataInfo { /// 开始时间 (秒) int startTimeStamp = 0; /// 时长 (秒) int duration = 0; /// 类型 使用 SleepType 判断 int sleepType = 0; @override String toString(); } /// 睡眠信息 class SleepDataInfo { /// 新旧睡眠区分标记 bool isNewSleepProtocol = false; /// 开始时间 (秒) int startTimeStamp = 0; /// 结束时间 (秒) int endTimeStamp = 0; /// 深睡 (秒) int deepSleepSeconds = 0; /// 浅睡 (秒) int lightSleepSeconds = 0; /// rem (秒) int remSleepSeconds = 0; /// 详细数据 List list = []; @override String toString(); } ``` * 心率数据 ```dart /// 心率数据 class HeartRateDataInfo { /// 测量时间 (秒) int startTimeStamp = 0; /// 心率值 int heartRate = 0; @override String toString(); } ``` * 血压数据 * 光电血压,可以通过API进行校准,校准指令可以通过文档中血压校准API来实现。 ```dart /// 健康数据测量模式 class HealthDataMeasureMode { /// 单次测量 static const int single = 0; /// 自动监测 static const int monitor = 1; /// 外接模块测量 static const int inflated = 2; } /// 血压数据 class BloodPressureDataInfo { /// 开始时间(秒) int startTimeStamp = 0; /// 收缩压 int systolicBloodPressure = 0; /// 舒张压 int diastolicBloodPressure = 0; /// HealthDataMeasureMode 等价 int mode = 0; @override String toString(); } ``` * 组合数据 (血压、呼吸率、温度、血糖) * 其它参数如步数、心率、血压不要使用。 * 温度的单位使用的是摄氏度,如果小数部分出现`15`,表示此温度值无效。 * 血糖的单位使用的是 mmol/L,与血压一样,血糖也可以通过血糖标定API来进行标定。 ```dart /// 组合数据 class CombinedDataDataInfo { /// 测量时间 (秒) int startTimeStamp = 0; int step = 0; int heartRate = 0; int systolicBloodPressure = 0; int diastolicBloodPressure = 0; /// 血氧 int bloodOxygen = 0; /// 呼吸率 int respirationRate = 0; int hrv = 0; int cvrr = 0; /// 血糖 mmol/L double bloodGlucose = 0; /// 体脂 double fat = 0; /// 温度 C double temperature = 0; @override String toString(); } ``` * 血脂和尿酸 * 血脂和尿酸也可以通过对应的API来标定。 * 目前用到的只有尿酸(uricAcid)和总胆固醇(totalCholesterol)两个参数。 ```dart /// 有创组合数据 class InvasiveComprehensiveDataInfo { /// 时间戳 int startTimeStamp = 0; /// 血糖测量模式 HealthDataMeasureMode int bloodGlucoseMode = 0; /// 血糖值 double bloodGlucose = 0.0; /// 尿酸模式 HealthDataMeasureMode int uricAcidMode = 0; /// 尿酸 int uricAcid = 0; /// 血酮模式 HealthDataMeasureMode int bloodKetoneMode = 0; /// 血酮 double bloodKetone = 0.0; /// 血酯模式 HealthDataMeasureMode int bloodFatMode = 0; /// 总胆固醇 double totalCholesterol = 0.0; /// 高密度脂蛋白胆固醇 double hdlCholesterol = 0.0; /// 低密度脂蛋白胆固醇 double ldlCholesterol = 0.0; /// 甘油三酯 double triglycerides = 0.0; @override String toString(); } ``` * 运动历史数据 * 如果按每10秒一条的格式返回 * 调用都可以按照时间的升序,相邻运动时间、相同运动类型的条件进行合并。 ```dart /// 运动类型定义 class DeviceSportType { static const int none = 0; // 保留 static const int run = 0x01; // 跑步 (户外) static const int swimming = 0x02; // 游泳 static const int riding = 0x03; // 户外骑行 static const int fitness = 0x04; // 健身 static const int ropeskipping = 0x06; // 跳绳 static const int playball = 0x07; // 篮球(打球) static const int walk = 0x08; // 健走 static const int badminton = 0x09; // 羽毛球 static const int football = 0x0A; // 足球 static const int mountaineering = 0x0B; // 登山 static const int pingPang = 0x0C; // 乒乓球 static const int freeMode = 0x0D; // 自由模式 static const int indoorRunning = 0x0E; // 室内跑步 static const int outdoorRunning = 0x0F; // 户外跑步 static const int outdoorWalking = 0x10; // 户外步行 static const int indoorWalking = 0x11; // 室内步行 static const int runMode = 0x12; // 走跑模式 static const int indoorRiding = 0x13; // 室内骑行 static const int stepper = 0x14; // 踏步机 static const int rowingMachine = 0x15; // 划船机 static const int realTimeMonitoring = 0x16; // 实时监护 static const int situps = 0x17; // 仰卧起坐 static const int jumping = 0x18; // 跳跃运动 static const int weightTraining = 0x19; // 重量训练 static const int yoga = 0x1A; // 瑜伽 static const int onfoot = 0x1B; // 徒步 static const int volleyball = 0x1C; // 排球 static const int kayak = 0x1D; // 皮划艇 static const int rollerSkating = 0x1E; // 轮滑 static const int tennis = 0x1F; // 网球 static const int golf = 0x20; // 高尔夫 static const int ellipticalMachine = 0x21; // 椭圆机 static const int dance = 0x22; // 舞蹈 static const int rockClimbing = 0x23; // 攀岩 static const int aerobics = 0x24; // 健身操 static const int otherSports = 0x25; // 其它运动 } /// 运动启动方式 class DeviceSportModeStartMethod { static const int app = 0; static const int device = 1; } /// 运动状态 enum DeviceSportState { stop, start, } /// 运动信息 class SportModeDataInfo { /// 开始时间戳(秒) int startTimeStamp = 0; /// 结束时间戳(秒) int endTimeStamp = 0; /// 运动启动方式 DeviceSportModeStartMethod int flag = 0; /// 运动方式 DeviceSportType 类型 int sportType = 0; /// 运动时间 (保留参数) int sportTime = 0; /// 步数 (步) int step = 0; /// 距离 (米) int distance = 0; /// 卡路里(千卡) int calories = 0; /// 心率 int heartRate = 0; /// 最小心率 (保留参数) int minimumHeartRate = 0; /// 最大心率 (保留参数) int maximumHeartRate = 0; @override String toString(); } ``` ## 4.1 查询数据 * 方法 ```dart Future?> queryDeviceHealthData(int healthDataType); ``` * 说明 * 依据不同的类型来获取设备上产生的历史数据。 * 示例 ```dart YcProductPlugin().queryDeviceHealthData(HealthDataType.heartRate).then((result) { if (result?.statusCode == PluginState.succeed) { final list = result?.data ?? []; for (var item in list) { debugPrint(item.toString()); } } else { debugPrint("failed"); } }); ``` ## 4.2 删除数据 * 方法 ```dart Future deleteDeviceHealthData(int healthDataType); ``` * 说明 * 依据不同的数据类型删除不同的数据,执行了删除指令后,再次获取将获取不到执行删除指令前的数据,但不影响手表上的数据显示。 * 参数类型与查询是相同的类型。 * 示例 ```dart YcProductPlugin().deleteDeviceHealthData(HealthDataType.heartRate).then((value) { if (value?.statusCode == PluginState.succeed) { debugPrint("succeed"); } else if (value?.statusCode == PluginState.failed) { debugPrint("failed"); } else if (value?.statusCode == PluginState.unavailable) { debugPrint("unavailable"); } }, ); ``` # 5. 获取信息 ## 5.1 基本信息 * 方法 ```dart /// 设备种类 enum DeviceType { watch, ring, touchRing, bodyTemperatureSticker, ecgStickers } /// 设备电量状态 enum DeviceBatteryState { normal, low, charging, full, } class DeviceBasicInfo { /// 设备id int deviceID = 0; /// 设备类别 DeviceType deviceType = DeviceType.watch; /// 电池状态 DeviceBatteryState batteryStatus = DeviceBatteryState.normal; /// 电量 int batteryPower = 0; /// 固件主版本 int firmwareMajorVersion = 0; /// 固件子版本 int firmwareSubVersion = 0; /// 显示固件版本 String get firmwareVersion; @override String toString(); } /// 查询设备的基本信息 Future?> queryDeviceBasicInfo(); ``` ## 5.2 功能支持列表 * 方法 ```dart /// 获取设备功能列表 FuturegetDeviceFeature(); /// 功能列表 class DeviceFeature { /// 血压 bool isSupportBloodPressure = false; /// 语言设置 bool isSupportLanguageSettings = false; /// 消息推送 (总开关) bool isSupportInformationPush = false; /// 心率 bool isSupportHeartRate = false; /// OTA升级 bool isSupportOta = true; /// 实时数据上传 bool isSupportRealTimeDataUpload = false; /// 睡眠 bool isSupportSleep = false; /// 计步 bool isSupportStep = false; // MARK: - === 主要功能2 === /// 多运动 bool isSupportSport = false; /// HRV bool isSupportHRV = false; /// 呼吸率 bool isSupportRespirationRate = false; /// 血氧 bool isSupportBloodOxygen = false; /// 历史ECG bool isSupportHistoricalECG = false; /// 实时ECG bool isSupportRealTimeECG = false; /// 血压告警 bool isSupportBloodPressureAlarm = false; /// 心率告警 bool isSupportHeartRateAlarm = false; // MARK: - === 闹钟类型 ==== /// 闹钟数量( alarmClockCount 0表示不支持闹钟) bool isSupportAlarm = false; /// 闹钟类型 起床 bool isSupportAlarmTypeWakeUp = false; /// 闹钟类型 起床 bool isSupportAlarmTypeSleep = false; /// 闹钟类型 锻炼 bool isSupportAlarmTypeExercise = false; /// 闹钟类型 吃药 bool isSupportAlarmTypeMedicine = false; /// 闹钟类型 约会 bool isSupportAlarmTypeAppointment = false; /// 闹钟类型 聚会 bool isSupportAlarmTypeParty = false; /// 闹钟类型 会议 bool isSupportAlarmTypeMeeting = false; /// 闹钟类型 自定义 bool isSupportAlarmTypeCustom = false; // MARK: - === 消息推送 === // 第一组 bool isSupportInformationTypeTwitter = false; bool isSupportInformationTypeFacebook = false; bool isSupportInformationTypeWeiBo = false; bool isSupportInformationTypeQQ = false; bool isSupportInformationTypeWeChat = false; bool isSupportInformationTypeEmail = false; bool isSupportInformationTypeSMS = false; bool isSupportInformationTypeCall = false; // 第二组 bool isSupportInformationTypeTelegram = false; bool isSupportInformationTypeSkype = false; bool isSupportInformationTypeSnapchat = false; bool isSupportInformationTypeLine = false; bool isSupportInformationTypeLinkedIn = false; bool isSupportInformationTypeInstagram = false; bool isSupportInformationTypeMessenger = false; bool isSupportInformationTypeWhatsApp = false; // MARK: - === 其它功能1 === /// 翻腕亮屏 bool isSupportWristBrightScreen = false; /// 勿扰模式 bool isSupportDoNotDisturbMode = false; /// 血压水平设置 bool isSupportBloodPressureLevelSetting = false; /// 出厂设置 bool isSupportFactorySettings = false; /// 找设备 bool isSupportFindDevice = false; /// 找手机 bool isSupportFindPhone = false; /// 防丢提醒 bool isSupportAntiLostReminder = false; /// 久坐提醒 bool isSupportSedentaryReminder = false; // MARK: - === 其它功能2 === /// 上传数据 加密 bool isSupportUploadDataEncryption = false; /// 通话 bool isSupportCall = false; /// 心电诊断 bool isSupportECGDiagnosis = false; /// 明日天气 bool isSupportTomorrowWeather = false; /// 今日天气 bool isSupportTodayWeather = false; /// 搜周边 bool isSupportSearchAround = false; /// 微信运动 bool isSupportWeChatSports = false; /// 肤色设置 bool isSupportSkinColorSettings = false; // MARK: - === 其它功能3 === /// 温度 bool isSupportTemperature = false; /// 压力 bool isSupportPressure = false; // 最大摄氧量 bool isSupportVo2max = false; /// 音乐控制 bool isSupportMusicControl = false; /// 主题 bool isSupportTheme = false; /// 电极位置 bool isSupportElectrodePosition = false; /// 血压校准 bool isSupportBloodPressureCalibration = false; /// CVRR bool isSupportCVRR = false; /// 腋温测量 bool isSupportAxillaryTemperatureMeasurement = false; /// 温度预警 bool isSupportTemperatureAlarm = false; // MARK: - === 其它功能4 === /// 温度校准 bool isSupportTemperatureCalibration = false; /// 机主信息编辑 bool isSupportHostInfomationEdit = false; /// 手动拍照 bool isSupportManualPhotographing = false; /// 摇一摇拍照 bool isSupportShakePhotographing = false; /// 女性生理周期 bool isSupportFemalePhysiologicalCycle = false; /// 表盘功能 bool isSupportWatchFace = false; /// 通讯录 bool isSupportAddressBook = false; /// ECG结果精准 bool isECGResultsAccurate = true; // MARK: - 运动模式 /// 登山 bool isSupportMountaineering = false; /// 足球 bool isSupportFootball = false; /// 乒乓球 bool isSupportPingPang = false; /// 户外跑步 bool isSupportOutdoorRunning = false; /// 室内跑步 bool isSupportIndoorRunning = false; /// 户外步行 bool isSupportOutdoorWalking = false; /// 室内步行 bool isSupportIndoorWalking = false; /// 实时监护模式 bool isSupportRealTimeMonitoring = false; /// 羽毛球 bool isSupportBadminton = false; /// 健走 bool isSupportWalk = false; /// 游泳 bool isSupportSwimming = false; /// 篮球 bool isSupportPlayBall = false; /// 跳绳 bool isSupportRopeSkipping = false; /// 骑行 bool isSupportRiding = false; /// 健身 bool isSupportFitness = false; /// 跑步 bool isSupportRun = false; /// 室内骑行 bool isSupportIndoorRiding = false; /// 踏步机 bool isSupportStepper = false; /// 划船机 bool isSupportRowingMachine = false; /// 仰卧起坐 bool isSupportSitUps = false; /// 跳跃运动 bool isSupportJumping = false; /// 重量训练 bool isSupportWeightTraining = false; /// 瑜伽 bool isSupportYoga = false; /// 徒步 bool isSupportOnFoot = false; // MARK: - === 扩充功能 /// 同步运动实时数据 bool isSupportSyncRealSportData = false; /// 启动心率测量 bool isSupportStartHeartRateMeasurement = false; /// 启动血压测量 bool isSupportStartBloodPressureMeasurement = false; /// 启动血氧测量 bool isSupportStartBloodOxygenMeasurement = false; /// 启动体温测量 bool isSupportStartBodyTemperatureMeasurement = false; /// 启动压力测量 bool isSupportStartPressureMeasurement = false; /// 启动呼吸率测量 bool isSupportStartRespirationRateMeasurement = false; /// 自定义表盘 bool isSupportCustomWatchface = false; // ================================================================= /// 精准血压测量 bool isSupportAccurateBloodPressureMeasurement = false; /// SOS开关 bool isSupportSOS = false; /// 血氧报警 bool isSupportBloodOxygenAlarm = false; /// 精准血压实时数据上传 bool isSupportAccurateBloodPressureRealTimeDataUpload = false; /// Viber消息推送 bool isSupportInformationTypeViber = false; /// 其它消息推送 bool isSupportInformationTypeOther = false; /// 自定义表盘颜色翻转 bool isFlipCustomDialColor = false; /// 手表亮度调节五档 bool isSupportFiveSpeedBrightness = false; // ================================================================= /// 震动强度设置 bool isSupportVibrationIntensitySetting = false; /// 亮屏时间设置 bool isSupportScreenTimeSetting = false; /// 亮屏亮度调节 bool isSupportScreenBrightnessAdjust = true; /// 血糖测量 bool isSupportBloodGlucose = false; /// 运动暂停 bool isSupportSportPause = false; /// 喝水提醒 bool isSupportDrinkWaterReminder = false; /// 发送名片 bool isSupportBusinessCard = false; /// 尿酸测量 bool isSupportUricAcid = false; // MARK: - 运动模式4 /// 网球 bool isSupportVolleyball = false; /// 皮划艇 bool isSupportKayak = false; /// 轮滑 bool isSupportRollerSkating = false; /// 网球 bool isSupportTennis = false; /// 高尔夫 bool isSupportGolf = false; /// 椭圆机 bool isSupportEllipticalMachine = false; /// 舞蹈 bool isSupportDance = false; /// 攀岩 bool isSupportRockClimbing = false; /// 健身操 bool isSupportAerobics = false; /// 其它运动 bool isSupportOtherSports = false; /// 血酮测量 bool isSupportBloodKetone = false; /// 支持支付宝 bool isSupportAliPay = false; /// 安卓绑定 bool isSupportAndroidBind = false; /// 呼吸率告警 bool isSupportRespirationRateAlarm = false; /// 血脂测量 bool isSupportBloodFat = false; /// 独立监测时间(E200测量) bool isSupportIndependentMonitoringTime = false; /// 本地录音上传 bool isSupportLocalRecordingFileUpload = false; /// 理疗记录 bool isSupportPhysiotherapyRecords = false; /// 是否支持消息推送 Zoom bool isSupportInformationTypeZoom = false; /// 是否支持消息推送 TikTok bool isSupportInformationTypeTikTok = false; /// 是否支持消息推送 KakaoTalk bool isSupportInformationTypeKaKaoTalk = false; // MARK: - /// 是否支持睡眠提醒 bool isSupportSleepReminder = false; /// 是否支持设备规格设置 bool isSupportDeviceSpecificationsSetting = false; /// 是否支持设备本地运动上传 bool isSupportLocalSportDataUpload = false; } ``` * 说明 * 此方法不需要调用,在设备连接后,在当前连接设备的属性中就可以直接获取。 * 示例 ```dart final feature = await getDeviceFeature(); ``` ## 5.3 Mac地址 * 方法 ```dart /// 查询设备mac地址 Future?> queryDeviceMacAddress(); ``` * 说明 * 此方法获取的是当前连接的设备Mac地址 * 示例 ```dart YcProductPlugin().queryDeviceMacAddress().then((value) { if (value?.statusCode == PluginState.succeed) { final macAddress = value?.data ?? ""; } else { } }); ``` ## 5.4 设备型号 * 方法 ```dart /// 查询设备型号 Future?> queryDeviceModel(); ``` * 说明 * 设备型号是用于区分手表的种类。 * 示例 ```dart YcProductPlugin().queryDeviceModel().then((value) { if (value?.statusCode == PluginState.succeed) { final model = value?.data ?? ""; } }); ``` ## 5.5 设备平台 * 方法 ```dart /// 查询设备平台 Future?> queryDeviceMCU(); ``` * 说明 * 用于查询设备的主控使用是哪一种平台,一般会影响到Ota功能。对于具体的定制项目则不需要考虑。 * 示例 ```dart YcProductPlugin().queryDeviceMCU().then((value) { if (value?.statusCode == PluginState.succeed) { final mcu = value?.data ?? DeviceMcuPlatform.nrf52832; } }); ``` # 6. 设置信息 ## 6.1 设置时间 * 方法 ```dart /// 设置时间(同步手机时间) Future setDeviceSyncPhoneTime(); ``` * 说明 * 插件在连接设备后,会主动更新时间,一般不需要调用此方法。 * 更新的时间以当前连接手机的时间为准。 * 示例 ```dart YcProductPlugin().setDeviceSyncPhoneTime(); ``` ## 6.2 设置目标 * 方法 ```dart /// 设置运动步数目标 Future setDeviceStepGoal(int step); /// 设置睡眠目标 Future setDeviceSleepGoal(int hour, int minute); ``` * 说明 * 设备普通支持运动目标和睡眠目标 * 如果是手表达到运动目标后,会出现奖杯,睡眠目标则不会有任何提示。 * 示例 ```dart // 运动目标 10000 步 YcProductPlugin().setDeviceStepGoal(10000).then((value) { if (value?.statusCode == PluginState.succeed) { } else { } }); // 睡眠目标 8小时 30分钟 YcProductPlugin().setDeviceSleepGoal(8, 30).then((value) { if (value?.statusCode == PluginState.succeed) { } else { } }); ``` ## 6.3 设置用户信息 * 方法 ```dart /// 用户性别 enum DeviceUserGender { male, female } /// 设置用户信息 Future setDeviceUserInfo(int height, int weight, int age, DeviceUserGender gender); ``` * 说明 * 用户信息会影响到用户的计量数据 * 示例 ```dart YcProductPlugin().setDeviceUserInfo(170, 65, 18, DeviceUserGender.male).then((value) { if (value?.statusCode == PluginState.succeed) { } else { } }); ``` ## 6.4 肤色设置 * 方法 ```dart /// 皮肤颜色 enum DeviceSkinColorLevel { white, whiteYellow, yellow, brown, darkBrown, black, other } /// 肤色设置 Future setDeviceSkinColor({DeviceSkinColorLevel level = DeviceSkinColorLevel.yellow}); ``` * 说明 * 不同的肤色会影响到设备采集测量数据的工作状态,如测量心率、睡眠等。 * 默认是黄色 * 示例 ```dart YcProductPlugin().setDeviceSkinColor().then((value) { if (value?.statusCode == PluginState.succeed) { } else { } }); ``` ## 6.5 单位设置 * 方法 ```dart /// 距离单位 enum DeviceDistanceUnit { km, mile } /// 体重单位 enum DeviceWeightUnit { kg, lb } /// 温度单位 enum DeviceTemperatureUnit { celsius, fahrenheit } /// 时间格式 enum DeviceTimeFormat { h24, h12 } /// 血糖或血脂单位 enum DeviceBloodGlucoseOrBloodFatUnit { millimolePerLiter, milligramsPerDeciliter } /// 尿酸单位 umol/l mg/dl enum DeviceUricAcidUnit { microMolePerLiter, milligramsPerDeciliter } /// 设置单位 Future setDeviceUnit({DeviceDistanceUnit distance = DeviceDistanceUnit.km, DeviceWeightUnit weight = DeviceWeightUnit.kg, DeviceTemperatureUnit temperature = DeviceTemperatureUnit.celsius, DeviceTimeFormat timeFormat = DeviceTimeFormat.h24, DeviceBloodGlucoseOrBloodFatUnit bloodGlucoseOrBloodFat = DeviceBloodGlucoseOrBloodFatUnit.millimolePerLiter, DeviceUricAcidUnit uricAcid = DeviceUricAcidUnit.microMolePerLiter}); ``` * 说明 * 单位设置,只是影响到手表的数值和单位显示。 * 默认是公制单位 * 示例 ```dart YcProductPlugin().setDeviceUnit(distance: DeviceDistanceUnit.km).then((value) { if (value?.statusCode == PluginState.succeed) { } else { } }); ``` ## 6.6 语言设置 * 方法 ```dart /// 语言类型 class DeviceLanguageType { static const int english = 0x00; static const int chineseSimplified = 0x01; static const int russian = 0x02; static const int german = 0x03; static const int french = 0x04; static const int japanese = 0x05; static const int spanish = 0x06; static const int italian = 0x07; static const int portuguese = 0x08; static const int korean = 0x09; static const int poland = 0x0A; static const int malay = 0x0B; static const int chineseTradition = 0x0C; static const int thai = 0x0D; static const int vietnamese = 0x0F; static const int hungarian = 0x10; static const int arabic = 0x1A; static const int greek = 0x1B; static const int malaysian = 0x1C; static const int hebrew = 0x1D; static const int finnish = 0x1E; static const int czech = 0x1F; static const int croatian = 0x20; static const int persian = 0x24; static const int ukrainian = 0x27; static const int turkish = 0x28; static const int danish = 0x2B; static const int swedish = 0x2C; static const int norwegian = 0x2D; static const int romanian = 0x32; static const int slovak = 0x34; } /// 设置语言 /// language - DeviceLanguageType Future setDeviceLanguage(int language); ``` * 说明 * 设置不同的语言可以使用手表显示不同的语言。 * 如果设置的语言不支持,则显示为英语。 * 示例 ```dart YcProductPlugin().setDeviceLanguage(DeviceLanguageType.english).then((value) { if (value?.statusCode == PluginState.succeed) { } else { } }); ``` ## 6.7 防丢设置 * 方法 ```dart /// 防丢设置 Future setDeviceAntiLost(bool isEnable); ``` * 说明 * 设置防丢开启后,手表与应用连接断开后,手表会震动提示。 * 示例 ```dart YcProductPlugin().setDeviceAntiLost(true).then((value) { if (value?.statusCode == PluginState.succeed) { } else { } }); ``` ## 6.8 勿扰设置 * 方法 ```dart /// 设置勿扰 Future setDeviceNotDisturb(bool isEnable, int startHour, int startMinute, int endHour, int endMinute); ``` * 说明 * 设置勿扰后,手表上的久坐提醒、消息提醒、抬腕亮屏将关闭。 * 方法中的参数分别是使能开关、开始时间和结束时间。 * 示例 ```dart YcProductPlugin().setDeviceNotDisturb(true, 9, 30, 12, 0).then((value) { if (value?.statusCode == PluginState.succeed) { } else { } }); ``` ## 6.9 久坐提醒 * 方法 ```dart /// 星期重复 class DeviceWeekDay { static const int monday = 1 << 0; static const int tuesday = 1 << 1; static const int wednesday = 1 << 2; static const int thursday = 1 << 3; static const int friday = 1 << 4; static const int saturday = 1 << 5; static const int sunday = 1 << 6; } /// 久坐提醒 /// isEnable 是否开启 /// startXXX 开始时间 /// endXXX 结束时间 /// interval 15 ~ 60 分钟,其它值不可以使用 /// repeat 重复,星期设置 DeviceWeekDay Future setDeviceSedentary( bool isEnable, int startHour1, int startMinute1, int endHour1, int endMinute1, int startHour2, int startMinute2, int endHour2, int endMinute2, int interval, Set repeat); ``` * 说明 * 方法中有两组参数,如果设置不同的时间,第一组的时间应该早于第二组。如果只想设置一组时间,则两组的时间应该相同。 * 提醒间隔只能是15~45分钟这个范围,超出这个范围的值是无效的。 * 示例 ```dart final Set week = {}; week.add(DeviceWeekDay.monday); week.add(DeviceWeekDay.tuesday); week.add(DeviceWeekDay.wednesday); week.add(DeviceWeekDay.thursday); week.add(DeviceWeekDay.friday); week.add(DeviceWeekDay.saturday); week.add(DeviceWeekDay.sunday); YcProductPlugin().setDeviceSedentary(true, 9, 30, 12, 0, 14, 0, 18, 30, 30, week).then((value) { if (value?.statusCode == PluginState.succeed) { } else { } }); ``` ## 6.10 手机系统设置 * 方法 ```dart /// 手机系统设置 Future setPhoneSystemInfo(); ``` * 说明 * 用于设置设备,当前连接的手机是什么操作系统和版本。 * 一般情况下,不需要使用此方法,此功能是用于触摸戒指时用于配置智趣功能。 * 示例 ```dart YcProductPlugin().setPhoneSystemInfo().then((value) { if (value?.statusCode == PluginState.succeed) { } else { } }); ``` ## 6.11 抬腕亮屏 * 方法 ```dart /// 抬腕亮屏 Future setDeviceWristBrightScreen(bool isEnable); ``` * 说明 * 用设置手表抬起时会自动亮屏,一般不建议设置,此功能可以在手表上自行设置。 * 示例 ```dart YcProductPlugin().setDeviceWristBrightScreen(true).then((value) { if (value?.statusCode == PluginState.succeed) { } else { } }); ``` ## 6.12 恢复出厂设置 * 方法 ```dart /// 恢复出厂设置 Future restoreFactorySettings(); ``` * 说明 * 调用此方法,手表会将数据全部清除后,自动重启。 * 示例 ```dart YcProductPlugin().restoreFactorySettings().then((value) { if (value?.statusCode == PluginState.succeed) { } else { } }); ``` ## 6.13 主题功能 * 方法 ```dart /// 表盘信息 class DeviceThemeInfo { /// 总数 int count = 0; /// 索引 int index = 0; @override String toString(); } /// 获取主题 Future?> queryDeviceTheme(); /// 设置主题 Future setDeviceTheme(int index); ``` * 说明 * 主题功能是指获取手表有哪几种显示的表盘样式、可以通过索引来设置,索引从0开始。 * 需要注意的是现在手表普遍使用的是表盘功能,使用此方法的场景很少。 * 示例 ```dart YcProductPlugin().queryDeviceTheme().then((value) { if (value?.statusCode == PluginState.succeed) { final info = value?.data as DeviceThemeInfo; YcProductPlugin().setDeviceTheme(info.count - 1).then((value) { if (value?.statusCode == PluginState.succeed) { } else { } }); } else { } }); ``` ## 6.14 健康监测 * 方法 ```dart /// 健康监测(心率监测) /// isEnable - 开关 /// interval - 1 ~ 60 min Future setDeviceHealthMonitoringMode({bool isEnable = true, int interval = 60}); @Deprecated("Use setDeviceHealthMonitoringMode") /// 温度监测 Future setDeviceTemperatureMonitoringMode({bool isEnable = true, int interval = 60}); ``` * 说明 * 健康监测只需要使用第一个方法,只有极个别设置会使用到第二个方法。 * 示例 ```dart YcProductPlugin().setDeviceHealthMonitoringMode().then((value) { if (value?.statusCode == PluginState.succeed) { } else { } }); ``` ## 6.15 报警设置 ### 6.15.1 心率报警 * 方法 ```dart /// 心率报警 FuturesetDeviceHeartRateAlarm({bool isEnable = true, int maxHeartRate = 100, int minHeartRate = 30}); ``` * 说明 * 最高心率报警范围是 100 ~ 240 * 最低心率报警直接指定 30 ~ 60 * 示例 ```dart YcProductPlugin().setDeviceHeartRateAlarm().then((value) { if (value?.statusCode == PluginState.succeed) { } else { } }); ``` ### 6.15.2 温度报警 * 方法 ```dart /// 温度报警 Future setDeviceTemperatureAlarm(bool isEnable, String maximumTemperature, String minimumTemperature); ``` * 说明 * 温度参数是浮点数的字符串,小数只支持0~9, 高度报警的范围是 36~100。 * 低温报警目前不支持。 * 设备功能标志 `isSupportTemperatureAlarm` 为true时,此功能才有效。 * 示例 ```dart YcProductPlugin().setDeviceTemperatureAlarm(true, "37.3", "33").then((value) { if (value?.statusCode == PluginState.succeed) { } else { } }); ``` ### 6.15.3 血氧报警 * 方法 ```dart /// 血氧报警 Future setDeviceBloodOxygenAlarm({bool isEnable = true, int minimum = 90}); ``` * 说明 * 当设备检查到血氧值低于设置的报警值时,设备会报警。 * 设备功能标志 `isSupportBloodOxygenAlarm` 为true时,此功能才有效。 * 示例 ```dart YcProductPlugin().setDeviceBloodOxygenAlarm().then((value) { if (value?.statusCode == PluginState.succeed) { } else { } }); ``` ### 6.15.4 呼吸率报警 * 方法 ```dart /// 呼吸率报警 Future setDeviceRespirationRateAlarm(bool isEnable, int maximum, int minimum); ``` * 说明 * 当设备检查到呼吸率没有超过这个范围时,设备会报警。 * 设备功能标志 `isSupportRespirationRateAlarm` 为true时,此功能才有效。 ### 6.15.5 血压报警 * 方法 ```dart /// 血压报警 Future setDeviceBloodPressureAlarm( bool isEnable, int maximumSystolicBloodPressure, int maximumDiastolicBloodPressure, int minimumSystolicBloodPressure, int minimumDiastolicBloodPressure); ``` * 说明 * 血压报警需要设置一具范围,当设备检查到的血压值不在设置的范围内时,设备将报警。 * 设备功能标志 `isSupportBloodPressureAlarm` 为true时,此功能才有效。 * 示例 ```dart // sbp 80 ~ 160, dbp: 60 ~ 120 YcProductPlugin().setDeviceBloodPressureAlarm(true, 160, 120, 80, 60).then((value) { if (value?.statusCode == PluginState.succeed) { } else { } }); ``` ## 6.16 睡眠提醒时间 * 方法 ```dart /// 设置睡眠提醒时间 Future setDeviceSleepReminder(bool isEnable, int hour, int minute, Setrepeat); ``` * 说明 * 设置睡前提醒,repeat表示周一到周日中哪天要提醒, 使用DeviceWeekDay成员。 * 设备功能标志 `isSupportSleepReminder` 为true时,此功能才有效。 * 示例 ```dart final Set week = {}; week.add(DeviceWeekDay.monday); week.add(DeviceWeekDay.tuesday); week.add(DeviceWeekDay.wednesday); week.add(DeviceWeekDay.thursday); week.add(DeviceWeekDay.friday); week.add(DeviceWeekDay.saturday); week.add(DeviceWeekDay.sunday); YcProductPlugin().setDeviceSleepReminder(true, 22, 30, week).then((value) { if value?.statusCode == PluginState.succeed) { } else { } }); ``` ## 6.17 消息提醒开关 * 方法 ```dart /// 通知开关(ANCS) /// items - DeviceInfoPushType 成员 Future setDeviceInfoPush(bool isEnable, Setitems); /// 通知类型 enum AndroidDevicePushNotificationType { call, sms, email, app, // 注意与 other 有相关的功能,取决于手表支持的固件。如果支持 other,则不使用此参数 qq, wechat, weibo, twitter, facebook, messenger, whatsAPP, linkedIn, instagram, skype, line, snapchat, declineCall, missedCall, telegram, viber, other } /// 消息推送 Android Future appPushNotifications(AndroidDevicePushNotificationType type, String title, String contents); ``` * 说明 * 通过不同的类型来设置手表可以显示接收到来自手机的来电、短信、微信、facebook等消息。 * 需要注意的是,这个功能在不同的平台是不一样的,在iOS端,需要将手表与系统蓝牙配对同时要允许通知。这是由于在iOS端消息推送是由ANCS服务实现的。 * 对于Android端,没有类似的服务,是要由App自行获取到通知道然后通过API下发到手表中。 * 示例 ```dart final Set items = {}; items.add(DeviceInfoPushType.call); items.add(DeviceInfoPushType.sms); items.add(DeviceInfoPushType.wechat); items.add(DeviceInfoPushType.qq); YcProductPlugin().setDeviceInfoPush(true, items).then((value) { if (value?.statusCode == PluginState.succeed) { } else { } }); // Android YcProductPlugin().appPushNotifications(AndroidDevicePushNotificationType.wechat, "你好", "吃了吗?").then((value) { if (value?.statusCode == PluginState.succeed) { } else { } }); ``` # 7. 控制设备 ## 7.1 找设备 * 方法 ```dart /// 找设备 Future findDevice({int remindCount = 5, int remindInterval = 1}); ``` * 说明 * 调用方法后,设备会有震动提示。 * 建议使用默认参数,不作修改。 * 示例 ```dart YcProductPlugin().findDevice().then((value) { if (value?.statusCode == PluginState.succeed) { } else { } }); ``` ## 7.2 关机、重启 * 方法 ```dart /// 设备操作 enum DeviceSystemOperator { shutDown, transportation, resetRestart, } /// 关机、复位、重启 Future deviceSystemOperator(DeviceSystemOperator operator); ``` * 说明 * 如果使用了复位,设备中的数据将会被清除。 * 如果进入了运输模式,则只以使用充电激活,手表键是没有反应的。 * 示例 ```dart YcProductPlugin().deviceSystemOperator(DeviceSystemOperator.shutDown).then((value) { if (value?.statusCode == PluginState.succeed) { } else { } }); ``` ## 7.3 血压校准 * 方法 ```dart /// 血压校准 Future bloodPressureCalibration(int systolicBloodPressure, int diastolicBloodPressure); ``` * 说明 * 对于光电血压测量出现偏差时,可以使用此方法进行校准。 * 示例 ```dart YcProductPlugin().bloodPressureCalibration(120, 80).then((value) { if (value?.statusCode == PluginState.succeed) { } else { } }); ``` ## 7.4 温度校准 * 方法 ```dart /// 温度校准 Future temperatureCalibration(); ``` * 说明 * 此功能只对于有两组温度传感器的精准体温功能才有效,其它产品则不起作用。该方法在开发中不常见。 * 示例 ```dart YcProductPlugin().temperatureCalibration().then((value) { if (value?.statusCode == PluginState.succeed) { } else { } }); ``` ## 7.5 血糖标定 * 方法 ```dart /// 血糖标定模式 enum DeviceBloodGlucoseCalibrationaMode { beforeMeal, afterMeal } /// 血糖标定 Future bloodGlucoseCalibration(DeviceBloodGlucoseCalibrationaMode mode, String value); ``` * 方法 * 血糖标定是用于校准血糖测量的数据。 * 血糖单位是 mmol/L * 示例 ```dart YcProductPlugin().bloodGlucoseCalibration(DeviceBloodGlucoseCalibrationaMode.afterMeal, "7.2").then((value) { if (value?.statusCode == PluginState.succeed) { } else { } }); ``` ## 7.6 尿酸标定 * 方法 ```dart /// 尿酸标定 /// uricAcid - umol/L Future uricAcidCalibration(int uricAcid); ``` * 说明 * 尿酸标定是用于校准尿酸测量的数据。 * 尿酸单位是 umol/L * 示例 ```dart YcProductPlugin().uricAcidCalibration(800).then((value) { if (value?.statusCode == PluginState.succeed) { } else { } }); ``` ## 7.7 血脂标定 * 方法 ```dart /// 血脂校准 /// cholesterol 胆固醇 - mmol/L Future bloodFatCalibration(String cholesterol); ``` * 说明 * 血脂标定是用于校准尿酸测量的数据。 * 血脂单位是 mmol/L * 示例 ```dart YcProductPlugin().bloodFatCalibration("5.6").then((value) { if (value?.statusCode == PluginState.succeed) { } else { } }); ``` ## 7.8 天气 * 方法 ```dart /// 天气类型 enum DeviceWeatherType { unKnow, sunny, cloudy, wind, rain, snow, foggy, } /// 发送天气 Future sendTodayWeather(DeviceWeatherType weatherType, int lowestTemperature, int highestTemperature, int realTimeTemperature); /// 发送明日天气 Future sendTomorrowWeather(DeviceWeatherType weatherType, int lowestTemperature, int highestTemperature, int realTimeTemperature); ``` * 说明 * 天气有今天气和明天天气,参数是相同,天气数据来源于天气服务商。 * 温度单位是摄氏温度。 * 明日天气的实时温度是不显示的,可以给任何值,建议给0或当天的实时温度。 * 示例 ```dart // 今天 下雪 -20 ~ 18 当前 12 YcProductPlugin().sendTodayWeather(DeviceWeatherType.snow, -20, 18, 12).then((value) { if (value?.statusCode == PluginState.succeed) { } else { } }); // 明天 16 ~ 33 YcProductPlugin().sendTomorrowWeather(DeviceWeatherType.sunny, 16, 33, 0).then((value) { if (value?.statusCode == PluginState.succeed) { } else { } }); ``` ## 7.9 名片 * 方法 ```dart /// 名片类型 class DeviceBusinessCardType { static const int wechat = 0; static const int qq = 1; static const int facebook = 2; static const int twitter = 3; static const int whatsApp = 4; static const int instagram = 5; static const int snCode = 0xF0; static const int staticCode = 0xF1; static const int dynamicCode = 0xF2; } /// 名片下发 /// type - DeviceBusinessCardType Future sendBusinessCard(int type, String contents); /// 查询名片 /// type - DeviceBusinessCardType Future queryBusinessCard(int type); ``` * 说明 * 目前只有杰理平台的设备支持此功能。 * 只有部分设置支持查询名片,对于类型中的snCode、staticCode、dynamicCode三种类型,只有个别定制设备才支持。 ```dart // 查询名片 YcProductPlugin().queryBusinessCard(DeviceBusinessCardType.wechat).then((value) { if (value?.statusCode == PluginState.succeed) { final info = value?.data ; } else { } }); // 设置名片 YcProductPlugin().sendBusinessCard(DeviceBusinessCardType.wechat, "https://me.wechat/xxxx").then((value) { if (value?.statusCode == PluginState.succeed) { } else { } }); ``` ## 7.10 拍照 * 方法 ```dart /// 控制设备进入或退出拍照 Future appControlTakePhoto(bool isEnable); /// 拍照状态变化 enum DeviceControlPhotoState { exit, // 设备退出拍照 enter, // 设备进入拍照 photo, // 设备执行拍照 } /// 拍照状态变化 NativeEventType.deviceControlPhotoStateChange ``` * 说明 * 拍照有两种模式,一种是由手机启动或退出,一种是由设备本身启动或退出。 * 执行拍照动作也有两种方式,一种是手机执行拍照,不需要做任何的蓝牙指令操作,另一个种是在设备上操作,由手机来响应这个指令。 * 举例 ```dart YcProductPlugin().onListening((event) { if (event.keys.contains(NativeEventType.deviceControlPhotoStateChange)) { final int index = event[NativeEventType.deviceControlPhotoStateChange]; final state = DeviceControlPhotoState.values[index]; debugPrint("Device photo ${state.toString()}"); } }); /// 手机启动拍照 YcProductPlugin().appControlTakePhoto(true). then((value) { if (value?.statusCode == PluginState.succeed) { } else { } }); /// 手机退出拍照 YcProductPlugin().appControlTakePhoto(false). then((value) { if (value?.statusCode == PluginState.succeed) { } else { } }); ``` ## 7.11 运动 * 方法 ```dart /// 控制运动 Future appControlSport(DeviceSportState state, int sportType); /// 运动状变化 NativeEventType.deviceSportStateChange; /// 运动状态 enum DeviceSportState { stop, // 停止 start, // 开始 pause, // 暂停 continueSport, // 继续 } /// 运动数据 NativeEventType.deviceRealSport; /// 运动类型定义 class DeviceSportType { static const int none = 0; // 保留 static const int run = 0x01; // 跑步 (户外) static const int swimming = 0x02; // 游泳 static const int riding = 0x03; // 户外骑行 static const int fitness = 0x04; // 健身 static const int ropeskipping = 0x06; // 跳绳 static const int playball = 0x07; // 篮球(打球) static const int walk = 0x08; // 健走 static const int badminton = 0x09; // 羽毛球 static const int football = 0x0A; // 足球 static const int mountaineering = 0x0B; // 登山 static const int pingPang = 0x0C; // 乒乓球 static const int freeMode = 0x0D; // 自由模式 static const int indoorRunning = 0x0E; // 室内跑步 static const int outdoorRunning = 0x0F; // 户外跑步 static const int outdoorWalking = 0x10; // 户外步行 static const int indoorWalking = 0x11; // 室内步行 static const int runMode = 0x12; // 走跑模式 static const int indoorRiding = 0x13; // 室内骑行 static const int stepper = 0x14; // 踏步机 static const int rowingMachine = 0x15; // 划船机 static const int realTimeMonitoring = 0x16; // 实时监护 static const int situps = 0x17; // 仰卧起坐 static const int jumping = 0x18; // 跳跃运动 static const int weightTraining = 0x19; // 重量训练 static const int yoga = 0x1A; // 瑜伽 static const int onfoot = 0x1B; // 徒步 static const int volleyball = 0x1C; // 排球 static const int kayak = 0x1D; // 皮划艇 static const int rollerSkating = 0x1E; // 轮滑 static const int tennis = 0x1F; // 网球 static const int golf = 0x20; // 高尔夫 static const int ellipticalMachine = 0x21; // 椭圆机 static const int dance = 0x22; // 舞蹈 static const int rockClimbing = 0x23; // 攀岩 static const int aerobics = 0x24; // 健身操 static const int otherSports = 0x25; // 其它运动 } ``` * 运动 * 这里的运动指的是由App启动设备进入实时运动状态。手表会将产生的数据返回,手表不会存储运动记录。 * 一般的设备只有开始和结束,只有`isSupportSportPause`为true时,才支持暂停与继续运动。 * 举例 ```dart YcProductPlugin().onListening((event) { // 实时运动 final Map? sportInfo = event[NativeEventType.deviceRealSport]; if (sportInfo != null) { // time 运动时间 // heartRate 运动心率 // distance 距离 // step 步数 // calories 千卡 } final Map? sportStateInfo = event[NativeEventType.deviceSportStateChange]; if (sportStateInfo != null) { // state 运动状态 // sportType 运动类型 } }); )} // 开始跑步 YcProductPlugin().appControlSport(DeviceSportState.start, DeviceSportType.run).then((value) { if (value?.statusCode == PluginState.succeed) { } else { } }); // 结束跑步 YcProductPlugin().appControlSport(DeviceSportState., DeviceSportType.run).then((value) { if (value?.statusCode == PluginState.succeed) { } else { } }); ``` ## 7.12 ECG ### 7.12.1 启动与停止ECG * 方法 ```dart /// 开启ECG测量 Future startECGMeasurement(); /// 结束ECG测量 Future stopECGMeasurement(); ``` * 说明 * 建议测量时长为60秒 * 示例 ```dart YcProductPlugin().startECGMeasurement().then((value) { if (value?.statusCode == PluginState.succeed) { } else { } }); // 停止测量 YcProductPlugin().stopECGMeasurement().then((value) { }); ``` ### 7.12.2 获取ECG实时数据 * 方法 ```dart /// 实时ECG NativeEventType.deviceRealECGData; /// 实时血压(包含心率和HRV) NativeEventType.deviceRealBloodPressure; ``` * 说明 * 测量过程中会产生实时的ECG数据、心率、血压和HRV,部分设备可能会携带PPG数据。 * 实时ECG数据可以用来绘制ECG图形。 * 示例 ```dart YcProductPlugin().onListening((event) { final ecgData = event[NativeEventType.deviceRealECGData]; if (ecgData != null) { // debugPrint("实时ECG: ${ecgData.toString()}"); } // final ppgData = event[NativeEventType.deviceRealECGData]; // if (ppgData != null) { // debugPrint("实时PPG: ${ppgData.toString()}"); // } final bloodMap = event[NativeEventType.deviceRealBloodPressure]; if (bloodMap != null) { debugPrint("实时血压: ${bloodMap.toString()}"); } }); ``` ### 7.12.3 获取ECG诊断结果 * 方法 ```dart /// ECG诊断结果 class DeviceECGResult { int hearRate = 0; int qrsType = 0; bool afFlag = false; double? heavyLoad; double? pressure; double? body; double? hrvNorm; double? sympatheticActivityIndex; int? respiratoryRate; @override String toString(); } /// 获取ECG的结果 Future?> getECGResult(); ``` * 说明 * 诊断结果中的三个参数用于判断心电的诊断结果。 * 对于诊断结果中用到的心率和HRV,如果设备主动上报了,则优先使用设备上报的数据,否则通过结果获取。 * 诊断结果可遵循如下原则: * 1. 优先判断 afFlag, 如果 afFlag 为 true, 则表示为心房颤动,其它参数不需要判断。 * 2. 如果 afFlag 为 false则判断 qrsType的类型,qrsType的类型。如下: * qrsType == 14,测量失败 * qrsType == 5, 室性早搏 * qrsType == 9, 房性早搏 * qrsType == 1,需要判断心率和hrv * hearRate <= 50, 疑似心动过缓 * hearRate >= 120, 疑似心动过速 * hrv >= 125, 疑似窦性心律不齐 * 以上条件都不成立,则为正常心电图。 * 示例 ```dart YcProductPlugin().getECGResult().then((value) { PluginResponse info = value as PluginResponse; // 依据 }); ``` ## 7.13 实时数据上传 * 方法 ```dart /// 设备实时数据类型 (除了step,其它类型一般不需要使用) enum DeviceRealTimeDataType { step, heartRate, bloodOxygen, bloodPressure, hrv, respirationRate, sportMode, combinedData, } /// 控制实时数据上传 Future realTimeDataUpload(bool isEnable, {DeviceRealTimeDataType dataType = DeviceRealTimeDataType.step}); ``` * 说明 * 参数类型中,除了step,其它参数一般不使用,step参数主要是用于直接获取手表上的当天实时计步信息。 * 示例 ```dart YcProductPlugin().onListening((event) { if (event.keys.contains(NativeEventType.deviceRealStep)) { final stepInfo = event[NativeEventType.deviceRealStep]; debugPrint('步数变化: $stepInfo'); } }); YcProductPlugin().realTimeDataUpload(true).then((value) { if (value?.statusCode == PluginState.succeed) { } else { } }); ``` # 8. 表盘操作 > 如果固件使用的是52832或8762d平台,则使用的玉成表盘,如果使用的是杰理平台则为杰理表盘。 ## 8.1 玉成表盘 ### 8.1.1 查询表盘信息 * 方法 ```dart /// 查询信息 Future>?> queryWatchFaceInfo(); /// 表盘信息 class DeviceWatchInfo { /// 表盘id int dialID; /// 版本,保留参数 int version; /// 表盘包数 int blockCount; /// 是否可以删除(非预置表盘) bool isSupportDelete; /// 是否为自定义表盘 bool get isCustomDial; /// 是否为当前表盘 bool get isCurrentDial; /// 最大允许表盘数 (包含可以下载的表盘和自定义表盘,不包含预置表盘。) int limitCount = 0; /// 当前已安装数 (包含可以下载的表盘和自定义表盘,不包含预置表盘。) int localCount = 0; @override String toString(); } ``` * 说明 * 使用此方法,可以查询当前手表中存储的表盘信息。 * 如果表盘中的`isCurrentDial`为 `true`说明此表盘是当前正在显示的表盘。 * 如果表盘中的`isSupportDelete为`true`说明此表盘可以删除,可以重新安装,否则不能删除。 * 如果表盘中的`isCustomDial`为`true`说明此表盘允许用户修改时间位置、颜色、背景图片。 * 可以通过`limitCount`的数量来判断手表允许安装几个表盘,`localCount`则表示当前已经安装且可以删除的表盘数量。 * 示例 ```dart YcProductPlugin().queryWatchFaceInfo().then((result) { if (result?.statusCode == PluginState.succeed) { final list = result?.data ?? []; for (var item in list) { debugPrint(item.toString()); } } else { debugPrint("Not support"); } }); ``` ### 8.1.2 设置表盘 * 方法 ```dart FuturechangeWatchFace(int dialID); ``` * 说明 * 通过dialID可以直接切换表盘,但这个表盘必须已经存在于手表,否则会失败。 * 示例 ```dart YcProductPlugin().changeWatchFace(185).then((result) { if (result?.statusCode == PluginState.succeed) { debugPrint("succeed"); } else { debugPrint("failed"); } }); ``` ### 8.1.3 删除表盘 * 方法 ```dart FuturedeleteWatchFace(int dialID); ``` * 说明 * 通过dialID可以直接删除表盘,但这个表盘必须已经存在于手表,否则会失败。 * 此方法只对可以删除的表盘有效,对于预置表盘无效。 * 示例 ```dart YcProductPlugin().deleteWatchFace(306).then((result) { if (result?.statusCode == PluginState.succeed) { debugPrint("succeed"); } else { debugPrint("failed"); } }); ``` ### 8.1.4 下载表盘 * 方法 ```dart /// 下载表盘 FutureinstallWatchFace(bool isEnable, int dialID, int blockCount, int dialVersion, String filePath, ProcessCallback processCallback); ``` * 说明 * isEnable 为`true`则表示启动下载, 否则表示停止下载。 * dialID 为 表盘的编号 * blockCount 为表盘已下载的包数,可以通过查询表盘信息获得,建议使用0,表示从头开始下载。 * dialVersion 是表盘版本,暂时没有,可以给任意数字。 * filePath 表盘文件的绝对路径 * processCallback 表盘的下载路径。 * 示例 ```dart final documentsDirectory = await getApplicationDocumentsDirectory(); final documentsPath = documentsDirectory.path; String filePath = "assets/files/E300H1.bin"; String destinationPath = '$documentsPath/E300H1.bin'; ByteData data = await rootBundle.load(filePath); List bytes = data.buffer.asUint8List(); // 写入到App目录下 File(destinationPath).writeAsBytes(bytes).then((value) { // 下载表盘 YcProductPlugin().installWatchFace(true, 306, 0, 0, destinationPath, (code, process, errorString) { debugPrint("Upgrading ${(process * 100).toInt()}%"); }).then((result) { if (result?.statusCode == PluginState.succeed) { debugPrint("succeed"); } else { debugPrint("failed"); } }); }); ``` ### 8.1.5 自定义表盘 * 方法 ```dart /// 自定义表盘的缩略图信息 class DeviceCustomWatchFaceDataInfo { /// 表盘宽度 (像素) int width = 0; /// 表盘高度 (像素) int height = 0; /// 表盘大小 (字节数) int size = 0; /// 表盘圆角半径 (像素) int radius = 0; /// 表盘缩略图宽度 (像素) int thumbnailWidth = 0; /// 表盘缩略图高度 (像素) int thumbnailHeight = 0; /// 表盘缩略大小 (字节数) int thumbnailSize = 0; /// 表盘缩略图半径 (像素) int thumbnailRadius = 0; DeviceCustomWatchFaceDataInfo.fromMap(Map map); @override String toString(); } /// 获取自定义表盘的参数 Future?>queryDeviceCustomWatchFaceInfo(String filePath); /// 下载自定义表盘 Future? installCustomWatchFace(int dialID, String filePath, String backgroundImage, String thumbnail, int timeX, int timeY, int redColor, int greenColor, int blueColor, ProcessCallback processCallback); ``` * 说明 * 要先查询到对应的参数,进行图片转换后,再下载到手中。 * 示例 ```dart final documentsDirectory = await getApplicationDocumentsDirectory(); final documentsPath = documentsDirectory.path; // debugPrint("目标地址: $documentsPath"); // 表盘文件 String filePath = "assets/files/customE88E.bin"; ByteData data = await rootBundle.load(filePath); List bytes = data.buffer.asUint8List(); // 目标路径 String destinationPath = '$documentsPath/customE88E.bin'; File(destinationPath).writeAsBytes(bytes).then((value) { debugPrint("写入成功 ${value.toString()}"); // 查询表盘信息 YcProductPlugin() .queryDeviceCustomWatchFaceInfo(destinationPath) .then((result) async { if (result?.statusCode == PluginState.succeed) { final dialInfo = result?.data; // 写入图片 由尺寸大小压缩得到 String bgPath = "assets/images/2147483615.png"; ByteData bgImageData = await rootBundle.load(bgPath); List bgImageBytes = bgImageData.buffer.asUint8List(); String bgImageDestinationPath = "$documentsPath/2147483615.png"; File(bgImageDestinationPath).writeAsBytes(bgImageBytes).then((value) async { String thumbnailPath = "assets/images/2147483615_thumbnail.png"; ByteData thumbnailImageData = await rootBundle.load(thumbnailPath); List thumbnailImageBytes = thumbnailImageData.buffer.asUint8List(); String thumbnailImageDestinationPath = "$documentsPath/thumbnail.png"; File(thumbnailImageDestinationPath).writeAsBytes(thumbnailImageBytes).then((value) { int dialID = 2147483615; int timeX = (dialInfo?.width ?? 0) ~/ 4; int timeY = (dialInfo?.height ?? 0) ~/ 2; YcProductPlugin().installCustomWatchFace(dialID, destinationPath, bgImageDestinationPath, thumbnailImageDestinationPath, timeX, timeY, 255, 0, 0, (code, process, errorString) { debugPrint("Upgrading ${(process * 100).toInt()}%"); })?.then((result) { if (result?.statusCode == PluginState.succeed) { debugPrint("succeed"); } else { debugPrint("failed"); } }); }); }); } else { debugPrint("Not support"); } }); }); ``` ### 8.1.6 表盘切换 * 方法 ```dart NativeEventType.deviceWatchFaceChange; ``` * 说明 * 通过全局监听,可以获取手表切换的表盘id。 * 示例 ```dart YcProductPlugin().onListening((event) { if (event.keys.contains(NativeEventType.deviceWatchFaceChange)) { int dialId = event[NativeEventType.deviceWatchFaceChange]; } }); ``` ## 8.2 杰理表盘 ### 8.2.1 查询表盘 * 和玉成表盘是相同的,手表的名称在服务器端与杰理工具配置相同。表盘名称与设置表盘相同。 ### 8.2.2 设置表盘 * 方法 ```dart FuturechangeJieLiWatchFace(String watchName); ``` * 说明 * 通过指定手表名称来进行切换表盘。如果该表盘不存在,则会出错。 * 示例 ```dart YcProductPlugin().changeJieLiWatchFace("WATCH1").then((result) { if (result?.statusCode == PluginState.succeed) { debugPrint("succeed"); } else { debugPrint("failed"); } }); ``` ### 8.2.3 删除表盘 * 方法 ```dart FuturedeleteJieLiWatchFace(String watchName); ``` * 说明 * 通过指定手表名称来删除表盘。如果该表盘不存在,则会出错。 * 示例 ```dart YcProductPlugin().deleteJieLiWatchFace("watch28").then((result) { if (result?.statusCode == PluginState.succeed) { debugPrint("succeed"); } else { debugPrint("failed"); } }); ``` ### 8.2.4 下载表盘 * 方法 ```dart FutureinstallJieLiWatchFace(String watchName, String filePath, ProcessCallback processCallback); ``` * 说明 * watchName 是表盘名称 * filePath 表盘文件在手机中的存储绝对路径 * processCallback 安装进度。 * 示例 ```dart YcProductPlugin().installJieLiWatchFace(watchName, destinationPath, (code, process, errorString) { EasyLoading.showProgress(process, debugPrint("Upgrading ${(process * 100).toInt()}%"); }).then((result) { if (result?.statusCode == PluginState.succeed) { debugPrint("succeed"); } else { debugPrint("failed"); } }); ``` ### 8.2.5 下载自定义表盘 * 方法 ```dart /// 屏幕类型 enum DeviceScreenType { round, // 圆形 square // 方法 } /// 设备显示信息 class DeviceDisplayParametersInfo { /// 屏幕类型 DeviceScreenType screenType = DeviceScreenType.round; /// 宽度(像素) int widthPixels = 0; /// 高度(像素) int heightPixels = 0; /// 圆角半径 (像素) int filletRadiusPixels = 0; /// 缩略图宽度 (像素) int thumbnailWidthPixels = 0; /// 缩略图高度 (像素) int thumbnailHeightPixels = 0; /// 缩略图半径 (像素) int thumbnailRadiusPixels = 0; /// 构造 DeviceDisplayParametersInfo.fromMap(Map map); @override String toString(); } Future?>queryDeviceDisplayParametersInfo(); /// 下载杰理自定义表盘 /// watchName 表盘名称 如 watch900 /// backgroundPath 背景图片的绝对路径 /// backgroundImageWidth/backgroundImageHeight 背景图片的宽/高 /// thumbnailPath 缩略图的绝对路径 /// thumbnailWidth/thumbnailHeight 缩略图的大小 /// DeviceWatchFaceTimePosition - 时间显示位置 /// timeTextColor 时间文字颜色 - RGB565 /// processCallback 安装进度条 Future installJieLiCustomWatchFace( String watchName, String backgroundPath, String thumbnailPath, DeviceWatchFaceTimePosition timePosition, int timeTextColor, DeviceDisplayParametersInfo info, ProcessCallback processCallback); ``` * 说明 * queryDeviceDisplayParametersInfo 可以查询手表的显示屏参数,用于背景图和缩略图片的大小设置。 * 切换好图片后,通过installJieLiCustomWatchFace方法下载到手表中,颜色参数注意是RGB565, 转换方法在工具类中已提供。 * 示例 ```dart YcProductPlugin().queryDeviceDisplayParametersInfo().then((result) async { if (result?.statusCode != PluginState.succeed) { return; } final parametersInfo = result?.data; // 依据 parametersInfo 的图片,进行将图片进行转换为相应尺寸、圆角的两张图片,这里不演示直接得到对应的。 // 写入图片 final documentsDirectory = await getApplicationDocumentsDirectory(); final documentsPath = documentsDirectory.path; String bgPath = "assets/images/2147483615.png"; ByteData bgImageData = await rootBundle.load(bgPath); List bgImageBytes = bgImageData.buffer.asUint8List(); String bgImageDestinationPath = "$documentsPath/background.png"; // 写入手表 File(bgImageDestinationPath) .writeAsBytes(bgImageBytes) .then((value) async { String thumbnailPath = "assets/images/2147483615_thumbnail.png"; ByteData thumbnailImageData = await rootBundle.load(thumbnailPath); List thumbnailImageBytes = thumbnailImageData.buffer.asUint8List(); String thumbnailImageDestinationPath = "$documentsPath/thumbnail.png"; File(thumbnailImageDestinationPath) .writeAsBytes(thumbnailImageBytes) .then((value) { // 准备转换图片 // BGP_W900 YcProductPlugin().installJieLiCustomWatchFace( "watch900", bgImageDestinationPath, thumbnailImageDestinationPath, DeviceWatchFaceTimePosition.bottom, YcProductPluginTools.colorToRGB565( const Color.fromARGB(255, 255, 255, 255)), parametersInfo!, (code, process, errorString) { EasyLoading.showProgress(process, status: "Upgrading ${(process * 100).toInt()}%"); }).then((value) { if (result?.statusCode == PluginState.succeed) { debugPrint("succeed"); } else { debugPrint("failed"); } }); }); }); }); ``` ### 8.2.6 表盘切换 * 方法 ```dart NativeEventType.deviceJieLiWatchFaceChange; ``` * 说明 * 手表切换表盘后,手表的名称返回。 * *示例 ```dart YcProductPlugin().onListening((event) { if (event.keys.contains(NativeEventType.deviceJieLiWatchFaceChange)) { String watchName = event[NativeEventType.deviceJieLiWatchFaceChange]; setState(() { _displayedText = "Watch face change: $watchName"; }); } }); ``` # 9. OTA # 10. 其它