WeChat MiniProgram wx1b56c32a1e5c1714 rewritten as a native Android app using
Jetpack Compose + Material 3.
- Kotlin 2.3.20, AGP 9.0.1
- Jetpack Compose (BOM 2026.03.01) + Material 3
- Navigation 3 with typed keys (kotlinx.serialization)
- Coroutines + StateFlow for reactive state
- Min SDK 26, target SDK 36
app/src/main/java/com/example/flipclock/
├── MainActivity.kt # Entry point, sets up theme + navigation
├── Navigation.kt # NavDisplay wiring, shared BleManager
├── NavigationKeys.kt # @Serializable NavKeys (Home, AddClockKey)
├── theme/ # Material 3 color/typography/shape
├── data/
│ ├── Alarm.kt # Alarm entity + RepeatMode enum
│ └── DeviceState.kt # Aggregate device state + FeatureTab
├── ble/
│ ├── Opcodes.kt # Protocol constants transcribed 1:1 from JS
│ ├── BleCodec.kt # ByteArray packet builders
│ ├── BleManager.kt # Transport interface
│ └── FakeBleManager.kt # In-memory impl (decodes writes back onto state)
└── ui/
├── components/
│ ├── FlipClockDisplay.kt # Split-flap digit + HH:MM row
│ └── CommonCards.kt # FlipCard, NoticeBanner, SettingsRow
├── home/
│ ├── HomeScreen.kt # Scaffold, clock, status card, tabs
│ ├── HomeViewModel.kt # Bridges UI events to BleManager
│ ├── AlarmSection.kt # 闹钟
│ ├── TomatoSection.kt # 橘子时钟
│ ├── DrinkWaterSection.kt # 喝水提醒
│ ├── SoundSection.kt # 四档音量滑块
│ └── CalibrationSection.kt # 校时 / 主页展示 / 轮子偏移 / OTA
└── addclock/
└── AddClockScreen.kt # 新增 / 编辑 / 喝水闹钟
Every opcode and packet layout from the original MiniProgram is kept byte-for-byte
in ble/Opcodes.kt and ble/BleCodec.kt. Swap FakeBleManager for a real
BluetoothGatt-backed implementation and the UI keeps working unchanged.
| Opcode | Purpose | Payload |
|---|---|---|
| 0 | Set volume | byte channel + byte 0..100 |
| 2 | Sync time | uint32 epoch (LE) |
| 5 | Add / update alarm | 12-byte alarm struct |
| 6 | Delete alarm | uint32 alarmSn |
| 8 | Wheel offset | int8 left + int8 right |
| 9 / 10 | Enter / exit production | — |
| 11 | Close connection | — |
| 12 | Factory reset | — |
| 13 | Wipe a flap page | byte page |
| 34/35/37 | OTA header/chunk/commit | see BleManager.startOta |
cd android
./gradlew :app:assembleDebug # produces app/build/outputs/apk/debug/app-debug.apk
./gradlew :app:installDebug # deploy to connected device / emulatorOr open the android/ folder in Android Studio and hit ▶.
- Real BLE scan/connect/GATT pipeline (
BleManagerimplementation againstBluetoothLeScanner/BluetoothGatt). - OTA end-to-end wiring on the home screen (the codec is in place).
- DrinkWater "enable" switch + interval picker round-trip.
- Persist user preferences (DataStore) so state survives device disconnects.
- Runtime permission prompts for
BLUETOOTH_SCAN/BLUETOOTH_CONNECT.
The UI, theming, data models, and protocol encoders are complete and verified against the original MiniProgram source.