From 3541ed5c9a8a5d7eb380e4cfd258a8a606ce6a02 Mon Sep 17 00:00:00 2001 From: Fabrizio Bertoglio Date: Tue, 2 Sep 2025 17:21:13 +0200 Subject: [PATCH] feat: add Mi Band connector --- README.md | 10 +++++++ docs/miband.md | 14 ++++++++++ package.json | 3 ++ src/miband/MiBandConnector.ts | 43 +++++++++++++++++++++++++++++ src/miband/rn-miband-connector.d.ts | 1 + 5 files changed, 71 insertions(+) create mode 100644 docs/miband.md create mode 100644 src/miband/MiBandConnector.ts create mode 100644 src/miband/rn-miband-connector.d.ts diff --git a/README.md b/README.md index 70162de..5c9c64a 100644 --- a/README.md +++ b/README.md @@ -14,6 +14,7 @@ Allows you to connect React Native Mobile apps with WearOS. # Table of Contents - [Installation](#installation) +- [Mi Band Setup](#mi-band-setup) - [React Native API Documentation](#react-native-api-documentation) - [Jetpack Compose API Documentation](#jetpack-compose-api-documentation) - [How to run the example](#how-to-run-the-example) @@ -69,6 +70,15 @@ Add the following entry to your `android/app/src/main/AndroidManifest.xml` (full ``` +## Mi Band Setup + +To use a Mi Band with this library the band must first be paired with the +Android device through the official **Mi Fitness** (or **Zepp Life**) +application. Ensure Bluetooth is enabled and grant the app the required +permissions such as `BLUETOOTH_CONNECT`, `BLUETOOTH_SCAN` and +`ACCESS_FINE_LOCATION`. More details are available in +[docs/miband.md](docs/miband.md). + ## React Native API Documentation The example of implementation available in the [CounterScreen](example/src/CounterScreen/index.android.tsx). diff --git a/docs/miband.md b/docs/miband.md new file mode 100644 index 0000000..48f477d --- /dev/null +++ b/docs/miband.md @@ -0,0 +1,14 @@ +# Mi Band Setup + +To connect a Mi Band device with this library: + +1. Pair the band with your Android phone using the official **Mi Fitness** (or **Zepp Life**) application. +2. Ensure Bluetooth is enabled and the band is connected before launching your React Native app. +3. Grant the application the required permissions: + - `android.permission.BLUETOOTH_CONNECT` + - `android.permission.BLUETOOTH_SCAN` + - `android.permission.ACCESS_FINE_LOCATION` (required for Bluetooth Low Energy scanning on older Android versions) + - `android.permission.BODY_SENSORS` if accessing heart rate or other biometric data + - `android.permission.POST_NOTIFICATIONS` to receive notifications on recent Android versions + +Without pairing through the Mi Fitness application the device will not accept connections from third‑party apps. diff --git a/package.json b/package.json index 86167e0..80e13cf 100644 --- a/package.json +++ b/package.json @@ -85,6 +85,9 @@ "react": "*", "react-native": "*" }, + "dependencies": { + "rn-miband-connector": "^0.1.0" + }, "workspaces": [ "example", "watch-example" diff --git a/src/miband/MiBandConnector.ts b/src/miband/MiBandConnector.ts new file mode 100644 index 0000000..6abb10f --- /dev/null +++ b/src/miband/MiBandConnector.ts @@ -0,0 +1,43 @@ +import { EventEmitter } from 'events'; +import type { AddListener, WatchEvents } from '../types'; +// The rn-miband-connector library exposes an EventEmitter that +// delivers raw Mi Band events. We translate those events to the +// shared `watchEvents` interface used by this project. +// +// We keep the dependency typed as `any` to avoid requiring its +// TypeScript definitions. +// eslint-disable-next-line @typescript-eslint/no-var-requires +const MiBand: any = require('rn-miband-connector'); + +const miband = new MiBand(); +const emitter = new EventEmitter(); + +// Forward any event from the Mi Band library as a `message` event so +// that consumers can subscribe via `watchEvents.on('message', cb)`. +miband.on('data', (payload: unknown) => { + emitter.emit('message', payload); +}); + +// Some implementations might emit a generic `event` callback instead +// of `data`. Handle that as well. +miband.on('event', (payload: unknown) => { + emitter.emit('message', payload); +}); + +const addListener: AddListener = (event, cb) => { + if (event !== 'message') { + throw new Error(`Unknown watch event "${event}"`); + } + + emitter.on(event, cb); + return () => { + emitter.removeListener(event, cb); + }; +}; + +export const mibandEvents: WatchEvents = { + addListener, + on: addListener, +}; + +export default mibandEvents; diff --git a/src/miband/rn-miband-connector.d.ts b/src/miband/rn-miband-connector.d.ts new file mode 100644 index 0000000..6fe02da --- /dev/null +++ b/src/miband/rn-miband-connector.d.ts @@ -0,0 +1 @@ +declare module 'rn-miband-connector';