@blife/rn-step-counter 1.0.1 → 1.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -1,160 +1,230 @@
1
- # React-Native Step Counter Library
1
+ # @blife/rn-step-counter
2
2
 
3
3
  [![npm version](https://img.shields.io/npm/v/@blife/rn-step-counter.svg)](https://www.npmjs.com/package/@blife/rn-step-counter)
4
+ [![npm downloads](https://img.shields.io/npm/dm/@blife/rn-step-counter.svg)](https://www.npmjs.com/package/@blife/rn-step-counter)
5
+ [![license](https://img.shields.io/github/license/bonnmh/rn-step-counter)](https://github.com/bonnmh/rn-step-counter/blob/main/LICENSE)
4
6
 
5
- 한국어 사용자는 [Korean version.](README.kr.md)를 참조하십시오.
7
+ A React Native TurboModule for live step counting on iOS and Android.
6
8
 
7
- This library provides an interface for tracking the number of steps taken by the user in a React Native app. It uses the Android `StepCounter` sensor, an accelerometer fallback on Android devices without a step counter sensor, and Apple's `Core Motion` framework on iOS.
9
+ - **npm:** [@blife/rn-step-counter](https://www.npmjs.com/package/@blife/rn-step-counter)
10
+ - **Source:** [github.com/bonnmh/rn-step-counter](https://github.com/bonnmh/rn-step-counter)
11
+
12
+ ## Features
13
+
14
+ - **iOS** — Core Motion (`CMPedometer`) with floors ascended/descended when available
15
+ - **Android** — Hardware step counter (`TYPE_STEP_COUNTER`) with accelerometer fallback
16
+ - **New Architecture** — TurboModule / Fabric (required)
17
+ - **Live updates** — Event-based API with start/stop lifecycle
18
+ - **Historical query (iOS)** — `queryPedometerDataBetweenDates()` for cumulative steps in a date range
19
+ - **Native events** — Optional listeners for errors, sensor metadata, and step detection
20
+ - **Optional filtering** — `createStepCountFilter()` reduces false positives from rapid motion
21
+ - **Utilities** — `parseStepData()` for display-friendly formatting
22
+
23
+ ## Requirements
24
+
25
+ | | |
26
+ |---|---|
27
+ | React Native | `>= 0.71.0` |
28
+ | Architecture | New Architecture (TurboModules) |
29
+ | Expo | Not supported in Expo Go (native module) |
30
+ | Autolinking | React Native 0.60+ |
8
31
 
9
32
  ## Installation
10
33
 
11
- ```shell
34
+ ```bash
12
35
  npm install @blife/rn-step-counter
13
36
  ```
14
37
 
15
- ```shell
38
+ ```bash
39
+ yarn add @blife/rn-step-counter
40
+ # or
41
+ pnpm add @blife/rn-step-counter
42
+ # or
16
43
  bun add @blife/rn-step-counter
17
44
  ```
18
45
 
19
- Native modules will automatically connect after React Native 0.60 version. So you don't need to link the native modules manually.
46
+ Rebuild the native app after installing:
20
47
 
21
- ## Requirements
48
+ ```bash
49
+ # iOS
50
+ cd ios && pod install && cd ..
22
51
 
23
- - React Native `>=0.71.0`
24
- - React Native CLI apps. Expo Go is not supported because this package includes native code.
52
+ # Android / iOS
53
+ npx react-native run-android
54
+ npx react-native run-ios
55
+ ```
25
56
 
26
- ### ANDROID
57
+ ## Platform setup
27
58
 
28
- Add the motion permission and sensor feature declarations if your app does not already include them.
59
+ ### Android
60
+
61
+ Add permissions and sensor features to your app manifest if they are not already present:
29
62
 
30
63
  ```xml
31
- <!-- android/src/main/AndroidManifest.xml-->
32
- <manifest xmlns:android="http://schemas.android.com/apk/res/android"
33
- package="com.stepcounter">
34
- <uses-permission android:name="android.permission.ACTIVITY_RECOGNITION" />
35
- <uses-permission android:name="android.permission.BODY_SENSORS_BACKGROUND" />
36
-
37
- <uses-feature
38
- android:name="android.hardware.sensor.stepcounter"
39
- android:required="false" />
40
- <uses-feature
41
- android:name="android.hardware.sensor.accelerometer"
42
- android:required="true" />
43
- </manifest>
64
+ <uses-permission android:name="android.permission.ACTIVITY_RECOGNITION" />
65
+
66
+ <uses-feature
67
+ android:name="android.hardware.sensor.stepcounter"
68
+ android:required="false" />
69
+ <uses-feature
70
+ android:name="android.hardware.sensor.accelerometer"
71
+ android:required="true" />
44
72
  ```
45
73
 
74
+ Request runtime permission before starting updates. The library reports permission status via `isStepCountingSupported()`.
75
+
46
76
  ### iOS
47
77
 
48
- Add `NSMotionUsageDescription` to your app's `Info.plist`.
78
+ Add a motion usage description to your app's `Info.plist`:
49
79
 
50
- ```xml plist
51
- <!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN">
52
- <plist version="1.0">
53
- ...
54
- <key>NSMotionUsageDescription</key>
55
- <string>We want to access your motion data to count your steps.</string>
56
- ...
57
- </plist>
80
+ ```xml
81
+ <key>NSMotionUsageDescription</key>
82
+ <string>This app uses motion data to count your steps.</string>
58
83
  ```
59
84
 
60
- ## Interface
85
+ ## Quick start
61
86
 
62
- - `isStepCountingSupported()`: `Promise<{ supported: boolean; granted: boolean }>`: method to check if the device has a feature related step counter or accelerometer.
63
- - One key for the response object is `granted`, whether the app user has granted this feature permission, and `supported` is whether the device supports this feature.
64
- - Android can fall back to accelerometer-based counting when the hardware step counter is unavailable. You should still request and respect the platform motion/activity permission before starting updates.
87
+ ```tsx
88
+ import { useEffect, useState } from "react";
89
+ import {
90
+ createStepCountFilter,
91
+ isStepCountingSupported,
92
+ parseStepData,
93
+ startStepCounterUpdate,
94
+ stopStepCounterUpdate,
95
+ } from "@blife/rn-step-counter";
65
96
 
66
- - `startStepCounterUpdate(start: Date, callBack: StepCountUpdateCallback)`: `EventSubscription`:
67
- - If the pedometer sensor is available and supported on the device, register it with the listener in the sensor manager, and return the step count event listener.
68
- - If the pedometer sensor is not supported by the device or is not available, register the accelerometer sensor with the listener, generate an accel event through a vector algorithm filter and receive it to the app.
97
+ export function StepCounterScreen() {
98
+ const [steps, setSteps] = useState(0);
69
99
 
70
- - `stopStepCounterUpdate(): void`:
71
- - Removes the subscription registered by `startStepCounterUpdate` and stops the native sensor session.
100
+ useEffect(() => {
101
+ let active = true;
72
102
 
73
- - `createStepCountFilter(options?: StepCountFilterOptions)`: `(data: StepCountData) => StepCountData | null`:
74
- - Creates a stateful live-update filter for sensor false positives such as hand rotation.
75
- - The filter drops bursts that imply a cadence faster than `minimumStepIntervalMs` and rebases later cumulative values so ignored steps do not come back on the next accepted event.
76
- - Native hardware/OS pedometers can still report false positives before the package receives the event. Use this helper when your app needs stricter live-session counts than the raw sensor stream.
103
+ (async () => {
104
+ const { supported, granted } = await isStepCountingSupported();
105
+ if (!active || !supported || !granted) {
106
+ return;
107
+ }
77
108
 
78
- - `StepCountData`:
79
- - **Common Interface**
80
- - `steps`: This is a number property that indicates the number of steps taken by the user during the specified time period.
81
- - `startDate`: This is a number property that indicates the start date of the data in Unix timestamp format, measured in milliseconds.
82
- - `endDate`: This is a number property that indicates the end date of the data in Unix timestamp format, measured in milliseconds.
83
- - `distance`: This is a number property that indicates the distance in meters that the user has walked or run during the specified time period.
84
- - `counterType`: (`CounterType`) The name of the sensor used to count the number of steps. One of `"CMPedometer"` (iOS), `"STEP_COUNTER"` (Android hardware sensor), or `"ACCELEROMETER"` (Android fallback).
109
+ const filter = createStepCountFilter();
85
110
 
86
- - **iOS Only**
87
- - `floorsAscended`: This is a number property that indicates the number of floors the user has ascended during the specified time period. It can be nil if the device does not support this feature.
88
- - `floorsDescended`: This is a number property that indicates the number of floors the user has descended during the specified time period. It can be nil if the device does not support this feature.
111
+ startStepCounterUpdate(new Date(), (data) => {
112
+ const filtered = filter(data);
113
+ if (!filtered) {
114
+ return;
115
+ }
116
+ setSteps(filtered.steps);
117
+ });
118
+ })();
89
119
 
90
- ## Usage
120
+ return () => {
121
+ active = false;
122
+ stopStepCounterUpdate();
123
+ };
124
+ }, []);
91
125
 
92
- To use the Step Counter Library in your React Native app, follow these steps:
126
+ return null; // render your UI, e.g. parseStepData(...)
127
+ }
128
+ ```
93
129
 
94
- Import the library into your React Native app.
130
+ See the full example app: [`example/src/App.tsx`](./example/src/App.tsx).
95
131
 
96
- ```typescript
97
- import React, { useEffect, useState } from "react";
98
- import {
99
- createStepCountFilter,
100
- isStepCountingSupported,
101
- parseStepData,
102
- startStepCounterUpdate,
103
- stopStepCounterUpdate,
104
- } from "@blife/rn-step-counter";
105
- ```
132
+ ## API
106
133
 
107
- Use the `isStepCountingSupported` method to check if the device has a step counter or accelerometer sensor.
134
+ ### `isStepCountingSupported()`
108
135
 
109
- ```typescript
110
- const [supported, setSupported] = useState(false);
111
- const [granted, setGranted] = useState(false);
136
+ Returns `Promise<{ supported: boolean; granted: boolean; working?: boolean }>`.
112
137
 
113
- async function askPermission() {
114
- isStepCountingSupported().then((result) => {
115
- console.debug("🚀 - isStepCountingSupported", result);
116
- setGranted(result.granted === true);
117
- setSupported(result.supported === true);
118
- });
119
- }
138
+ - `supported` — device can count steps (hardware sensor or fallback)
139
+ - `granted` — required motion/activity permission has been granted
140
+ - `working` — Android only: whether the native sensor service is currently active
141
+
142
+ ### `queryPedometerDataBetweenDates(start, end)` (iOS only)
143
+
144
+ Queries cumulative step data for the given range using Core Motion. Returns `Promise<StepCountData>`.
145
+
146
+ Apple retains roughly seven days of pedometer history; older ranges may return partial data. Does not interfere with an active live session. On Android, throws `UnavailabilityError`.
147
+
148
+ ```tsx
149
+ import { queryPedometerDataBetweenDates } from "@blife/rn-step-counter";
150
+
151
+ const start = new Date();
152
+ start.setHours(0, 0, 0, 0);
153
+ const today = await queryPedometerDataBetweenDates(start, new Date());
120
154
  ```
121
155
 
122
- Call the `startStepCounterUpdate` method to start the step counter service.
156
+ ### `startStepCounterUpdate(start, callback)`
123
157
 
124
- ```typescript
125
- const [steps, setSteps] = useState(0);
158
+ Starts native step updates from `start` (JavaScript `Date`) and invokes `callback` with `StepCountData` on each event.
126
159
 
127
- async function startStepCounter() {
128
- const filterStepCountData = createStepCountFilter();
160
+ Returns an `EventSubscription`. Call `stopStepCounterUpdate()` to stop.
129
161
 
130
- startStepCounterUpdate(new Date(), (data) => {
131
- const filteredData = filterStepCountData(data);
132
- if (!filteredData) {
133
- return;
134
- }
162
+ ### `stopStepCounterUpdate()`
135
163
 
136
- console.debug(parseStepData(filteredData));
137
- setSteps(filteredData.steps);
138
- });
139
- }
164
+ Stops the active native session and removes the library's event subscription.
165
+
166
+ ### `isSensorWorking()`
167
+
168
+ Returns `true` when this library has an active subscription from `startStepCounterUpdate`. This reflects the JS-managed session, not Android's native `working` flag.
169
+
170
+ ### Event listeners
171
+
172
+ Subscribe to native events with the helpers below. Each returns an `EventSubscription`.
173
+
174
+ ```tsx
175
+ import {
176
+ addStepCounterErrorListener,
177
+ addStepsSensorInfoListener,
178
+ addStepDetectedListener,
179
+ } from "@blife/rn-step-counter";
180
+
181
+ const errorSub = addStepCounterErrorListener((error) => {
182
+ console.warn(error.message);
183
+ });
184
+ errorSub.remove();
140
185
  ```
141
186
 
142
- Here's an example of a complete React component that uses the `NativeStepCounter`.
187
+ - `addStepCounterErrorListener` `StepCounter.errorOccurred` (iOS Core Motion errors)
188
+ - `addStepsSensorInfoListener` — `StepCounter.stepsSensorInfo` (capability metadata; fired from `isStepCountingSupported` on iOS and when the Android sensor starts)
189
+ - `addStepDetectedListener` — `StepCounter.stepDetected` (motion detection signal)
143
190
 
144
- Link to Example Application: [here](https://github.com/bonnmh/rn-step-counter/blob/main/example/src/App.tsx)
191
+ ### `createStepCountFilter(options?)`
145
192
 
146
- ## Change Log
193
+ Returns a stateful filter function. Drops bursts that exceed the configured cadence (default: 250 ms per step) and rebases cumulative counts so ignored steps are not applied later.
147
194
 
148
- See the [`Release Notes`](CHANGELOG.md) for a list of changes.
195
+ ### `parseStepData(data)`
149
196
 
150
- ## Contributing
197
+ Formats raw `StepCountData` for display (steps, distance, time range, estimated calories, daily goal progress).
151
198
 
152
- See the [`Contributing Guide`](CONTRIBUTING.md) to learn how to contribute to the repository and the development workflow.
199
+ ### `StepCountData`
153
200
 
154
- ## License
201
+ | Field | Type | Description |
202
+ |-------|------|-------------|
203
+ | `steps` | `number` | Step count for the interval |
204
+ | `startDate` | `number` | Interval start (Unix ms) |
205
+ | `endDate` | `number` | Interval end (Unix ms) |
206
+ | `distance` | `number` | Distance in meters |
207
+ | `counterType` | `CounterType` | `"CMPedometer"` · `"STEP_COUNTER"` · `"ACCELEROMETER"` |
208
+ | `floorsAscended` | `number?` | iOS only |
209
+ | `floorsDescended` | `number?` | iOS only |
210
+ | `calories` | `number?` | Estimated calories when provided by native |
155
211
 
156
- MIT
212
+ ## Development
157
213
 
158
- ---
214
+ ```bash
215
+ bun install
216
+ bun run prepare
217
+ bun run test
218
+ bun run example:start # Metro
219
+ bun run example:ios # or example:android
220
+ ```
221
+
222
+ See [CONTRIBUTING.md](./CONTRIBUTING.md) for the full workflow.
223
+
224
+ ## Changelog
225
+
226
+ See [CHANGELOG.md](./CHANGELOG.md).
227
+
228
+ ## License
159
229
 
160
- Made with [create-react-native-library](https://github.com/callstack/react-native-builder-bob)
230
+ [MIT](./LICENSE)
package/android/README.md CHANGED
@@ -1,65 +1,56 @@
1
- # 안드로이드 기본센서 & 복합센서
1
+ # Android sensors
2
2
 
3
- - [안드로이드 동작 센서](https://developer.android.com/guide/topics/sensors/sensors_motion?hl=ko)
4
- - [안드로이드 센서 유형](https://source.android.com/docs/core/interaction/sensors/sensor-types?hl=ko)
3
+ Reference notes for the sensor types used by this library.
4
+
5
+ - [Motion sensors (Android Developers)](https://developer.android.com/guide/topics/sensors/sensors_motion)
6
+ - [Sensor types (AOSP)](https://source.android.com/docs/core/interaction/sensors/sensor-types)
5
7
 
6
8
  ## TYPE_ACCELEROMETER
7
9
 
8
- SensorEvent.values[0] x축의 가속력\(중력 포함). m/s2
9
- SensorEvent.values[1] y축의 가속력\(중력 포함). m/s2
10
- SensorEvent.values[2] z축의 가속력\(중력 포함). m/s2
10
+ | Index | Description |
11
+ |-------|-------------|
12
+ | `values[0]` | Acceleration on the X axis, including gravity (m/s²) |
13
+ | `values[1]` | Acceleration on the Y axis, including gravity (m/s²) |
14
+ | `values[2]` | Acceleration on the Z axis, including gravity (m/s²) |
11
15
 
12
- ## TYPE_ACCELEROMETER_UNCALIBRATED
16
+ Used by the accelerometer fallback when `TYPE_STEP_COUNTER` is unavailable.
13
17
 
14
- SensorEvent.values[0] 편향 보상 없이 X축을 따라 측정한 가속. m/s2
15
- SensorEvent.values[1] 편향 보상 없이 Y축을 따라 측정한 가속. m/s2
16
- SensorEvent.values[2] 편향 보상 없이 Z축을 따라 측정한 가속. m/s2
17
- SensorEvent.values[3] 추정된 편향 보상을 적용하여 X축을 따라 측정한 가속. m/s2
18
- SensorEvent.values[4] 추정된 편향 보상을 적용하여 Y축을 따라 측정한 가속. m/s2
19
- SensorEvent.values[5] 추정된 편향 보상을 적용하여 Z축을 따라 측정한 가속. m/s2
18
+ ## TYPE_STEP_COUNTER
20
19
 
21
- ## TYPE_GRAVITY
20
+ | Index | Description |
21
+ |-------|-------------|
22
+ | `values[0]` | Steps since last reboot while the sensor was active |
22
23
 
23
- SensorEvent.values[0] x축의 중력. m/s2
24
- SensorEvent.values[1] y축의 중력. m/s2
25
- SensorEvent.values[2] z축의 중력. m/s2
24
+ This is the preferred Android data source. The module converts cumulative counter readings into session step counts.
26
25
 
27
- ## TYPE_GYROSCOPE
26
+ ## TYPE_STEP_DETECTOR
28
27
 
29
- SensorEvent.values[0] x축을 중심으로 회전 속도. rad/s
30
- SensorEvent.values[1] y축을 중심으로 한 회전 속도. rad/s
31
- SensorEvent.values[2] z축을 중심으로 한 회전 속도. rad/s
28
+ Not used directly by this library. Step detection is handled in software when falling back to the accelerometer.
32
29
 
33
- ## TYPE_GYROSCOPE_UNCALIBRATED
30
+ ## TYPE_SIGNIFICANT_MOTION
34
31
 
35
- SensorEvent.values[0] x축을 중심으로 회전 속도\(드리프트 보상 없음). rad/s
36
- SensorEvent.values[1] y축을 중심으로 한 회전 속도\(드리프트 보상 없음). rad/s
37
- SensorEvent.values[2] z축을 중심으로 한 회전 속도\(드리프트 보상 없음). rad/s
38
- SensorEvent.values[3] x축을 중심으로 추정한 드리프트. rad/s
39
- SensorEvent.values[4] y축을 중심으로 추정한 드리프트. rad/s
40
- SensorEvent.values[5] z축을 중심으로 추정한 드리프트. rad/s
32
+ Not used by this library.
41
33
 
42
- ## TYPE_LINEAR_ACCELERATION
34
+ ## Other sensor types
43
35
 
44
- SensorEvent.values[0] x축의 가속력\(중력 제외). m/s2
45
- SensorEvent.values[1] y축의 가속력\(중력 제외). m/s2
46
- SensorEvent.values[2] z축의 가속력\(중력 제외). m/s2
36
+ The sections below are retained as general Android sensor reference material and are not required for integration.
47
37
 
48
- ## TYPE_ROTATION_VECTOR
38
+ ### TYPE_ACCELEROMETER_UNCALIBRATED
49
39
 
50
- SensorEvent.values[0] x축의 회전 벡터 구성요소\(x \* sin\(θ/2)). 단위 없음
51
- SensorEvent.values[1] y축의 회전 벡터 구성요소\(y \* sin\(θ/2)). 단위 없음
52
- SensorEvent.values[2] z축의 회전 벡터 구성요소\(z \* sin\(θ/2)). 단위 없음
53
- SensorEvent.values[3] 회전 벡터의 스칼라 구성요소\(\(cos\(θ/2)). 옵셔널.단위 없음
40
+ Six-axis uncalibrated accelerometer values (m/s²).
54
41
 
55
- ## TYPE_STEP_COUNTER
42
+ ### TYPE_GRAVITY
43
+
44
+ Gravity vector on X, Y, and Z axes (m/s²).
45
+
46
+ ### TYPE_GYROSCOPE / TYPE_GYROSCOPE_UNCALIBRATED
56
47
 
57
- SensorEvent.values[0] 센서가 활성화되어 있는 동안 마지막 재부팅 이후로 사용자가 걸은 걸음 수. 단위 보
48
+ Rotation rate around X, Y, and Z axes (rad/s).
58
49
 
59
- ### TYPE_SIGNIFICANT_MOTION
50
+ ### TYPE_LINEAR_ACCELERATION
60
51
 
61
- \(중요하거나 위험할 있는 활동 감지) 해당 없음
52
+ Device acceleration with gravity removed (m/s²).
62
53
 
63
- ### TYPE_STEP_DETECTOR
54
+ ### TYPE_ROTATION_VECTOR
64
55
 
65
- 해당 없음
56
+ Rotation vector components used for orientation fusion.
@@ -128,6 +128,18 @@ class StepCounterModule(
128
128
  stepCounterListener!!.stopService()
129
129
  }
130
130
 
131
+ @ReactMethod
132
+ override fun queryPedometerDataBetweenDates(
133
+ startDate: Double,
134
+ endDate: Double,
135
+ promise: Promise,
136
+ ) {
137
+ promise.reject(
138
+ "ERR_UNAVAILABLE",
139
+ "queryPedometerDataBetweenDates is not supported on Android",
140
+ )
141
+ }
142
+
131
143
  /**
132
144
  * Keep: Required for RN built in Event Emitter Support.
133
145
  * @param eventName the name of the event. usually "stepCounterUpdate".
@@ -69,16 +69,26 @@ RCT_EXPORT_METHOD(isStepCountingSupported:(RCTPromiseResolveBlock)resolve
69
69
  body:[self dictionaryAboutSensorInfo]];
70
70
  }
71
71
 
72
- RCT_EXPORT_METHOD(queryStepCounterDataBetweenDates:(NSDate *)startDate
73
- endDate:(NSDate *)endDate
74
- handler:(RCTResponseSenderBlock)handler) {
75
- [self.pedometer queryPedometerDataFromDate:startDate
76
- toDate:endDate
72
+ RCT_EXPORT_METHOD(queryPedometerDataBetweenDates:(double)startDate
73
+ endDate:(double)endDate
74
+ resolve:(RCTPromiseResolveBlock)resolve
75
+ reject:(RCTPromiseRejectBlock)reject) {
76
+ NSDate *start = [self dateFromTimestamp:startDate];
77
+ NSDate *end = [self dateFromTimestamp:endDate];
78
+
79
+ if ([start compare:end] == NSOrderedDescending) {
80
+ reject(@"INVALID_RANGE", @"startDate must be before or equal to endDate", nil);
81
+ return;
82
+ }
83
+
84
+ [self.pedometer queryPedometerDataFromDate:start
85
+ toDate:end
77
86
  withHandler:^(CMPedometerData *pedometerData, NSError *error) {
78
- handler(@[
79
- error.description ?: [NSNull null],
80
- [self dictionaryFromPedometerData:pedometerData]
81
- ]);
87
+ if (error) {
88
+ reject(@"QUERY_FAILED", error.localizedDescription, error);
89
+ return;
90
+ }
91
+ resolve([self dictionaryFromPedometerData:pedometerData]);
82
92
  }];
83
93
  }
84
94
 
@@ -188,6 +198,14 @@ RCT_EXPORT_METHOD(startStepsDetection) {
188
198
 
189
199
  #pragma mark - Sensor info / mapping
190
200
 
201
+ - (NSDate *)dateFromTimestamp:(double)timestamp {
202
+ double seconds = (timestamp > 1e12) ? (timestamp / 1000.0) : timestamp;
203
+ if (seconds <= 0) {
204
+ return [NSDate date];
205
+ }
206
+ return [NSDate dateWithTimeIntervalSince1970:seconds];
207
+ }
208
+
191
209
  - (NSDictionary *)dictionaryAboutSensorInfo {
192
210
  return @{
193
211
  @"name": @"CMPedometer",
@@ -215,6 +233,8 @@ RCT_EXPORT_METHOD(startStepsDetection) {
215
233
 
216
234
  NSNumber *startDate = @((long long)(data.startDate.timeIntervalSince1970 * 1000.0));
217
235
  NSNumber *endDate = @((long long)(data.endDate.timeIntervalSince1970 * 1000.0));
236
+ NSInteger steps = data.numberOfSteps.integerValue;
237
+ NSNumber *calories = @(steps * 0.045);
218
238
 
219
239
  return @{
220
240
  @"counterType": @"CMPedometer",
@@ -224,6 +244,7 @@ RCT_EXPORT_METHOD(startStepsDetection) {
224
244
  @"distance": data.distance ?: [NSNull null],
225
245
  @"floorsAscended": data.floorsAscended ?: [NSNull null],
226
246
  @"floorsDescended": data.floorsDescended ?: [NSNull null],
247
+ @"calories": calories,
227
248
  };
228
249
  }
229
250
 
@@ -12,10 +12,14 @@ import { TurboModuleRegistry } from "react-native";
12
12
  * distance - The distance in meters that the user has walked or run.
13
13
  * floorsAscended - number of floors ascended (iOS only)
14
14
  * floorsDescended - number of floors descended (iOS only)
15
+ * calories - estimated calories burned (Android native; iOS may include estimated value)
15
16
  */
16
17
 
17
18
  export const NAME = "StepCounter";
18
19
  export const VERSION = "0.3.1";
19
20
  export const eventName = "StepCounter.stepCounterUpdate";
21
+ export const errorEventName = "StepCounter.errorOccurred";
22
+ export const sensorInfoEventName = "StepCounter.stepsSensorInfo";
23
+ export const stepDetectedEventName = "StepCounter.stepDetected";
20
24
  export default TurboModuleRegistry.getEnforcing("StepCounter");
21
25
  //# sourceMappingURL=NativeStepCounter.js.map
@@ -1 +1 @@
1
- {"version":3,"names":["TurboModuleRegistry","NAME","VERSION","eventName","getEnforcing"],"sourceRoot":"../../src","sources":["NativeStepCounter.ts"],"mappings":";;AAAA,SAASA,mBAAmB,QAA0B,cAAc;;AAIpE;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAWA,OAAO,MAAMC,IAAI,GAAG,aAAa;AACjC,OAAO,MAAMC,OAAO,GAAG,OAAO;AAC9B,OAAO,MAAMC,SAAS,GAAG,+BAA+B;AAkCxD,eAAeH,mBAAmB,CAACI,YAAY,CAAO,aAAa,CAAC","ignoreList":[]}
1
+ {"version":3,"names":["TurboModuleRegistry","NAME","VERSION","eventName","errorEventName","sensorInfoEventName","stepDetectedEventName","getEnforcing"],"sourceRoot":"../../src","sources":["NativeStepCounter.ts"],"mappings":";;AAAA,SAASA,mBAAmB,QAA0B,cAAc;;AAIpE;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AA8CA,OAAO,MAAMC,IAAI,GAAG,aAAa;AACjC,OAAO,MAAMC,OAAO,GAAG,OAAO;AAC9B,OAAO,MAAMC,SAAS,GAAG,+BAA+B;AACxD,OAAO,MAAMC,cAAc,GAAG,2BAA2B;AACzD,OAAO,MAAMC,mBAAmB,GAAG,6BAA6B;AAChE,OAAO,MAAMC,qBAAqB,GAAG,0BAA0B;AAwC/D,eAAeN,mBAAmB,CAACO,YAAY,CAAO,aAAa,CAAC","ignoreList":[]}
@@ -1,6 +1,6 @@
1
1
  "use strict";
2
2
 
3
- import StepCounterModule, { eventName, NAME, VERSION } from "./NativeStepCounter.js";
3
+ import StepCounterModule, { errorEventName, eventName, NAME, sensorInfoEventName, stepDetectedEventName, VERSION } from "./NativeStepCounter.js";
4
4
  import { NativeEventEmitter, Platform } from "react-native";
5
5
  import { PACKAGE_NAME, REPOSITORY_WEB_URL } from "./packageMeta.js";
6
6
 
@@ -127,20 +127,89 @@ class UnavailabilityError extends Error {
127
127
  this.code = "ERR_UNAVAILABLE";
128
128
  }
129
129
  }
130
+ function normalizeStepCounterError(payload) {
131
+ if (payload && typeof payload === "object") {
132
+ const errorPayload = payload;
133
+ const message = typeof errorPayload.message === "string" ? errorPayload.message : typeof errorPayload.localizedDescription === "string" ? errorPayload.localizedDescription : String(payload);
134
+ return {
135
+ message,
136
+ code: typeof errorPayload.code === "number" ? errorPayload.code : undefined,
137
+ domain: typeof errorPayload.domain === "string" ? errorPayload.domain : undefined
138
+ };
139
+ }
140
+ return {
141
+ message: String(payload ?? "Unknown error")
142
+ };
143
+ }
130
144
 
131
145
  /**
132
146
  * Returns whether the stepCounter is enabled on the device.
133
147
  * iOS 8.0+ only. Android is available since KitKat (4.4 / API 19).
134
148
  * @see https://developer.android.com/about/versions/android-4.4.html
135
149
  * @see https://developer.apple.com/documentation/coremotion/cmpedometer/1613963-isstepcountingavailable
136
- * @returns {Promise<{ supported: boolean; granted: boolean }>} A promise that resolves with an object containing the stepCounter availability.
150
+ * @returns {Promise<StepCountingSupportResult>} A promise that resolves with step counter availability.
137
151
  * supported - Whether the stepCounter is supported on device.
138
152
  * granted - Whether user granted the permission.
153
+ * working - Android only: whether the native sensor service is currently active.
139
154
  */
140
155
  export function isStepCountingSupported() {
141
156
  return StepCounter.isStepCountingSupported();
142
157
  }
143
158
 
159
+ /**
160
+ * Query cumulative step data for a date range. iOS only (Core Motion `CMPedometer`).
161
+ *
162
+ * Apple retains roughly seven days of pedometer history. Ranges older than that may return
163
+ * partial or empty data. This call does not stop or interfere with an active live session.
164
+ *
165
+ * @param start Start of the query range.
166
+ * @param end End of the query range. Values in the future are clamped to the current time.
167
+ */
168
+ export function queryPedometerDataBetweenDates(start, end) {
169
+ if (Platform.OS !== "ios" || !StepCounter.queryPedometerDataBetweenDates) {
170
+ throw new UnavailabilityError(NAME, "queryPedometerDataBetweenDates");
171
+ }
172
+ if (start.getTime() > end.getTime()) {
173
+ return Promise.reject(new Error("start must be before or equal to end"));
174
+ }
175
+ const now = Date.now();
176
+ const endMs = Math.min(end.getTime(), now);
177
+ return StepCounter.queryPedometerDataBetweenDates(start.getTime(), endMs);
178
+ }
179
+
180
+ /**
181
+ * Returns whether this library currently has an active live step-count subscription.
182
+ *
183
+ * This reflects the session managed by `startStepCounterUpdate` / `stopStepCounterUpdate`,
184
+ * not the Android `working` flag from `isStepCountingSupported()`.
185
+ */
186
+ export function isSensorWorking() {
187
+ return _activeSubscription !== null;
188
+ }
189
+
190
+ /**
191
+ * Subscribe to native step counter errors (`StepCounter.errorOccurred`).
192
+ */
193
+ export function addStepCounterErrorListener(callback) {
194
+ return StepEventEmitter.addListener(errorEventName, payload => callback(normalizeStepCounterError(payload)));
195
+ }
196
+
197
+ /**
198
+ * Subscribe to native sensor capability metadata (`StepCounter.stepsSensorInfo`).
199
+ *
200
+ * Emitted from `isStepCountingSupported()` on iOS and when the Android sensor service starts.
201
+ */
202
+ export function addStepsSensorInfoListener(callback) {
203
+ return StepEventEmitter.addListener(sensorInfoEventName, payload => callback(payload));
204
+ }
205
+
206
+ /**
207
+ * Subscribe to motion/step detection signals (`StepCounter.stepDetected`).
208
+ */
209
+ export function addStepDetectedListener(callback) {
210
+ return StepEventEmitter.addListener(stepDetectedEventName, payload => callback(Boolean(payload)));
211
+ }
212
+
144
213
  /**
145
214
  * Start to subscribe stepCounter updates.
146
215
  * Only the past seven days worth of data is stored and available for you to retrieve.
@@ -186,5 +255,5 @@ export function stopStepCounterUpdate() {
186
255
  _activeSubscription = null;
187
256
  StepCounter.stopStepCounterUpdate();
188
257
  }
189
- export { NAME, VERSION };
258
+ export { errorEventName, eventName, NAME, sensorInfoEventName, stepDetectedEventName, VERSION };
190
259
  //# sourceMappingURL=index.js.map
@@ -1 +1 @@
1
- {"version":3,"names":["StepCounterModule","eventName","NAME","VERSION","NativeEventEmitter","Platform","PACKAGE_NAME","REPOSITORY_WEB_URL","LINKING_ERROR","select","ios","android","default","StepCounter","Proxy","get","Error","StepEventEmitter","DEFAULT_MINIMUM_STEP_INTERVAL_MS","_activeSubscription","parseStepData","data","steps","startDate","endDate","distance","dailyGoal","stepsString","kCal","toFixed","endDateTime","Date","toLocaleTimeString","startDateTime","roundedDistance","stepGoalStatus","calories","createStepCountFilter","options","minimumStepIntervalMs","previousRawData","ignoredSteps","ignoredDistance","Number","isFinite","referenceTime","stepDelta","distanceDelta","elapsedMs","POSITIVE_INFINITY","isSuspiciousBurst","Math","max","UnavailabilityError","constructor","moduleName","propertyName","OS","code","isStepCountingSupported","startStepCounterUpdate","start","callBack","remove","from","getTime","addListener","stopStepCounterUpdate"],"sourceRoot":"../../src","sources":["index.tsx"],"mappings":";;AACA,OAAOA,iBAAiB,IACtBC,SAAS,EACTC,IAAI,EACJC,OAAO,QAIF,wBAAqB;AAC5B,SAASC,kBAAkB,EAAEC,QAAQ,QAAQ,cAAc;AAC3D,SAASC,YAAY,EAAEC,kBAAkB,QAAQ,kBAAe;;AAEhE;AACA,MAAMC,aAAa,GACjB,gBAAgBF,YAAY,8CAA8C,GAC1ED,QAAQ,CAACI,MAAM,CAAC;EACdC,GAAG,EAAE,2JAA2J;EAChKC,OAAO,EACL,0GAA0G;EAC5GC,OAAO,EAAE;AACX,CAAC,CAAC,GACF,4FAA4F,GAC5F,iGAAiG,GACjG,mDAAmD,GACnD,sDAAsD,GACtD,+BAA+B,GAC/B,mFAAmFL,kBAAkB,EAAE;AAYzG;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,MAAMM,WAAW,GACfb,iBAAiB,GACbA,iBAAiB,GACjB,IAAIc,KAAK,CACP,CAAC,CAAC,EACF;EACEC,GAAGA,CAAA,EAAG;IACJ,MAAM,IAAIC,KAAK,CAACR,aAAa,CAAC;EAChC;AACF,CACF,CACG;AAET,MAAMS,gBAAgB,GAAG,IAAIb,kBAAkB,CAACS,WAAW,CAAC;AAc5D,MAAMK,gCAAgC,GAAG,GAAG;;AAE5C;AACA;AACA;AACA,IAAIC,mBAA6C,GAAG,IAAI;;AAExD;AACA;AACA;AACA;AACA;AACA;AACA,OAAO,SAASC,aAAaA,CAACC,IAAmB,EAAuB;EACtE,MAAM;IAAEC,KAAK;IAAEC,SAAS;IAAEC,OAAO;IAAEC;EAAS,CAAC,GAAGJ,IAAI;EACpD,MAAMK,SAAS,GAAG,KAAK;EACvB,MAAMC,WAAW,GAAGL,KAAK,GAAG,QAAQ;EACpC,MAAMM,IAAI,GAAG,CAACN,KAAK,GAAG,KAAK,EAAEO,OAAO,CAAC,CAAC,CAAC,GAAG,MAAM;EAChD,MAAMC,WAAW,GAAG,IAAIC,IAAI,CAACP,OAAO,CAAC,CAACQ,kBAAkB,CAAC,OAAO,CAAC;EACjE,MAAMC,aAAa,GAAG,IAAIF,IAAI,CAACR,SAAS,CAAC,CAACS,kBAAkB,CAAC,OAAO,CAAC;EACrE,MAAME,eAAe,GAAGT,QAAQ,CAACI,OAAO,CAAC,CAAC,CAAC,GAAG,GAAG;EACjD,MAAMM,cAAc,GAAGb,KAAK,IAAII,SAAS,GAAG,cAAc,GAAG,GAAGJ,KAAK,IAAII,SAAS,QAAQ;EAC1F,OAAO;IACLA,SAAS,EAAES,cAAc;IACzBb,KAAK;IACLK,WAAW;IACXS,QAAQ,EAAER,IAAI;IACdL,SAAS,EAAEU,aAAa;IACxBT,OAAO,EAAEM,WAAW;IACpBL,QAAQ,EAAES;EACZ,CAAC;AACH;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,OAAO,SAASG,qBAAqBA,CAACC,OAA+B,GAAG,CAAC,CAAC,EAAmB;EAC3F,MAAMC,qBAAqB,GACzBD,OAAO,CAACC,qBAAqB,IAAID,OAAO,CAACC,qBAAqB,GAAG,CAAC,GAC9DD,OAAO,CAACC,qBAAqB,GAC7BrB,gCAAgC;EAEtC,IAAIsB,eAAqC,GAAG,IAAI;EAChD,IAAIC,YAAY,GAAG,CAAC;EACpB,IAAIC,eAAe,GAAG,CAAC;EAEvB,OAAQrB,IAAmB,IAAK;IAC9B,IAAI,CAACsB,MAAM,CAACC,QAAQ,CAACvB,IAAI,CAACC,KAAK,CAAC,IAAID,IAAI,CAACC,KAAK,GAAG,CAAC,EAAE;MAClD,OAAO,IAAI;IACb;IAEA,IAAIkB,eAAe,IAAInB,IAAI,CAACC,KAAK,GAAGkB,eAAe,CAAClB,KAAK,EAAE;MACzDkB,eAAe,GAAGnB,IAAI;MACtBoB,YAAY,GAAG,CAAC;MAChBC,eAAe,GAAG,CAAC;MACnB,OAAOrB,IAAI;IACb;IAEA,MAAMwB,aAAa,GAAGL,eAAe,GAAGA,eAAe,CAAChB,OAAO,GAAGH,IAAI,CAACE,SAAS;IAChF,MAAMuB,SAAS,GAAGN,eAAe,GAAGnB,IAAI,CAACC,KAAK,GAAGkB,eAAe,CAAClB,KAAK,GAAGD,IAAI,CAACC,KAAK;IACnF,MAAMyB,aAAa,GAAGP,eAAe,GACjCnB,IAAI,CAACI,QAAQ,GAAGe,eAAe,CAACf,QAAQ,GACxCJ,IAAI,CAACI,QAAQ;IACjB,MAAMuB,SAAS,GACbL,MAAM,CAACC,QAAQ,CAACvB,IAAI,CAACG,OAAO,CAAC,IAAImB,MAAM,CAACC,QAAQ,CAACC,aAAa,CAAC,GAC3DxB,IAAI,CAACG,OAAO,GAAGqB,aAAa,GAC5BF,MAAM,CAACM,iBAAiB;IAC9B,MAAMC,iBAAiB,GACrBJ,SAAS,GAAG,CAAC,IAAIE,SAAS,IAAI,CAAC,IAAIA,SAAS,GAAGF,SAAS,GAAGP,qBAAqB;IAElFC,eAAe,GAAGnB,IAAI;IAEtB,IAAI6B,iBAAiB,EAAE;MACrBT,YAAY,IAAIK,SAAS;MACzB,IAAIC,aAAa,GAAG,CAAC,EAAE;QACrBL,eAAe,IAAIK,aAAa;MAClC;MACA,OAAO,IAAI;IACb;IAEA,IAAIN,YAAY,KAAK,CAAC,IAAIC,eAAe,KAAK,CAAC,EAAE;MAC/C,OAAOrB,IAAI;IACb;IAEA,OAAO;MACL,GAAGA,IAAI;MACPC,KAAK,EAAE6B,IAAI,CAACC,GAAG,CAAC,CAAC,EAAE/B,IAAI,CAACC,KAAK,GAAGmB,YAAY,CAAC;MAC7ChB,QAAQ,EAAE0B,IAAI,CAACC,GAAG,CAAC,CAAC,EAAE/B,IAAI,CAACI,QAAQ,GAAGiB,eAAe;IACvD,CAAC;EACH,CAAC;AACH;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,MAAMW,mBAAmB,SAASrC,KAAK,CAAC;EAEtCsC,WAAWA,CAACC,UAAkB,EAAEC,YAAoB,EAAE;IACpD,KAAK,CACH,0BAA0BD,UAAU,IAAIC,YAAY,wBAAwBnD,QAAQ,CAACoD,EAAE,IAAI,GACzF,kEACJ,CAAC;IACD,IAAI,CAACC,IAAI,GAAG,iBAAiB;EAC/B;AACF;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,OAAO,SAASC,uBAAuBA,CAAA,EAAsD;EAC3F,OAAO9C,WAAW,CAAC8C,uBAAuB,CAAC,CAAC;AAC9C;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,OAAO,SAASC,sBAAsBA,CACpCC,KAAW,EACXC,QAAiC,EACd;EACnB,IAAI,CAACjD,WAAW,CAAC+C,sBAAsB,EAAE;IACvC,MAAM,IAAIP,mBAAmB,CAACnD,IAAI,EAAED,SAAS,CAAC;EAChD;EACA;EACAkB,mBAAmB,EAAE4C,MAAM,CAAC,CAAC;EAC7B5C,mBAAmB,GAAG,IAAI;EAC1B,MAAM6C,IAAI,GAAGH,KAAK,CAACI,OAAO,CAAC,CAAC;EAC5B9C,mBAAmB,GAAGF,gBAAgB,CAACiD,WAAW,CAACjE,SAAS,EAAGoB,IAAI,IACjEyC,QAAQ,CAACzC,IAAqB,CAChC,CAAC;EACDR,WAAW,CAAC+C,sBAAsB,CAACI,IAAI,CAAC;EACxC,OAAO7C,mBAAmB;AAC5B;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,OAAO,SAASgD,qBAAqBA,CAAA,EAAS;EAC5C;EACA;EACAhD,mBAAmB,EAAE4C,MAAM,CAAC,CAAC;EAC7B5C,mBAAmB,GAAG,IAAI;EAC1BN,WAAW,CAACsD,qBAAqB,CAAC,CAAC;AACrC;AAEA,SAASjE,IAAI,EAAEC,OAAO","ignoreList":[]}
1
+ {"version":3,"names":["StepCounterModule","errorEventName","eventName","NAME","sensorInfoEventName","stepDetectedEventName","VERSION","NativeEventEmitter","Platform","PACKAGE_NAME","REPOSITORY_WEB_URL","LINKING_ERROR","select","ios","android","default","StepCounter","Proxy","get","Error","StepEventEmitter","DEFAULT_MINIMUM_STEP_INTERVAL_MS","_activeSubscription","parseStepData","data","steps","startDate","endDate","distance","dailyGoal","stepsString","kCal","toFixed","endDateTime","Date","toLocaleTimeString","startDateTime","roundedDistance","stepGoalStatus","calories","createStepCountFilter","options","minimumStepIntervalMs","previousRawData","ignoredSteps","ignoredDistance","Number","isFinite","referenceTime","stepDelta","distanceDelta","elapsedMs","POSITIVE_INFINITY","isSuspiciousBurst","Math","max","UnavailabilityError","constructor","moduleName","propertyName","OS","code","normalizeStepCounterError","payload","errorPayload","message","localizedDescription","String","undefined","domain","isStepCountingSupported","queryPedometerDataBetweenDates","start","end","getTime","Promise","reject","now","endMs","min","isSensorWorking","addStepCounterErrorListener","callback","addListener","addStepsSensorInfoListener","addStepDetectedListener","Boolean","startStepCounterUpdate","callBack","remove","from","stopStepCounterUpdate"],"sourceRoot":"../../src","sources":["index.tsx"],"mappings":"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","ignoreList":[]}
@@ -10,6 +10,7 @@ export type CounterType = "STEP_COUNTER" | "ACCELEROMETER" | "CMPedometer";
10
10
  * distance - The distance in meters that the user has walked or run.
11
11
  * floorsAscended - number of floors ascended (iOS only)
12
12
  * floorsDescended - number of floors descended (iOS only)
13
+ * calories - estimated calories burned (Android native; iOS may include estimated value)
13
14
  */
14
15
  export type StepCountData = {
15
16
  counterType: CounterType;
@@ -19,15 +20,48 @@ export type StepCountData = {
19
20
  distance: number;
20
21
  floorsAscended?: number;
21
22
  floorsDescended?: number;
23
+ calories?: number;
22
24
  };
25
+ export type StepCountingSupportResult = {
26
+ supported: boolean;
27
+ granted: boolean;
28
+ /** Android only: whether the sensor service is currently active */
29
+ working?: boolean;
30
+ };
31
+ export type StepCounterError = {
32
+ message: string;
33
+ code?: number;
34
+ domain?: string;
35
+ };
36
+ export type StepsSensorInfoIOS = {
37
+ name: string;
38
+ granted: boolean;
39
+ stepCounting: boolean;
40
+ pace: boolean;
41
+ cadence: boolean;
42
+ distance: boolean;
43
+ floorCounting: boolean;
44
+ };
45
+ export type StepsSensorInfoAndroid = {
46
+ name: string;
47
+ vendor: string;
48
+ minDelay: number;
49
+ maxDelay: number;
50
+ power: number;
51
+ resolution: number;
52
+ };
53
+ export type StepsSensorInfo = StepsSensorInfoIOS | StepsSensorInfoAndroid;
23
54
  export declare const NAME = "StepCounter";
24
55
  export declare const VERSION = "0.3.1";
25
56
  export declare const eventName = "StepCounter.stepCounterUpdate";
57
+ export declare const errorEventName = "StepCounter.errorOccurred";
58
+ export declare const sensorInfoEventName = "StepCounter.stepsSensorInfo";
59
+ export declare const stepDetectedEventName = "StepCounter.stepDetected";
26
60
  export interface Spec extends TurboModule {
27
61
  /**
28
62
  * @description Check if the step counter is supported on the device.
29
63
  * @async
30
- * @returns {Promise<{ supported: boolean; granted: boolean }>} Returns the `Promise` object,
64
+ * @returns {Promise<StepCountingSupportResult>} Returns the `Promise` object,
31
65
  * including information such as whether the user's device has a step counter sensor by default (`supported`)
32
66
  * and whether the user has allowed the app to measure the pedometer data. (`granted`)
33
67
  * granted - The permission is granted or not.
@@ -39,10 +73,13 @@ export interface Spec extends TurboModule {
39
73
  * setStepCountingGranted(granted);
40
74
  * });
41
75
  */
42
- isStepCountingSupported(): Promise<{
43
- supported: boolean;
44
- granted: boolean;
45
- }>;
76
+ isStepCountingSupported(): Promise<StepCountingSupportResult>;
77
+ /**
78
+ * Query cumulative step data for a date range. iOS only (Core Motion).
79
+ * @param startDate Unix timestamp in milliseconds.
80
+ * @param endDate Unix timestamp in milliseconds.
81
+ */
82
+ queryPedometerDataBetweenDates(startDate: number, endDate: number): Promise<StepCountData>;
46
83
  /**
47
84
  * @param {number} from the current time obtained by `new Date()` in milliseconds.
48
85
  */
@@ -1 +1 @@
1
- {"version":3,"file":"NativeStepCounter.d.ts","sourceRoot":"","sources":["../../../src/NativeStepCounter.ts"],"names":[],"mappings":"AAAA,OAAO,EAAuB,KAAK,WAAW,EAAE,MAAM,cAAc,CAAC;AAErE,MAAM,MAAM,WAAW,GAAG,cAAc,GAAG,eAAe,GAAG,aAAa,CAAC;AAE3E;;;;;;;;;;GAUG;AACH,MAAM,MAAM,aAAa,GAAG;IAC1B,WAAW,EAAE,WAAW,CAAC;IACzB,KAAK,EAAE,MAAM,CAAC;IACd,SAAS,EAAE,MAAM,CAAC;IAClB,OAAO,EAAE,MAAM,CAAC;IAChB,QAAQ,EAAE,MAAM,CAAC;IACjB,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB,eAAe,CAAC,EAAE,MAAM,CAAC;CAC1B,CAAC;AAEF,eAAO,MAAM,IAAI,gBAAgB,CAAC;AAClC,eAAO,MAAM,OAAO,UAAU,CAAC;AAC/B,eAAO,MAAM,SAAS,kCAAkC,CAAC;AAEzD,MAAM,WAAW,IAAK,SAAQ,WAAW;IACvC;;;;;;;;;;;;;;OAcG;IACH,uBAAuB,IAAI,OAAO,CAAC;QAAE,SAAS,EAAE,OAAO,CAAC;QAAC,OAAO,EAAE,OAAO,CAAA;KAAE,CAAC,CAAC;IAC7E;;OAEG;IACH,sBAAsB,CAAC,IAAI,EAAE,MAAM,GAAG,IAAI,CAAC;IAC3C;;;OAGG;IACH,qBAAqB,IAAI,IAAI,CAAC;IAG9B,WAAW,CAAC,KAAK,EAAE,MAAM,GAAG,IAAI,CAAC;IACjC,eAAe,CAAC,KAAK,EAAE,MAAM,GAAG,IAAI,CAAC;CACtC;;AAED,wBAAqE"}
1
+ {"version":3,"file":"NativeStepCounter.d.ts","sourceRoot":"","sources":["../../../src/NativeStepCounter.ts"],"names":[],"mappings":"AAAA,OAAO,EAAuB,KAAK,WAAW,EAAE,MAAM,cAAc,CAAC;AAErE,MAAM,MAAM,WAAW,GAAG,cAAc,GAAG,eAAe,GAAG,aAAa,CAAC;AAE3E;;;;;;;;;;;GAWG;AACH,MAAM,MAAM,aAAa,GAAG;IAC1B,WAAW,EAAE,WAAW,CAAC;IACzB,KAAK,EAAE,MAAM,CAAC;IACd,SAAS,EAAE,MAAM,CAAC;IAClB,OAAO,EAAE,MAAM,CAAC;IAChB,QAAQ,EAAE,MAAM,CAAC;IACjB,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB,eAAe,CAAC,EAAE,MAAM,CAAC;IACzB,QAAQ,CAAC,EAAE,MAAM,CAAC;CACnB,CAAC;AAEF,MAAM,MAAM,yBAAyB,GAAG;IACtC,SAAS,EAAE,OAAO,CAAC;IACnB,OAAO,EAAE,OAAO,CAAC;IACjB,mEAAmE;IACnE,OAAO,CAAC,EAAE,OAAO,CAAC;CACnB,CAAC;AAEF,MAAM,MAAM,gBAAgB,GAAG;IAC7B,OAAO,EAAE,MAAM,CAAC;IAChB,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,MAAM,CAAC,EAAE,MAAM,CAAC;CACjB,CAAC;AAEF,MAAM,MAAM,kBAAkB,GAAG;IAC/B,IAAI,EAAE,MAAM,CAAC;IACb,OAAO,EAAE,OAAO,CAAC;IACjB,YAAY,EAAE,OAAO,CAAC;IACtB,IAAI,EAAE,OAAO,CAAC;IACd,OAAO,EAAE,OAAO,CAAC;IACjB,QAAQ,EAAE,OAAO,CAAC;IAClB,aAAa,EAAE,OAAO,CAAC;CACxB,CAAC;AAEF,MAAM,MAAM,sBAAsB,GAAG;IACnC,IAAI,EAAE,MAAM,CAAC;IACb,MAAM,EAAE,MAAM,CAAC;IACf,QAAQ,EAAE,MAAM,CAAC;IACjB,QAAQ,EAAE,MAAM,CAAC;IACjB,KAAK,EAAE,MAAM,CAAC;IACd,UAAU,EAAE,MAAM,CAAC;CACpB,CAAC;AAEF,MAAM,MAAM,eAAe,GAAG,kBAAkB,GAAG,sBAAsB,CAAC;AAE1E,eAAO,MAAM,IAAI,gBAAgB,CAAC;AAClC,eAAO,MAAM,OAAO,UAAU,CAAC;AAC/B,eAAO,MAAM,SAAS,kCAAkC,CAAC;AACzD,eAAO,MAAM,cAAc,8BAA8B,CAAC;AAC1D,eAAO,MAAM,mBAAmB,gCAAgC,CAAC;AACjE,eAAO,MAAM,qBAAqB,6BAA6B,CAAC;AAEhE,MAAM,WAAW,IAAK,SAAQ,WAAW;IACvC;;;;;;;;;;;;;;OAcG;IACH,uBAAuB,IAAI,OAAO,CAAC,yBAAyB,CAAC,CAAC;IAC9D;;;;OAIG;IACH,8BAA8B,CAAC,SAAS,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,GAAG,OAAO,CAAC,aAAa,CAAC,CAAC;IAC3F;;OAEG;IACH,sBAAsB,CAAC,IAAI,EAAE,MAAM,GAAG,IAAI,CAAC;IAC3C;;;OAGG;IACH,qBAAqB,IAAI,IAAI,CAAC;IAG9B,WAAW,CAAC,KAAK,EAAE,MAAM,GAAG,IAAI,CAAC;IACjC,eAAe,CAAC,KAAK,EAAE,MAAM,GAAG,IAAI,CAAC;CACtC;;AAED,wBAAqE"}
@@ -1,5 +1,5 @@
1
1
  import type { EventSubscription } from "react-native";
2
- import { NAME, VERSION, type CounterType, type StepCountData } from "./NativeStepCounter";
2
+ import { errorEventName, eventName, NAME, sensorInfoEventName, stepDetectedEventName, VERSION, type CounterType, type StepCountData, type StepCountingSupportResult, type StepCounterError, type StepsSensorInfo } from "./NativeStepCounter";
3
3
  export interface ParsedStepCountData {
4
4
  dailyGoal: string;
5
5
  steps: number;
@@ -41,14 +41,43 @@ export declare function createStepCountFilter(options?: StepCountFilterOptions):
41
41
  * iOS 8.0+ only. Android is available since KitKat (4.4 / API 19).
42
42
  * @see https://developer.android.com/about/versions/android-4.4.html
43
43
  * @see https://developer.apple.com/documentation/coremotion/cmpedometer/1613963-isstepcountingavailable
44
- * @returns {Promise<{ supported: boolean; granted: boolean }>} A promise that resolves with an object containing the stepCounter availability.
44
+ * @returns {Promise<StepCountingSupportResult>} A promise that resolves with step counter availability.
45
45
  * supported - Whether the stepCounter is supported on device.
46
46
  * granted - Whether user granted the permission.
47
+ * working - Android only: whether the native sensor service is currently active.
47
48
  */
48
- export declare function isStepCountingSupported(): Promise<{
49
- supported: boolean;
50
- granted: boolean;
51
- }>;
49
+ export declare function isStepCountingSupported(): Promise<StepCountingSupportResult>;
50
+ /**
51
+ * Query cumulative step data for a date range. iOS only (Core Motion `CMPedometer`).
52
+ *
53
+ * Apple retains roughly seven days of pedometer history. Ranges older than that may return
54
+ * partial or empty data. This call does not stop or interfere with an active live session.
55
+ *
56
+ * @param start Start of the query range.
57
+ * @param end End of the query range. Values in the future are clamped to the current time.
58
+ */
59
+ export declare function queryPedometerDataBetweenDates(start: Date, end: Date): Promise<StepCountData>;
60
+ /**
61
+ * Returns whether this library currently has an active live step-count subscription.
62
+ *
63
+ * This reflects the session managed by `startStepCounterUpdate` / `stopStepCounterUpdate`,
64
+ * not the Android `working` flag from `isStepCountingSupported()`.
65
+ */
66
+ export declare function isSensorWorking(): boolean;
67
+ /**
68
+ * Subscribe to native step counter errors (`StepCounter.errorOccurred`).
69
+ */
70
+ export declare function addStepCounterErrorListener(callback: (error: StepCounterError) => void): EventSubscription;
71
+ /**
72
+ * Subscribe to native sensor capability metadata (`StepCounter.stepsSensorInfo`).
73
+ *
74
+ * Emitted from `isStepCountingSupported()` on iOS and when the Android sensor service starts.
75
+ */
76
+ export declare function addStepsSensorInfoListener(callback: (info: StepsSensorInfo) => void): EventSubscription;
77
+ /**
78
+ * Subscribe to motion/step detection signals (`StepCounter.stepDetected`).
79
+ */
80
+ export declare function addStepDetectedListener(callback: (detected: boolean) => void): EventSubscription;
52
81
  /**
53
82
  * Start to subscribe stepCounter updates.
54
83
  * Only the past seven days worth of data is stored and available for you to retrieve.
@@ -76,5 +105,5 @@ export declare function startStepCounterUpdate(start: Date, callBack: StepCountU
76
105
  * @see https://developer.apple.com/documentation/coremotion/cmstepcounter/1616157-stopstepcountingupdates
77
106
  */
78
107
  export declare function stopStepCounterUpdate(): void;
79
- export { NAME, VERSION, type CounterType, type StepCountData };
108
+ export { errorEventName, eventName, NAME, sensorInfoEventName, stepDetectedEventName, VERSION, type CounterType, type StepCountData, type StepCountingSupportResult, type StepCounterError, type StepsSensorInfo, };
80
109
  //# sourceMappingURL=index.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/index.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,cAAc,CAAC;AACtD,OAA0B,EAExB,IAAI,EACJ,OAAO,EACP,KAAK,WAAW,EAEhB,KAAK,aAAa,EACnB,MAAM,qBAAqB,CAAC;AAoB7B,MAAM,WAAW,mBAAmB;IAClC,SAAS,EAAE,MAAM,CAAC;IAClB,KAAK,EAAE,MAAM,CAAC;IACd,WAAW,EAAE,MAAM,CAAC;IACpB,QAAQ,EAAE,MAAM,CAAC;IACjB,SAAS,EAAE,MAAM,CAAC;IAClB,OAAO,EAAE,MAAM,CAAC;IAChB,QAAQ,EAAE,MAAM,CAAC;CAClB;AA0BD,KAAK,uBAAuB,GAAG,CAAC,IAAI,EAAE,aAAa,KAAK,IAAI,CAAC;AAC7D,MAAM,MAAM,eAAe,GAAG,CAAC,IAAI,EAAE,aAAa,KAAK,aAAa,GAAG,IAAI,CAAC;AAE5E,MAAM,WAAW,sBAAsB;IACrC;;;;;OAKG;IACH,qBAAqB,CAAC,EAAE,MAAM,CAAC;CAChC;AASD;;;;;GAKG;AACH,wBAAgB,aAAa,CAAC,IAAI,EAAE,aAAa,GAAG,mBAAmB,CAkBtE;AAED;;;;;;;GAOG;AACH,wBAAgB,qBAAqB,CAAC,OAAO,GAAE,sBAA2B,GAAG,eAAe,CAsD3F;AAuBD;;;;;;;;GAQG;AACH,wBAAgB,uBAAuB,IAAI,OAAO,CAAC;IAAE,SAAS,EAAE,OAAO,CAAC;IAAC,OAAO,EAAE,OAAO,CAAA;CAAE,CAAC,CAE3F;AAED;;;;;;;;;;;;;;;;;GAiBG;AACH,wBAAgB,sBAAsB,CACpC,KAAK,EAAE,IAAI,EACX,QAAQ,EAAE,uBAAuB,GAChC,iBAAiB,CAanB;AAED;;;;;;GAMG;AACH,wBAAgB,qBAAqB,IAAI,IAAI,CAM5C;AAED,OAAO,EAAE,IAAI,EAAE,OAAO,EAAE,KAAK,WAAW,EAAE,KAAK,aAAa,EAAE,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/index.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,cAAc,CAAC;AACtD,OAA0B,EACxB,cAAc,EACd,SAAS,EACT,IAAI,EACJ,mBAAmB,EACnB,qBAAqB,EACrB,OAAO,EACP,KAAK,WAAW,EAEhB,KAAK,aAAa,EAClB,KAAK,yBAAyB,EAC9B,KAAK,gBAAgB,EACrB,KAAK,eAAe,EACrB,MAAM,qBAAqB,CAAC;AAoB7B,MAAM,WAAW,mBAAmB;IAClC,SAAS,EAAE,MAAM,CAAC;IAClB,KAAK,EAAE,MAAM,CAAC;IACd,WAAW,EAAE,MAAM,CAAC;IACpB,QAAQ,EAAE,MAAM,CAAC;IACjB,SAAS,EAAE,MAAM,CAAC;IAClB,OAAO,EAAE,MAAM,CAAC;IAChB,QAAQ,EAAE,MAAM,CAAC;CAClB;AA0BD,KAAK,uBAAuB,GAAG,CAAC,IAAI,EAAE,aAAa,KAAK,IAAI,CAAC;AAC7D,MAAM,MAAM,eAAe,GAAG,CAAC,IAAI,EAAE,aAAa,KAAK,aAAa,GAAG,IAAI,CAAC;AAE5E,MAAM,WAAW,sBAAsB;IACrC;;;;;OAKG;IACH,qBAAqB,CAAC,EAAE,MAAM,CAAC;CAChC;AASD;;;;;GAKG;AACH,wBAAgB,aAAa,CAAC,IAAI,EAAE,aAAa,GAAG,mBAAmB,CAkBtE;AAED;;;;;;;GAOG;AACH,wBAAgB,qBAAqB,CAAC,OAAO,GAAE,sBAA2B,GAAG,eAAe,CAsD3F;AAyCD;;;;;;;;;GASG;AACH,wBAAgB,uBAAuB,IAAI,OAAO,CAAC,yBAAyB,CAAC,CAE5E;AAED;;;;;;;;GAQG;AACH,wBAAgB,8BAA8B,CAAC,KAAK,EAAE,IAAI,EAAE,GAAG,EAAE,IAAI,GAAG,OAAO,CAAC,aAAa,CAAC,CAU7F;AAED;;;;;GAKG;AACH,wBAAgB,eAAe,IAAI,OAAO,CAEzC;AAED;;GAEG;AACH,wBAAgB,2BAA2B,CACzC,QAAQ,EAAE,CAAC,KAAK,EAAE,gBAAgB,KAAK,IAAI,GAC1C,iBAAiB,CAInB;AAED;;;;GAIG;AACH,wBAAgB,0BAA0B,CACxC,QAAQ,EAAE,CAAC,IAAI,EAAE,eAAe,KAAK,IAAI,GACxC,iBAAiB,CAInB;AAED;;GAEG;AACH,wBAAgB,uBAAuB,CACrC,QAAQ,EAAE,CAAC,QAAQ,EAAE,OAAO,KAAK,IAAI,GACpC,iBAAiB,CAInB;AAED;;;;;;;;;;;;;;;;;GAiBG;AACH,wBAAgB,sBAAsB,CACpC,KAAK,EAAE,IAAI,EACX,QAAQ,EAAE,uBAAuB,GAChC,iBAAiB,CAanB;AAED;;;;;;GAMG;AACH,wBAAgB,qBAAqB,IAAI,IAAI,CAM5C;AAED,OAAO,EACL,cAAc,EACd,SAAS,EACT,IAAI,EACJ,mBAAmB,EACnB,qBAAqB,EACrB,OAAO,EACP,KAAK,WAAW,EAChB,KAAK,aAAa,EAClB,KAAK,yBAAyB,EAC9B,KAAK,gBAAgB,EACrB,KAAK,eAAe,GACrB,CAAC"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@blife/rn-step-counter",
3
- "version": "1.0.1",
3
+ "version": "1.1.0",
4
4
  "description": "This library provides an interface for tracking the number of steps taken by the user in a React Native app.",
5
5
  "main": "./lib/module/index.js",
6
6
  "types": "./lib/typescript/src/index.d.ts",
@@ -44,6 +44,23 @@
44
44
  },
45
45
  "keywords": [
46
46
  "react-native",
47
+ "react-native-step-counter",
48
+ "step-counter",
49
+ "step-counter-sensor",
50
+ "pedometer",
51
+ "CMPedometer",
52
+ "CoreMotion",
53
+ "core-motion",
54
+ "ACTIVITY_RECOGNITION",
55
+ "TYPE_STEP_COUNTER",
56
+ "accelerometer",
57
+ "turbomodule",
58
+ "turbo-module",
59
+ "new-architecture",
60
+ "fabric",
61
+ "health",
62
+ "fitness",
63
+ "walking",
47
64
  "ios",
48
65
  "android"
49
66
  ],
@@ -12,6 +12,7 @@ export type CounterType = "STEP_COUNTER" | "ACCELEROMETER" | "CMPedometer";
12
12
  * distance - The distance in meters that the user has walked or run.
13
13
  * floorsAscended - number of floors ascended (iOS only)
14
14
  * floorsDescended - number of floors descended (iOS only)
15
+ * calories - estimated calories burned (Android native; iOS may include estimated value)
15
16
  */
16
17
  export type StepCountData = {
17
18
  counterType: CounterType;
@@ -21,17 +22,55 @@ export type StepCountData = {
21
22
  distance: number; // distance in meters (android: probably not accurate)
22
23
  floorsAscended?: number; // number of floors ascended (iOS only)
23
24
  floorsDescended?: number; // number of floors descended (iOS only)
25
+ calories?: number;
24
26
  };
25
27
 
28
+ export type StepCountingSupportResult = {
29
+ supported: boolean;
30
+ granted: boolean;
31
+ /** Android only: whether the sensor service is currently active */
32
+ working?: boolean;
33
+ };
34
+
35
+ export type StepCounterError = {
36
+ message: string;
37
+ code?: number;
38
+ domain?: string;
39
+ };
40
+
41
+ export type StepsSensorInfoIOS = {
42
+ name: string;
43
+ granted: boolean;
44
+ stepCounting: boolean;
45
+ pace: boolean;
46
+ cadence: boolean;
47
+ distance: boolean;
48
+ floorCounting: boolean;
49
+ };
50
+
51
+ export type StepsSensorInfoAndroid = {
52
+ name: string;
53
+ vendor: string;
54
+ minDelay: number;
55
+ maxDelay: number;
56
+ power: number;
57
+ resolution: number;
58
+ };
59
+
60
+ export type StepsSensorInfo = StepsSensorInfoIOS | StepsSensorInfoAndroid;
61
+
26
62
  export const NAME = "StepCounter";
27
63
  export const VERSION = "0.3.1";
28
64
  export const eventName = "StepCounter.stepCounterUpdate";
65
+ export const errorEventName = "StepCounter.errorOccurred";
66
+ export const sensorInfoEventName = "StepCounter.stepsSensorInfo";
67
+ export const stepDetectedEventName = "StepCounter.stepDetected";
29
68
 
30
69
  export interface Spec extends TurboModule {
31
70
  /**
32
71
  * @description Check if the step counter is supported on the device.
33
72
  * @async
34
- * @returns {Promise<{ supported: boolean; granted: boolean }>} Returns the `Promise` object,
73
+ * @returns {Promise<StepCountingSupportResult>} Returns the `Promise` object,
35
74
  * including information such as whether the user's device has a step counter sensor by default (`supported`)
36
75
  * and whether the user has allowed the app to measure the pedometer data. (`granted`)
37
76
  * granted - The permission is granted or not.
@@ -43,7 +82,13 @@ export interface Spec extends TurboModule {
43
82
  * setStepCountingGranted(granted);
44
83
  * });
45
84
  */
46
- isStepCountingSupported(): Promise<{ supported: boolean; granted: boolean }>;
85
+ isStepCountingSupported(): Promise<StepCountingSupportResult>;
86
+ /**
87
+ * Query cumulative step data for a date range. iOS only (Core Motion).
88
+ * @param startDate Unix timestamp in milliseconds.
89
+ * @param endDate Unix timestamp in milliseconds.
90
+ */
91
+ queryPedometerDataBetweenDates(startDate: number, endDate: number): Promise<StepCountData>;
47
92
  /**
48
93
  * @param {number} from the current time obtained by `new Date()` in milliseconds.
49
94
  */
package/src/index.tsx CHANGED
@@ -1,11 +1,17 @@
1
1
  import type { EventSubscription } from "react-native";
2
2
  import StepCounterModule, {
3
+ errorEventName,
3
4
  eventName,
4
5
  NAME,
6
+ sensorInfoEventName,
7
+ stepDetectedEventName,
5
8
  VERSION,
6
9
  type CounterType,
7
10
  type Spec,
8
11
  type StepCountData,
12
+ type StepCountingSupportResult,
13
+ type StepCounterError,
14
+ type StepsSensorInfo,
9
15
  } from "./NativeStepCounter";
10
16
  import { NativeEventEmitter, Platform } from "react-native";
11
17
  import { PACKAGE_NAME, REPOSITORY_WEB_URL } from "./packageMeta";
@@ -191,19 +197,104 @@ class UnavailabilityError extends Error {
191
197
  }
192
198
  }
193
199
 
200
+ function normalizeStepCounterError(payload: unknown): StepCounterError {
201
+ if (payload && typeof payload === "object") {
202
+ const errorPayload = payload as Record<string, unknown>;
203
+ const message =
204
+ typeof errorPayload.message === "string"
205
+ ? errorPayload.message
206
+ : typeof errorPayload.localizedDescription === "string"
207
+ ? errorPayload.localizedDescription
208
+ : String(payload);
209
+ return {
210
+ message,
211
+ code: typeof errorPayload.code === "number" ? errorPayload.code : undefined,
212
+ domain: typeof errorPayload.domain === "string" ? errorPayload.domain : undefined,
213
+ };
214
+ }
215
+ return { message: String(payload ?? "Unknown error") };
216
+ }
217
+
194
218
  /**
195
219
  * Returns whether the stepCounter is enabled on the device.
196
220
  * iOS 8.0+ only. Android is available since KitKat (4.4 / API 19).
197
221
  * @see https://developer.android.com/about/versions/android-4.4.html
198
222
  * @see https://developer.apple.com/documentation/coremotion/cmpedometer/1613963-isstepcountingavailable
199
- * @returns {Promise<{ supported: boolean; granted: boolean }>} A promise that resolves with an object containing the stepCounter availability.
223
+ * @returns {Promise<StepCountingSupportResult>} A promise that resolves with step counter availability.
200
224
  * supported - Whether the stepCounter is supported on device.
201
225
  * granted - Whether user granted the permission.
226
+ * working - Android only: whether the native sensor service is currently active.
202
227
  */
203
- export function isStepCountingSupported(): Promise<{ supported: boolean; granted: boolean }> {
228
+ export function isStepCountingSupported(): Promise<StepCountingSupportResult> {
204
229
  return StepCounter.isStepCountingSupported();
205
230
  }
206
231
 
232
+ /**
233
+ * Query cumulative step data for a date range. iOS only (Core Motion `CMPedometer`).
234
+ *
235
+ * Apple retains roughly seven days of pedometer history. Ranges older than that may return
236
+ * partial or empty data. This call does not stop or interfere with an active live session.
237
+ *
238
+ * @param start Start of the query range.
239
+ * @param end End of the query range. Values in the future are clamped to the current time.
240
+ */
241
+ export function queryPedometerDataBetweenDates(start: Date, end: Date): Promise<StepCountData> {
242
+ if (Platform.OS !== "ios" || !StepCounter.queryPedometerDataBetweenDates) {
243
+ throw new UnavailabilityError(NAME, "queryPedometerDataBetweenDates");
244
+ }
245
+ if (start.getTime() > end.getTime()) {
246
+ return Promise.reject(new Error("start must be before or equal to end"));
247
+ }
248
+ const now = Date.now();
249
+ const endMs = Math.min(end.getTime(), now);
250
+ return StepCounter.queryPedometerDataBetweenDates(start.getTime(), endMs);
251
+ }
252
+
253
+ /**
254
+ * Returns whether this library currently has an active live step-count subscription.
255
+ *
256
+ * This reflects the session managed by `startStepCounterUpdate` / `stopStepCounterUpdate`,
257
+ * not the Android `working` flag from `isStepCountingSupported()`.
258
+ */
259
+ export function isSensorWorking(): boolean {
260
+ return _activeSubscription !== null;
261
+ }
262
+
263
+ /**
264
+ * Subscribe to native step counter errors (`StepCounter.errorOccurred`).
265
+ */
266
+ export function addStepCounterErrorListener(
267
+ callback: (error: StepCounterError) => void
268
+ ): EventSubscription {
269
+ return StepEventEmitter.addListener(errorEventName, (payload) =>
270
+ callback(normalizeStepCounterError(payload))
271
+ );
272
+ }
273
+
274
+ /**
275
+ * Subscribe to native sensor capability metadata (`StepCounter.stepsSensorInfo`).
276
+ *
277
+ * Emitted from `isStepCountingSupported()` on iOS and when the Android sensor service starts.
278
+ */
279
+ export function addStepsSensorInfoListener(
280
+ callback: (info: StepsSensorInfo) => void
281
+ ): EventSubscription {
282
+ return StepEventEmitter.addListener(sensorInfoEventName, (payload) =>
283
+ callback(payload as StepsSensorInfo)
284
+ );
285
+ }
286
+
287
+ /**
288
+ * Subscribe to motion/step detection signals (`StepCounter.stepDetected`).
289
+ */
290
+ export function addStepDetectedListener(
291
+ callback: (detected: boolean) => void
292
+ ): EventSubscription {
293
+ return StepEventEmitter.addListener(stepDetectedEventName, (payload) =>
294
+ callback(Boolean(payload))
295
+ );
296
+ }
297
+
207
298
  /**
208
299
  * Start to subscribe stepCounter updates.
209
300
  * Only the past seven days worth of data is stored and available for you to retrieve.
@@ -255,4 +346,16 @@ export function stopStepCounterUpdate(): void {
255
346
  StepCounter.stopStepCounterUpdate();
256
347
  }
257
348
 
258
- export { NAME, VERSION, type CounterType, type StepCountData };
349
+ export {
350
+ errorEventName,
351
+ eventName,
352
+ NAME,
353
+ sensorInfoEventName,
354
+ stepDetectedEventName,
355
+ VERSION,
356
+ type CounterType,
357
+ type StepCountData,
358
+ type StepCountingSupportResult,
359
+ type StepCounterError,
360
+ type StepsSensorInfo,
361
+ };
package/README.kr.md DELETED
@@ -1,159 +0,0 @@
1
- # React-Native Step Counter Library
2
-
3
- English-speaking developers, please return to the repository main page or click [the following link](README.md)
4
-
5
- 사용자가 일정 시간 걸은 걸음 수를 계산하기 위한 리액트 네이티브 모듈입니다. 이 패키지는 Android의 `StepCounter` 센서, Android 기기에서 하드웨어 스텝 카운터를 사용할 수 없을 때의 가속도계 기반 폴백, iOS의 `Core Motion` 프레임워크를 사용합니다.
6
-
7
- ## 설치 방법
8
-
9
- ```shell
10
- npm install @blife/rn-step-counter
11
- ```
12
-
13
- ```shell
14
- yarn add @blife/rn-step-counter
15
- ```
16
-
17
- 리액트네이티브 0.60 버전 이후 설치된 네이티브 모듈은 오토 링크됩니다. 네이티브 모듈을 수동으로 연결할 필요가 없습니다.
18
-
19
- ## 요구 사항
20
-
21
- - React Native `>=0.71.0`
22
- - React Native CLI 앱. 네이티브 코드가 포함되어 있으므로 Expo Go는 지원하지 않습니다.
23
-
24
- ### ANDROID
25
-
26
- 앱에 아래 권한과 센서 feature 선언이 없다면 추가하세요.
27
-
28
- ```xml
29
- <!-- android/src/main/AndroidManifest.xml-->
30
- <manifest xmlns:android="http://schemas.android.com/apk/res/android"
31
- package="com.stepcounter">
32
- <uses-permission android:name="android.permission.ACTIVITY_RECOGNITION" />
33
- <uses-permission android:name="android.permission.BODY_SENSORS_BACKGROUND" />
34
-
35
- <uses-feature
36
- android:name="android.hardware.sensor.stepcounter"
37
- android:required="false" />
38
- <uses-feature
39
- android:name="android.hardware.sensor.accelerometer"
40
- android:required="true" />
41
- </manifest>
42
- ```
43
-
44
- ### iOS
45
-
46
- 앱의 `Info.plist`에 `NSMotionUsageDescription`을 추가하세요.
47
-
48
- ```xml plist
49
- <!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN">
50
- <plist version="1.0">
51
- ...
52
- <key>NSMotionUsageDescription</key>
53
- <string>We want to access your motion data to count your steps.</string>
54
- ...
55
- </plist>
56
- ```
57
-
58
- ## Interface
59
-
60
- - `isStepCountingSupported()`: `Promise<{ supported: boolean; granted: boolean }>`: 장치에 기능 관련 스텝 카운터 또는 가속도계가 있는지 확인하는 메서드입니다.
61
- - 응답 객체의 키 `granted`의 Boolean 값은 앱 사용자가 이 기능 사용 권한을 부여했는지 권한 허용 여부이며, `supported`는 장치가 이 기능을 지원하는지 여부입니다.
62
- - Android에서는 하드웨어 스텝 카운터를 사용할 수 없을 때 가속도계 기반 카운팅으로 폴백할 수 있습니다. 그래도 업데이트를 시작하기 전에 플랫폼의 동작/활동 권한을 요청하고 사용자의 권한 선택을 존중해야 합니다.
63
-
64
- - `startStepCounterUpdate(start: Date, callBack: StepCountUpdateCallback)`: EmitterSubscription:
65
- - 만보계 센서가 장치에서 지원되고 사용 가능한 상태인 경우 센서 매니저의 수신기 이벤트 리스너를 등록하고 스텝 카운트 이벤트 수신기를 자바스크립트에 전달합니다.
66
- - 만보계 센서가 장치에서 지원되지 않거나 사용할 수 없는 경우, 가속도계 센서를 리스너에 등록하고, 걸음을 감지하는 벡터 알고리즘 필터를 통해 걸음 이벤트를 생성한 후 앱으로 전달합니다.
67
- - `start`는 `Date` 객체로, 이벤트를 수신하기 시작할 날짜를 나타냅니다. (new Date())
68
-
69
- - `stopStepCounterUpdate()`: void:
70
- - `startStepCounterUpdate`로 등록된 구독을 제거하고 네이티브 센서 세션을 중지합니다.
71
-
72
- - `createStepCountFilter(options?: StepCountFilterOptions)`: `(data: StepCountData) => StepCountData | null`:
73
- - 손으로 휴대폰을 축을 중심으로 돌리는 것처럼 센서 오탐이 발생할 수 있는 라이브 업데이트를 걸러내기 위한 상태 기반 필터를 생성합니다.
74
- - `minimumStepIntervalMs`보다 빠른 보행 간격을 의미하는 버스트 업데이트를 버리고, 이후 누적 값에서 무시한 걸음 수를 보정합니다.
75
- - 하드웨어/OS 만보계가 이미 오탐을 걸음으로 판단한 경우 패키지는 원시 움직임 정보를 받을 수 없습니다. 앱에서 원시 센서 스트림보다 엄격한 라이브 세션 카운트가 필요할 때 이 헬퍼를 사용하세요.
76
-
77
- - `StepCountData`:
78
- - **공통 데이터**
79
- - `steps`: 지정된 기간 동안 사용자가 걸은 걸음 수를 나타내는 숫자 속성입니다.
80
- - `startDate`: 이것은 밀리세컨드로 측정 된 UNIX 타임 스탬프 형식의 데이터의 시작 날짜를 나타내는 숫자 속성입니다.
81
- - `endDate`: 이것은 밀리세컨드로 측정 된 UNIX 타임 스탬프 형식의 데이터의 종료 날짜를 나타내는 숫자 속성입니다.
82
- - `distance`: 이것은 지정된 기간 동안 사용자가 걸거나 뛴 거리를 미터로 나타내는 숫자 속성입니다. (안드로이드는 지원하지 않기 때문에 임의 설정한 상수와 걸음 수를 이용해 계산됩니다.)
83
- - `counterType`: (`CounterType`) 걸음을 감지하는 데 사용되는 센서 유형을 나타내는 유니온 타입입니다. iOS에서는 `"CMPedometer"`, 안드로이드에서는 하드웨어 만보계 센서 사용 시 `"STEP_COUNTER"`, 가속도계 폴백 사용 시 `"ACCELEROMETER"` 중 하나의 값을 가집니다.
84
-
85
- - **iOS에만 있음**
86
- - `floorsAscended`: 지정된 기간 동안 사용자가 상승한 층의 수를 나타내는 숫자 속성입니다. 기기가 이 기능을 지원하지 않으면 `nil`이 될 수 있습니다.
87
- - `floorsDescended`: 지정된 기간 동안 사용자가 하강한 층의 수를 나타내는 숫자 속성입니다. 기기가 이 기능을 지원하지 않으면 `nil`이 될 수 있습니다.
88
-
89
- ## Usage
90
-
91
- 리액트 네이티브 앱에서 이 라이브러리를 실제로 사용하려면 다음 단계를 따르세요.:
92
-
93
- 라이브러리를 리액트 네이티브 앱으로 임포트합니다.
94
-
95
- ```typescript
96
- import React, { useEffect, useState } from "react";
97
- import {
98
- createStepCountFilter,
99
- isStepCountingSupported,
100
- parseStepData,
101
- startStepCounterUpdate,
102
- stopStepCounterUpdate,
103
- } from "@blife/rn-step-counter";
104
- ```
105
-
106
- `isStepCountingSupported` 메소드를 사용하여 장치에 스텝 카운터 또는 가속도계 센서가 있는지 확인합니다.
107
-
108
- ```typescript
109
- const [supported, setSupported] = useState(false);
110
- const [granted, setGranted] = useState(false);
111
-
112
- async function askPermission() {
113
- isStepCountingSupported().then((result) => {
114
- console.debug("🚀 - isStepCountingSupported", result);
115
- setGranted(result.granted === true);
116
- setSupported(result.supported === true);
117
- });
118
- }
119
- ```
120
-
121
- 스텝 카운터를 시작하려면 `startStepCounterUpdate` 메소드를 호출합니다.
122
-
123
- ```typescript
124
- const [steps, setSteps] = useState(0);
125
-
126
- async function startStepCounter() {
127
- const filterStepCountData = createStepCountFilter();
128
-
129
- startStepCounterUpdate(new Date(), (data) => {
130
- const filteredData = filterStepCountData(data);
131
- if (!filteredData) {
132
- return;
133
- }
134
-
135
- console.debug(parseStepData(filteredData));
136
- setSteps(filteredData.steps);
137
- });
138
- }
139
- ```
140
-
141
- 다음은 `NativeStepCounter`를 사용하는 리액트 네이티브 애플리케이션의 예시입니다.
142
-
143
- 예제 앱 코드 보기: [링크](https://github.com/bonnmh/rn-step-counter/blob/main/example/src/App.tsx)
144
-
145
- ## Change Log
146
-
147
- 패키지의 버전별 변경 사항을 확인하려면 [`Release Notes`](CHANGELOG.md)를 참조하십시오.
148
-
149
- ## Contributing
150
-
151
- 리포지토리 및 개발 워크 플로에 기여하는 방법을 알고 싶으시다면 [`Contributing Guide`](CONTRIBUTING.md)를 참조하십시오.
152
-
153
- ## License
154
-
155
- MIT
156
-
157
- ---
158
-
159
- [CallStack](https://callstack.com/)의 [create-react-native-library](https://github.com/callstack/react-native-builder-bob/tree/main/packages/create-react-native-library)를 사용해 개발했습니다.