community-cordova-plugin-magnetometer 1.0.1
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/.idea/community-cordova-plugin-magnetometer.iml +8 -0
- package/.idea/modules.xml +8 -0
- package/.idea/vcs.xml +6 -0
- package/CHANGELOG.md +27 -0
- package/README.md +383 -0
- package/package.json +48 -0
- package/plugin.xml +54 -0
- package/src/android/Magnetometer.java +524 -0
- package/src/browser/MagnetometerProxy.js +300 -0
- package/src/ios/CDVMagnetometer.h +26 -0
- package/src/ios/CDVMagnetometer.m +321 -0
- package/types/index.d.ts +150 -0
- package/www/magnetometer.js +122 -0
|
@@ -0,0 +1,524 @@
|
|
|
1
|
+
package com.community.cordova.magnetometer;
|
|
2
|
+
|
|
3
|
+
import android.content.Context;
|
|
4
|
+
import android.hardware.Sensor;
|
|
5
|
+
import android.hardware.SensorEvent;
|
|
6
|
+
import android.hardware.SensorEventListener;
|
|
7
|
+
import android.hardware.SensorManager;
|
|
8
|
+
import android.os.Handler;
|
|
9
|
+
import android.os.Looper;
|
|
10
|
+
import android.util.Log;
|
|
11
|
+
|
|
12
|
+
import org.apache.cordova.CallbackContext;
|
|
13
|
+
import org.apache.cordova.CordovaPlugin;
|
|
14
|
+
import org.apache.cordova.PluginResult;
|
|
15
|
+
import org.json.JSONArray;
|
|
16
|
+
import org.json.JSONException;
|
|
17
|
+
import org.json.JSONObject;
|
|
18
|
+
|
|
19
|
+
public class Magnetometer extends CordovaPlugin implements SensorEventListener {
|
|
20
|
+
|
|
21
|
+
private static final String LOG_TAG = "Magnetometer";
|
|
22
|
+
|
|
23
|
+
private SensorManager sensorManager;
|
|
24
|
+
private Sensor magnetometer;
|
|
25
|
+
private Sensor rotationVector;
|
|
26
|
+
|
|
27
|
+
private CallbackContext watchCallbackContext;
|
|
28
|
+
private CallbackContext watchHeadingCallbackContext;
|
|
29
|
+
|
|
30
|
+
private float[] magnetometerValues = new float[3];
|
|
31
|
+
private float[] rotationMatrix = new float[9];
|
|
32
|
+
private float[] orientationValues = new float[3];
|
|
33
|
+
|
|
34
|
+
private int currentAccuracy = SensorManager.SENSOR_STATUS_ACCURACY_HIGH;
|
|
35
|
+
private boolean calibrationNeeded = false;
|
|
36
|
+
|
|
37
|
+
private Handler handler;
|
|
38
|
+
private Runnable watchRunnable;
|
|
39
|
+
private Runnable watchHeadingRunnable;
|
|
40
|
+
|
|
41
|
+
@Override
|
|
42
|
+
protected void pluginInitialize() {
|
|
43
|
+
sensorManager = (SensorManager) cordova.getActivity().getSystemService(Context.SENSOR_SERVICE);
|
|
44
|
+
magnetometer = sensorManager.getDefaultSensor(Sensor.TYPE_MAGNETIC_FIELD);
|
|
45
|
+
rotationVector = sensorManager.getDefaultSensor(Sensor.TYPE_ROTATION_VECTOR);
|
|
46
|
+
handler = new Handler(Looper.getMainLooper());
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
@Override
|
|
50
|
+
public boolean execute(String action, JSONArray args, CallbackContext callbackContext) throws JSONException {
|
|
51
|
+
switch (action) {
|
|
52
|
+
case "isAvailable":
|
|
53
|
+
isAvailable(callbackContext);
|
|
54
|
+
return true;
|
|
55
|
+
case "getReading":
|
|
56
|
+
getReading(callbackContext);
|
|
57
|
+
return true;
|
|
58
|
+
case "getHeading":
|
|
59
|
+
getHeading(callbackContext);
|
|
60
|
+
return true;
|
|
61
|
+
case "watchReadings":
|
|
62
|
+
int frequency = args.optInt(0, 100);
|
|
63
|
+
watchReadings(callbackContext, frequency);
|
|
64
|
+
return true;
|
|
65
|
+
case "stopWatch":
|
|
66
|
+
stopWatch(callbackContext);
|
|
67
|
+
return true;
|
|
68
|
+
case "watchHeading":
|
|
69
|
+
int headingFrequency = args.optInt(0, 100);
|
|
70
|
+
watchHeading(callbackContext, headingFrequency);
|
|
71
|
+
return true;
|
|
72
|
+
case "stopWatchHeading":
|
|
73
|
+
stopWatchHeading(callbackContext);
|
|
74
|
+
return true;
|
|
75
|
+
case "getMagnetometerInfo":
|
|
76
|
+
getMagnetometerInfo(callbackContext);
|
|
77
|
+
return true;
|
|
78
|
+
case "getAccuracy":
|
|
79
|
+
getAccuracy(callbackContext);
|
|
80
|
+
return true;
|
|
81
|
+
case "isCalibrationNeeded":
|
|
82
|
+
isCalibrationNeeded(callbackContext);
|
|
83
|
+
return true;
|
|
84
|
+
case "getFieldStrength":
|
|
85
|
+
getFieldStrength(callbackContext);
|
|
86
|
+
return true;
|
|
87
|
+
default:
|
|
88
|
+
return false;
|
|
89
|
+
}
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
private void isAvailable(CallbackContext callbackContext) {
|
|
93
|
+
boolean available = magnetometer != null;
|
|
94
|
+
callbackContext.success(available ? 1 : 0);
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
private void getReading(final CallbackContext callbackContext) {
|
|
98
|
+
if (magnetometer == null) {
|
|
99
|
+
callbackContext.error("Magnetometer not available");
|
|
100
|
+
return;
|
|
101
|
+
}
|
|
102
|
+
|
|
103
|
+
cordova.getThreadPool().execute(new Runnable() {
|
|
104
|
+
@Override
|
|
105
|
+
public void run() {
|
|
106
|
+
final boolean[] dataReceived = {false};
|
|
107
|
+
|
|
108
|
+
SensorEventListener listener = new SensorEventListener() {
|
|
109
|
+
@Override
|
|
110
|
+
public void onSensorChanged(SensorEvent event) {
|
|
111
|
+
if (!dataReceived[0] && event.sensor.getType() == Sensor.TYPE_MAGNETIC_FIELD) {
|
|
112
|
+
dataReceived[0] = true;
|
|
113
|
+
sensorManager.unregisterListener(this);
|
|
114
|
+
|
|
115
|
+
try {
|
|
116
|
+
JSONObject reading = createReadingObject(event.values);
|
|
117
|
+
callbackContext.success(reading);
|
|
118
|
+
} catch (JSONException e) {
|
|
119
|
+
callbackContext.error("Failed to create reading: " + e.getMessage());
|
|
120
|
+
}
|
|
121
|
+
}
|
|
122
|
+
}
|
|
123
|
+
|
|
124
|
+
@Override
|
|
125
|
+
public void onAccuracyChanged(Sensor sensor, int accuracy) {
|
|
126
|
+
currentAccuracy = accuracy;
|
|
127
|
+
calibrationNeeded = accuracy < SensorManager.SENSOR_STATUS_ACCURACY_MEDIUM;
|
|
128
|
+
}
|
|
129
|
+
};
|
|
130
|
+
|
|
131
|
+
sensorManager.registerListener(listener, magnetometer, SensorManager.SENSOR_DELAY_UI);
|
|
132
|
+
|
|
133
|
+
// Timeout after 1 second
|
|
134
|
+
handler.postDelayed(new Runnable() {
|
|
135
|
+
@Override
|
|
136
|
+
public void run() {
|
|
137
|
+
if (!dataReceived[0]) {
|
|
138
|
+
dataReceived[0] = true;
|
|
139
|
+
callbackContext.error("Timeout waiting for magnetometer reading");
|
|
140
|
+
}
|
|
141
|
+
}
|
|
142
|
+
}, 1000);
|
|
143
|
+
}
|
|
144
|
+
});
|
|
145
|
+
}
|
|
146
|
+
|
|
147
|
+
private void getHeading(final CallbackContext callbackContext) {
|
|
148
|
+
if (magnetometer == null) {
|
|
149
|
+
callbackContext.error("Magnetometer not available");
|
|
150
|
+
return;
|
|
151
|
+
}
|
|
152
|
+
|
|
153
|
+
cordova.getThreadPool().execute(new Runnable() {
|
|
154
|
+
@Override
|
|
155
|
+
public void run() {
|
|
156
|
+
final boolean[] dataReceived = {false};
|
|
157
|
+
final float[] magValues = new float[3];
|
|
158
|
+
final float[] accelValues = new float[3];
|
|
159
|
+
final boolean[] hasMag = {false};
|
|
160
|
+
final boolean[] hasAccel = {false};
|
|
161
|
+
|
|
162
|
+
Sensor accelerometer = sensorManager.getDefaultSensor(Sensor.TYPE_ACCELEROMETER);
|
|
163
|
+
|
|
164
|
+
SensorEventListener listener = new SensorEventListener() {
|
|
165
|
+
@Override
|
|
166
|
+
public void onSensorChanged(SensorEvent event) {
|
|
167
|
+
if (dataReceived[0]) return;
|
|
168
|
+
|
|
169
|
+
if (event.sensor.getType() == Sensor.TYPE_MAGNETIC_FIELD) {
|
|
170
|
+
System.arraycopy(event.values, 0, magValues, 0, 3);
|
|
171
|
+
hasMag[0] = true;
|
|
172
|
+
} else if (event.sensor.getType() == Sensor.TYPE_ACCELEROMETER) {
|
|
173
|
+
System.arraycopy(event.values, 0, accelValues, 0, 3);
|
|
174
|
+
hasAccel[0] = true;
|
|
175
|
+
}
|
|
176
|
+
|
|
177
|
+
if (hasMag[0] && hasAccel[0]) {
|
|
178
|
+
dataReceived[0] = true;
|
|
179
|
+
sensorManager.unregisterListener(this);
|
|
180
|
+
|
|
181
|
+
try {
|
|
182
|
+
JSONObject heading = calculateHeading(magValues, accelValues);
|
|
183
|
+
callbackContext.success(heading);
|
|
184
|
+
} catch (JSONException e) {
|
|
185
|
+
callbackContext.error("Failed to calculate heading: " + e.getMessage());
|
|
186
|
+
}
|
|
187
|
+
}
|
|
188
|
+
}
|
|
189
|
+
|
|
190
|
+
@Override
|
|
191
|
+
public void onAccuracyChanged(Sensor sensor, int accuracy) {
|
|
192
|
+
if (sensor.getType() == Sensor.TYPE_MAGNETIC_FIELD) {
|
|
193
|
+
currentAccuracy = accuracy;
|
|
194
|
+
calibrationNeeded = accuracy < SensorManager.SENSOR_STATUS_ACCURACY_MEDIUM;
|
|
195
|
+
}
|
|
196
|
+
}
|
|
197
|
+
};
|
|
198
|
+
|
|
199
|
+
sensorManager.registerListener(listener, magnetometer, SensorManager.SENSOR_DELAY_UI);
|
|
200
|
+
if (accelerometer != null) {
|
|
201
|
+
sensorManager.registerListener(listener, accelerometer, SensorManager.SENSOR_DELAY_UI);
|
|
202
|
+
}
|
|
203
|
+
|
|
204
|
+
// Timeout after 1 second
|
|
205
|
+
handler.postDelayed(new Runnable() {
|
|
206
|
+
@Override
|
|
207
|
+
public void run() {
|
|
208
|
+
if (!dataReceived[0]) {
|
|
209
|
+
dataReceived[0] = true;
|
|
210
|
+
callbackContext.error("Timeout waiting for heading");
|
|
211
|
+
}
|
|
212
|
+
}
|
|
213
|
+
}, 1000);
|
|
214
|
+
}
|
|
215
|
+
});
|
|
216
|
+
}
|
|
217
|
+
|
|
218
|
+
private void watchReadings(CallbackContext callbackContext, final int frequency) {
|
|
219
|
+
if (magnetometer == null) {
|
|
220
|
+
callbackContext.error("Magnetometer not available");
|
|
221
|
+
return;
|
|
222
|
+
}
|
|
223
|
+
|
|
224
|
+
// Stop existing watch
|
|
225
|
+
if (watchCallbackContext != null) {
|
|
226
|
+
sensorManager.unregisterListener(this, magnetometer);
|
|
227
|
+
}
|
|
228
|
+
|
|
229
|
+
watchCallbackContext = callbackContext;
|
|
230
|
+
|
|
231
|
+
int sensorDelay = getSensorDelay(frequency);
|
|
232
|
+
sensorManager.registerListener(this, magnetometer, sensorDelay);
|
|
233
|
+
|
|
234
|
+
PluginResult result = new PluginResult(PluginResult.Status.NO_RESULT);
|
|
235
|
+
result.setKeepCallback(true);
|
|
236
|
+
callbackContext.sendPluginResult(result);
|
|
237
|
+
}
|
|
238
|
+
|
|
239
|
+
private void stopWatch(CallbackContext callbackContext) {
|
|
240
|
+
if (watchCallbackContext != null) {
|
|
241
|
+
sensorManager.unregisterListener(this, magnetometer);
|
|
242
|
+
watchCallbackContext = null;
|
|
243
|
+
}
|
|
244
|
+
callbackContext.success();
|
|
245
|
+
}
|
|
246
|
+
|
|
247
|
+
private void watchHeading(CallbackContext callbackContext, final int frequency) {
|
|
248
|
+
if (magnetometer == null) {
|
|
249
|
+
callbackContext.error("Magnetometer not available");
|
|
250
|
+
return;
|
|
251
|
+
}
|
|
252
|
+
|
|
253
|
+
// Stop existing watch
|
|
254
|
+
if (watchHeadingCallbackContext != null) {
|
|
255
|
+
stopHeadingSensors();
|
|
256
|
+
}
|
|
257
|
+
|
|
258
|
+
watchHeadingCallbackContext = callbackContext;
|
|
259
|
+
|
|
260
|
+
int sensorDelay = getSensorDelay(frequency);
|
|
261
|
+
Sensor accelerometer = sensorManager.getDefaultSensor(Sensor.TYPE_ACCELEROMETER);
|
|
262
|
+
|
|
263
|
+
sensorManager.registerListener(headingListener, magnetometer, sensorDelay);
|
|
264
|
+
if (accelerometer != null) {
|
|
265
|
+
sensorManager.registerListener(headingListener, accelerometer, sensorDelay);
|
|
266
|
+
}
|
|
267
|
+
|
|
268
|
+
PluginResult result = new PluginResult(PluginResult.Status.NO_RESULT);
|
|
269
|
+
result.setKeepCallback(true);
|
|
270
|
+
callbackContext.sendPluginResult(result);
|
|
271
|
+
}
|
|
272
|
+
|
|
273
|
+
private void stopWatchHeading(CallbackContext callbackContext) {
|
|
274
|
+
stopHeadingSensors();
|
|
275
|
+
watchHeadingCallbackContext = null;
|
|
276
|
+
callbackContext.success();
|
|
277
|
+
}
|
|
278
|
+
|
|
279
|
+
private void stopHeadingSensors() {
|
|
280
|
+
sensorManager.unregisterListener(headingListener);
|
|
281
|
+
}
|
|
282
|
+
|
|
283
|
+
private final float[] headingMagValues = new float[3];
|
|
284
|
+
private final float[] headingAccelValues = new float[3];
|
|
285
|
+
private boolean headingHasMag = false;
|
|
286
|
+
private boolean headingHasAccel = false;
|
|
287
|
+
|
|
288
|
+
private SensorEventListener headingListener = new SensorEventListener() {
|
|
289
|
+
@Override
|
|
290
|
+
public void onSensorChanged(SensorEvent event) {
|
|
291
|
+
if (watchHeadingCallbackContext == null) return;
|
|
292
|
+
|
|
293
|
+
if (event.sensor.getType() == Sensor.TYPE_MAGNETIC_FIELD) {
|
|
294
|
+
System.arraycopy(event.values, 0, headingMagValues, 0, 3);
|
|
295
|
+
headingHasMag = true;
|
|
296
|
+
} else if (event.sensor.getType() == Sensor.TYPE_ACCELEROMETER) {
|
|
297
|
+
System.arraycopy(event.values, 0, headingAccelValues, 0, 3);
|
|
298
|
+
headingHasAccel = true;
|
|
299
|
+
}
|
|
300
|
+
|
|
301
|
+
if (headingHasMag && headingHasAccel) {
|
|
302
|
+
try {
|
|
303
|
+
JSONObject heading = calculateHeading(headingMagValues, headingAccelValues);
|
|
304
|
+
PluginResult result = new PluginResult(PluginResult.Status.OK, heading);
|
|
305
|
+
result.setKeepCallback(true);
|
|
306
|
+
watchHeadingCallbackContext.sendPluginResult(result);
|
|
307
|
+
} catch (JSONException e) {
|
|
308
|
+
Log.e(LOG_TAG, "Error calculating heading: " + e.getMessage());
|
|
309
|
+
}
|
|
310
|
+
}
|
|
311
|
+
}
|
|
312
|
+
|
|
313
|
+
@Override
|
|
314
|
+
public void onAccuracyChanged(Sensor sensor, int accuracy) {
|
|
315
|
+
if (sensor.getType() == Sensor.TYPE_MAGNETIC_FIELD) {
|
|
316
|
+
currentAccuracy = accuracy;
|
|
317
|
+
calibrationNeeded = accuracy < SensorManager.SENSOR_STATUS_ACCURACY_MEDIUM;
|
|
318
|
+
}
|
|
319
|
+
}
|
|
320
|
+
};
|
|
321
|
+
|
|
322
|
+
private void getMagnetometerInfo(final CallbackContext callbackContext) {
|
|
323
|
+
cordova.getThreadPool().execute(new Runnable() {
|
|
324
|
+
@Override
|
|
325
|
+
public void run() {
|
|
326
|
+
try {
|
|
327
|
+
JSONObject info = new JSONObject();
|
|
328
|
+
info.put("isAvailable", magnetometer != null);
|
|
329
|
+
info.put("accuracy", currentAccuracy);
|
|
330
|
+
info.put("calibrationNeeded", calibrationNeeded);
|
|
331
|
+
info.put("platform", "android");
|
|
332
|
+
|
|
333
|
+
if (magnetometer != null) {
|
|
334
|
+
final boolean[] dataReceived = {false};
|
|
335
|
+
final JSONObject[] readingObj = {null};
|
|
336
|
+
|
|
337
|
+
SensorEventListener listener = new SensorEventListener() {
|
|
338
|
+
@Override
|
|
339
|
+
public void onSensorChanged(SensorEvent event) {
|
|
340
|
+
if (!dataReceived[0] && event.sensor.getType() == Sensor.TYPE_MAGNETIC_FIELD) {
|
|
341
|
+
dataReceived[0] = true;
|
|
342
|
+
sensorManager.unregisterListener(this);
|
|
343
|
+
try {
|
|
344
|
+
readingObj[0] = createReadingObject(event.values);
|
|
345
|
+
} catch (JSONException e) {
|
|
346
|
+
Log.e(LOG_TAG, "Error creating reading: " + e.getMessage());
|
|
347
|
+
}
|
|
348
|
+
synchronized (readingObj) {
|
|
349
|
+
readingObj.notify();
|
|
350
|
+
}
|
|
351
|
+
}
|
|
352
|
+
}
|
|
353
|
+
|
|
354
|
+
@Override
|
|
355
|
+
public void onAccuracyChanged(Sensor sensor, int accuracy) {}
|
|
356
|
+
};
|
|
357
|
+
|
|
358
|
+
sensorManager.registerListener(listener, magnetometer, SensorManager.SENSOR_DELAY_UI);
|
|
359
|
+
|
|
360
|
+
synchronized (readingObj) {
|
|
361
|
+
try {
|
|
362
|
+
readingObj.wait(500);
|
|
363
|
+
} catch (InterruptedException e) {
|
|
364
|
+
// Ignored
|
|
365
|
+
}
|
|
366
|
+
}
|
|
367
|
+
|
|
368
|
+
if (readingObj[0] != null) {
|
|
369
|
+
info.put("reading", readingObj[0]);
|
|
370
|
+
}
|
|
371
|
+
}
|
|
372
|
+
|
|
373
|
+
callbackContext.success(info);
|
|
374
|
+
} catch (JSONException e) {
|
|
375
|
+
callbackContext.error("Failed to get magnetometer info: " + e.getMessage());
|
|
376
|
+
}
|
|
377
|
+
}
|
|
378
|
+
});
|
|
379
|
+
}
|
|
380
|
+
|
|
381
|
+
private void getAccuracy(CallbackContext callbackContext) {
|
|
382
|
+
callbackContext.success(currentAccuracy);
|
|
383
|
+
}
|
|
384
|
+
|
|
385
|
+
private void isCalibrationNeeded(CallbackContext callbackContext) {
|
|
386
|
+
callbackContext.success(calibrationNeeded ? 1 : 0);
|
|
387
|
+
}
|
|
388
|
+
|
|
389
|
+
private void getFieldStrength(final CallbackContext callbackContext) {
|
|
390
|
+
if (magnetometer == null) {
|
|
391
|
+
callbackContext.error("Magnetometer not available");
|
|
392
|
+
return;
|
|
393
|
+
}
|
|
394
|
+
|
|
395
|
+
cordova.getThreadPool().execute(new Runnable() {
|
|
396
|
+
@Override
|
|
397
|
+
public void run() {
|
|
398
|
+
final boolean[] dataReceived = {false};
|
|
399
|
+
|
|
400
|
+
SensorEventListener listener = new SensorEventListener() {
|
|
401
|
+
@Override
|
|
402
|
+
public void onSensorChanged(SensorEvent event) {
|
|
403
|
+
if (!dataReceived[0] && event.sensor.getType() == Sensor.TYPE_MAGNETIC_FIELD) {
|
|
404
|
+
dataReceived[0] = true;
|
|
405
|
+
sensorManager.unregisterListener(this);
|
|
406
|
+
|
|
407
|
+
float x = event.values[0];
|
|
408
|
+
float y = event.values[1];
|
|
409
|
+
float z = event.values[2];
|
|
410
|
+
double magnitude = Math.sqrt(x * x + y * y + z * z);
|
|
411
|
+
|
|
412
|
+
callbackContext.success((int) Math.round(magnitude));
|
|
413
|
+
}
|
|
414
|
+
}
|
|
415
|
+
|
|
416
|
+
@Override
|
|
417
|
+
public void onAccuracyChanged(Sensor sensor, int accuracy) {}
|
|
418
|
+
};
|
|
419
|
+
|
|
420
|
+
sensorManager.registerListener(listener, magnetometer, SensorManager.SENSOR_DELAY_UI);
|
|
421
|
+
|
|
422
|
+
handler.postDelayed(new Runnable() {
|
|
423
|
+
@Override
|
|
424
|
+
public void run() {
|
|
425
|
+
if (!dataReceived[0]) {
|
|
426
|
+
dataReceived[0] = true;
|
|
427
|
+
callbackContext.error("Timeout waiting for field strength");
|
|
428
|
+
}
|
|
429
|
+
}
|
|
430
|
+
}, 1000);
|
|
431
|
+
}
|
|
432
|
+
});
|
|
433
|
+
}
|
|
434
|
+
|
|
435
|
+
@Override
|
|
436
|
+
public void onSensorChanged(SensorEvent event) {
|
|
437
|
+
if (watchCallbackContext != null && event.sensor.getType() == Sensor.TYPE_MAGNETIC_FIELD) {
|
|
438
|
+
try {
|
|
439
|
+
JSONObject reading = createReadingObject(event.values);
|
|
440
|
+
PluginResult result = new PluginResult(PluginResult.Status.OK, reading);
|
|
441
|
+
result.setKeepCallback(true);
|
|
442
|
+
watchCallbackContext.sendPluginResult(result);
|
|
443
|
+
} catch (JSONException e) {
|
|
444
|
+
Log.e(LOG_TAG, "Error sending reading: " + e.getMessage());
|
|
445
|
+
}
|
|
446
|
+
}
|
|
447
|
+
}
|
|
448
|
+
|
|
449
|
+
@Override
|
|
450
|
+
public void onAccuracyChanged(Sensor sensor, int accuracy) {
|
|
451
|
+
if (sensor.getType() == Sensor.TYPE_MAGNETIC_FIELD) {
|
|
452
|
+
currentAccuracy = accuracy;
|
|
453
|
+
calibrationNeeded = accuracy < SensorManager.SENSOR_STATUS_ACCURACY_MEDIUM;
|
|
454
|
+
}
|
|
455
|
+
}
|
|
456
|
+
|
|
457
|
+
private JSONObject createReadingObject(float[] values) throws JSONException {
|
|
458
|
+
float x = values[0];
|
|
459
|
+
float y = values[1];
|
|
460
|
+
float z = values[2];
|
|
461
|
+
double magnitude = Math.sqrt(x * x + y * y + z * z);
|
|
462
|
+
|
|
463
|
+
JSONObject reading = new JSONObject();
|
|
464
|
+
reading.put("x", x);
|
|
465
|
+
reading.put("y", y);
|
|
466
|
+
reading.put("z", z);
|
|
467
|
+
reading.put("magnitude", magnitude);
|
|
468
|
+
reading.put("timestamp", System.currentTimeMillis());
|
|
469
|
+
|
|
470
|
+
return reading;
|
|
471
|
+
}
|
|
472
|
+
|
|
473
|
+
private JSONObject calculateHeading(float[] magValues, float[] accelValues) throws JSONException {
|
|
474
|
+
float[] R = new float[9];
|
|
475
|
+
float[] I = new float[9];
|
|
476
|
+
|
|
477
|
+
boolean success = SensorManager.getRotationMatrix(R, I, accelValues, magValues);
|
|
478
|
+
|
|
479
|
+
float azimuth = 0;
|
|
480
|
+
if (success) {
|
|
481
|
+
float[] orientation = new float[3];
|
|
482
|
+
SensorManager.getOrientation(R, orientation);
|
|
483
|
+
azimuth = (float) Math.toDegrees(orientation[0]);
|
|
484
|
+
if (azimuth < 0) {
|
|
485
|
+
azimuth += 360;
|
|
486
|
+
}
|
|
487
|
+
}
|
|
488
|
+
|
|
489
|
+
JSONObject heading = new JSONObject();
|
|
490
|
+
heading.put("magneticHeading", azimuth);
|
|
491
|
+
heading.put("trueHeading", azimuth); // True heading requires GPS, using magnetic as fallback
|
|
492
|
+
heading.put("headingAccuracy", -1); // Not available on Android
|
|
493
|
+
heading.put("timestamp", System.currentTimeMillis());
|
|
494
|
+
|
|
495
|
+
return heading;
|
|
496
|
+
}
|
|
497
|
+
|
|
498
|
+
private int getSensorDelay(int frequencyMs) {
|
|
499
|
+
if (frequencyMs <= 20) {
|
|
500
|
+
return SensorManager.SENSOR_DELAY_FASTEST;
|
|
501
|
+
} else if (frequencyMs <= 60) {
|
|
502
|
+
return SensorManager.SENSOR_DELAY_GAME;
|
|
503
|
+
} else if (frequencyMs <= 200) {
|
|
504
|
+
return SensorManager.SENSOR_DELAY_UI;
|
|
505
|
+
} else {
|
|
506
|
+
return SensorManager.SENSOR_DELAY_NORMAL;
|
|
507
|
+
}
|
|
508
|
+
}
|
|
509
|
+
|
|
510
|
+
@Override
|
|
511
|
+
public void onReset() {
|
|
512
|
+
if (watchCallbackContext != null) {
|
|
513
|
+
sensorManager.unregisterListener(this, magnetometer);
|
|
514
|
+
watchCallbackContext = null;
|
|
515
|
+
}
|
|
516
|
+
stopHeadingSensors();
|
|
517
|
+
watchHeadingCallbackContext = null;
|
|
518
|
+
}
|
|
519
|
+
|
|
520
|
+
@Override
|
|
521
|
+
public void onDestroy() {
|
|
522
|
+
onReset();
|
|
523
|
+
}
|
|
524
|
+
}
|