web-step-counter-pro 1.0.1 → 1.0.4
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/package.json +2 -4
- package/step-counter.js +67 -11
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "web-step-counter-pro",
|
|
3
|
-
"version": "1.0.
|
|
3
|
+
"version": "1.0.4",
|
|
4
4
|
"description": "A professional-grade web step counting library with advanced anti-cheat mechanisms (GPS, Gyroscope, Rhythm Analysis).",
|
|
5
5
|
"main": "step-counter.js",
|
|
6
6
|
"type": "module",
|
|
@@ -23,7 +23,5 @@
|
|
|
23
23
|
"README.md",
|
|
24
24
|
"package.json"
|
|
25
25
|
],
|
|
26
|
-
"dependencies": {
|
|
27
|
-
|
|
28
|
-
}
|
|
26
|
+
"dependencies": {}
|
|
29
27
|
}
|
package/step-counter.js
CHANGED
|
@@ -49,6 +49,7 @@ export class WebStepCounter {
|
|
|
49
49
|
gpsAccuracyLimit: 20,
|
|
50
50
|
maxSpeed: 2.8,
|
|
51
51
|
debug: false,
|
|
52
|
+
autoPauseOnBackground: true, // 新增: Capacitor 环境下切后台自动暂停传感器
|
|
52
53
|
onStep: null,
|
|
53
54
|
onStatus: null,
|
|
54
55
|
onSensorData: null,
|
|
@@ -58,6 +59,7 @@ export class WebStepCounter {
|
|
|
58
59
|
// 内部状态
|
|
59
60
|
this.stepCount = 0;
|
|
60
61
|
this.isTracking = false;
|
|
62
|
+
this.isPausedByBackground = false; // 新增: 标记是否因后台而暂停
|
|
61
63
|
this.candidateSteps = 0;
|
|
62
64
|
this.lastStepTime = 0;
|
|
63
65
|
this.lastCandidateStepTime = 0;
|
|
@@ -76,6 +78,9 @@ export class WebStepCounter {
|
|
|
76
78
|
|
|
77
79
|
this.orientationData = { alpha: 0, beta: 0, gamma: 0 };
|
|
78
80
|
|
|
81
|
+
// 节流控制
|
|
82
|
+
this._lastUiUpdate = 0;
|
|
83
|
+
|
|
79
84
|
this.handleMotion = this.handleMotion.bind(this);
|
|
80
85
|
this.handleOrientation = this.handleOrientation.bind(this);
|
|
81
86
|
this.handleGeolocation = this.handleGeolocation.bind(this);
|
|
@@ -84,13 +89,21 @@ export class WebStepCounter {
|
|
|
84
89
|
async start() {
|
|
85
90
|
if (this.isTracking) return;
|
|
86
91
|
|
|
87
|
-
|
|
92
|
+
const isCapacitor = !!window.Capacitor;
|
|
93
|
+
|
|
94
|
+
// 1. HTTPS 检查 (Capacitor 环境豁免)
|
|
95
|
+
if (!isCapacitor && location.protocol !== 'https:' && location.hostname !== 'localhost' && location.hostname !== '127.0.0.1') {
|
|
88
96
|
this._reportStatus("必须使用 HTTPS 协议", WebStepCounter.StatusType.ERROR, WebStepCounter.StatusCode.HTTPS_REQUIRED);
|
|
89
97
|
return false;
|
|
90
98
|
}
|
|
91
99
|
|
|
92
100
|
this._reportStatus("正在请求传感器权限...", WebStepCounter.StatusType.INFO);
|
|
93
101
|
|
|
102
|
+
// Capacitor 优化: 绑定生命周期
|
|
103
|
+
if (isCapacitor && this.config.autoPauseOnBackground) {
|
|
104
|
+
this._initCapacitorLifecycle();
|
|
105
|
+
}
|
|
106
|
+
|
|
94
107
|
const permissionGranted = await this._requestPermissions();
|
|
95
108
|
if (!permissionGranted) return false;
|
|
96
109
|
|
|
@@ -109,13 +122,19 @@ export class WebStepCounter {
|
|
|
109
122
|
|
|
110
123
|
stop() {
|
|
111
124
|
this.isTracking = false;
|
|
112
|
-
|
|
113
|
-
window.removeEventListener('deviceorientation', this.handleOrientation);
|
|
114
|
-
window.removeEventListener('deviceorientationabsolute', this.handleOrientation);
|
|
125
|
+
this._removeSensors();
|
|
115
126
|
|
|
116
127
|
if (this.watchId) {
|
|
117
128
|
navigator.geolocation.clearWatch(this.watchId);
|
|
129
|
+
this.watchId = null;
|
|
118
130
|
}
|
|
131
|
+
|
|
132
|
+
// 清理 Capacitor 监听
|
|
133
|
+
if (this.appListener) {
|
|
134
|
+
this.appListener.remove();
|
|
135
|
+
this.appListener = null;
|
|
136
|
+
}
|
|
137
|
+
|
|
119
138
|
this._reportStatus("已停止", WebStepCounter.StatusType.INFO);
|
|
120
139
|
}
|
|
121
140
|
|
|
@@ -147,6 +166,49 @@ export class WebStepCounter {
|
|
|
147
166
|
|
|
148
167
|
// --- Internal ---
|
|
149
168
|
|
|
169
|
+
// Capacitor 生命周期处理
|
|
170
|
+
_initCapacitorLifecycle() {
|
|
171
|
+
if (!window.Capacitor || !window.Capacitor.Plugins || !window.Capacitor.Plugins.App) return;
|
|
172
|
+
|
|
173
|
+
const App = window.Capacitor.Plugins.App;
|
|
174
|
+
|
|
175
|
+
// 监听 App 状态变化
|
|
176
|
+
this.appListener = App.addListener('appStateChange', ({ isActive }) => {
|
|
177
|
+
if (!this.isTracking) return;
|
|
178
|
+
|
|
179
|
+
if (!isActive) {
|
|
180
|
+
// 切到后台: 暂停传感器以省电,并防止 iOS 冻结导致的异常数据
|
|
181
|
+
this._reportStatus("App 进入后台,暂停计步", WebStepCounter.StatusType.INFO);
|
|
182
|
+
this._removeSensors();
|
|
183
|
+
this.isPausedByBackground = true;
|
|
184
|
+
} else {
|
|
185
|
+
// 切回前台: 恢复
|
|
186
|
+
if (this.isPausedByBackground) {
|
|
187
|
+
this._reportStatus("App 回到前台,恢复计步", WebStepCounter.StatusType.INFO);
|
|
188
|
+
this._addSensors();
|
|
189
|
+
this.isPausedByBackground = false;
|
|
190
|
+
}
|
|
191
|
+
}
|
|
192
|
+
});
|
|
193
|
+
}
|
|
194
|
+
|
|
195
|
+
_addSensors() {
|
|
196
|
+
window.addEventListener('devicemotion', this.handleMotion);
|
|
197
|
+
// 重新检查环境支持情况来决定添加哪个 Orientation 事件
|
|
198
|
+
if (window.DeviceOrientationEvent) {
|
|
199
|
+
window.addEventListener('deviceorientation', this.handleOrientation);
|
|
200
|
+
}
|
|
201
|
+
if ('ondeviceorientationabsolute' in window) {
|
|
202
|
+
window.addEventListener('deviceorientationabsolute', this.handleOrientation);
|
|
203
|
+
}
|
|
204
|
+
}
|
|
205
|
+
|
|
206
|
+
_removeSensors() {
|
|
207
|
+
window.removeEventListener('devicemotion', this.handleMotion);
|
|
208
|
+
window.removeEventListener('deviceorientation', this.handleOrientation);
|
|
209
|
+
window.removeEventListener('deviceorientationabsolute', this.handleOrientation);
|
|
210
|
+
}
|
|
211
|
+
|
|
150
212
|
async _requestPermissions() {
|
|
151
213
|
if (typeof DeviceMotionEvent !== 'undefined' && typeof DeviceMotionEvent.requestPermission === 'function') {
|
|
152
214
|
try {
|
|
@@ -175,13 +237,7 @@ export class WebStepCounter {
|
|
|
175
237
|
return false;
|
|
176
238
|
}
|
|
177
239
|
} else {
|
|
178
|
-
|
|
179
|
-
if (window.DeviceOrientationEvent) {
|
|
180
|
-
window.addEventListener('deviceorientation', this.handleOrientation);
|
|
181
|
-
}
|
|
182
|
-
if ('ondeviceorientationabsolute' in window) {
|
|
183
|
-
window.addEventListener('deviceorientationabsolute', this.handleOrientation);
|
|
184
|
-
}
|
|
240
|
+
this._addSensors();
|
|
185
241
|
}
|
|
186
242
|
return true;
|
|
187
243
|
}
|