Skip to content

Instantly share code, notes, and snippets.

@naderio
Created January 30, 2016 20:15
Show Gist options
  • Save naderio/e3c806188ddfaac3906f to your computer and use it in GitHub Desktop.
Save naderio/e3c806188ddfaac3906f to your computer and use it in GitHub Desktop.
NativeScript Android orientation service
'use strict';
const application = require('application');
const observable = require('data/observable');
const events = require('~/common/events');
const params = require('~/common/params');
const debug = require('nativescript-debug')(__filename);
var sensorManager, listener, accelerometerSensor, magneticFieldSensor;
const service = new observable.Observable();
service.watching = false;
service.timestamp = null;
service.value = null;
service.accuracy = null;
service._accelerometerValue = null;
service._accelerometerAccuracy = null;
service._magneticFieldValue = null;
service._magneticFieldAccuracy = null;
service.startWatching = function startWatching() {
if (this.watching) {
return;
}
const Context = android.content.Context;
const SensorManager = android.hardware.SensorManager;
const Surface = android.view.Surface;
sensorManager = application.android.context.getSystemService(Context.SENSOR_SERVICE);
function onAccuracyChanged(sensor, accuracy) {
debug('onAccuracyChanged:', sensor.getName(), accuracy);
if (sensor.getName() === accelerometerSensor.getName()) {
this._accelerometerAccuracy = accuracy;
} else if (sensor.getName() === magneticFieldSensor.getName()) {
this._magneticFieldAccuracy = accuracy;
}
if (this._accelerometerAccuracy !== null && this._magneticFieldAccuracy !== null) {
this.accuracy = (this._accelerometerAccuracy + this._magneticFieldAccuracy) / 2;
}
}
var FACTOR = 180 / Math.PI;
function onSensorChanged(event) {
// debug('onSensorChanged', event, event.sensor.getName(), event.values);
var timestamp = new Date();
if (this.timestamp && timestamp - this.timestamp < params.orientationDelay) {
return;
}
if (event.sensor.getName() === accelerometerSensor.getName()) {
this._accelerometerValue = event.values;
} else if (event.sensor.getName() === magneticFieldSensor.getName()) {
this._magneticFieldValue = event.values;
}
if (this._accelerometerValue !== null && this._magneticFieldValue !== null) {
// debug('onSensorChanged', this._accelerometerValue, this._magneticFieldValue);
// var rotationMatrix = Array.create('float', 16);
var rotationMatrix = java.lang.reflect.Array.newInstance(java.lang.Float.class.getField("TYPE").get(null), 16);
var result = SensorManager.getRotationMatrix(rotationMatrix, null, this._accelerometerValue, this._magneticFieldValue);
if (!result) {
return;
}
// debug('onSensorChanged', rotationMatrix);
var windowManager = application.android.context.getSystemService(Context.WINDOW_SERVICE);
var screenRotation = windowManager.getDefaultDisplay().getRotation();
// debug('onSensorChanged', 'screenRotation', screenRotation);
var axisX, axisY;
if (screenRotation === Surface.ROTATION_0) {
// debug('onSensorChanged', 'Surface.ROTATION_0');
axisX = SensorManager.AXIS_X;
axisY = SensorManager.AXIS_Y;
} else if (screenRotation === Surface.ROTATION_90) {
// debug('onSensorChanged', 'Surface.ROTATION_90');
axisX = SensorManager.AXIS_Y;
axisY = SensorManager.AXIS_MINUS_X;
} else if (screenRotation === Surface.ROTATION_180) {
// debug('onSensorChanged', 'Surface.ROTATION_180');
axisX = SensorManager.AXIS_MINUS_X;
axisY = SensorManager.AXIS_MINUS_Y;
} else if (screenRotation === Surface.ROTATION_270) {
// debug('onSensorChanged', 'Surface.ROTATION_270');
axisX = SensorManager.AXIS_MINUS_Y;
axisY = SensorManager.AXIS_X;
}
var remappedRotationMatrix = java.lang.reflect.Array.newInstance(java.lang.Float.class.getField("TYPE").get(null), 16);
result = SensorManager.remapCoordinateSystem(rotationMatrix, axisX, axisY, remappedRotationMatrix);
if (!result) {
return;
}
// debug('onSensorChanged', rotationMatrix);
// var orientation = Array.create('float', 4);
var orientation = java.lang.reflect.Array.newInstance(java.lang.Float.class.getField("TYPE").get(null), 4);
SensorManager.getOrientation(remappedRotationMatrix, orientation);
// debug('onSensorChanged', orientation);
var value = orientation[0] * FACTOR;
// debug('onSensorChanged', 'value', value);
if (typeof this.value === 'number' && Math.abs(value - this.value) < params.orientationMinimalChange) {
return;
}
this.timestamp = timestamp;
this.value = value;
this.notify({
eventName: 'update',
object: {
timestamp: timestamp,
value: value,
accuracy: this.accuracy,
},
});
}
return;
}
listener = new android.hardware.SensorEventListener({
onAccuracyChanged: onAccuracyChanged.bind(this),
onSensorChanged: onSensorChanged.bind(this)
});
accelerometerSensor = sensorManager.getDefaultSensor(
android.hardware.Sensor.TYPE_ACCELEROMETER
);
sensorManager.registerListener(
listener,
accelerometerSensor,
SensorManager.SENSOR_DELAY_UI
);
magneticFieldSensor = sensorManager.getDefaultSensor(
android.hardware.Sensor.TYPE_MAGNETIC_FIELD
);
sensorManager.registerListener(
listener,
magneticFieldSensor,
SensorManager.SENSOR_DELAY_UI
);
this.watching = true;
};
service.stopWatching = function stopWatching() {
if (!this.watching) {
return;
}
sensorManager.unregisterListener(listener, accelerometerSensor);
sensorManager.unregisterListener(listener, magneticFieldSensor);
this.watching = false;
};
module.exports = service;
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment