Links

journey.sensors

Version compatibility
  • journey.sensors was introduced in version 4.85.0 of the JourneyApps Runtime and version 22.4.1 of the JourneyApps Container.
  • Currently only supported on Android and iOS.
Returns information about the device's accelerometer, compass and orientation data.

Supported fields

getCapabilities()

To retrieve a device's supported sensor capabilities.
main.ts
var capabilities = await journey.sensors.getCapabilities();
view.accelerometer_supported = capabilities.accelerometerIsSupported;
view.compass_supported = capabilities.compassIsSupported;
view.orientation_supported = capabilities.orientationIsSupported;

accelerometer.read()

Returns accelerometer data captured at a specific point in time.
Acceleration values include the effect of gravity (9.81 m/s^2), so that when a device lies flat and facing up, x, y, and z values returned should be 0, 0, and 9.81.
Properties returned:
  • x: Number value
  • y: Number value
  • z: Number value
  • timestamp: Unix Timestamp when sample was taken

accelerometer.registerListener()

Listeners supply an onData callback which will be invoked with the data argument set to the same format as a read function call. The onError callback will be called on an error condition, if called, no subsequent onData callbacks are executed. The argument provided to the onError function is a string error message.
Listener options:
Currently the only option supported for all sensors is the sampling period in milliseconds.
export interface ListenerOptions {
periodMs: number;
}
Example:
main.js
watchRemover = journey.sensors.accelerometer.registerListener(
function onData(result) {
// Do something with result here, e.g.
var listenerTimestamp = result.timestamp.toString();
},
function onError(error) {
console.log('Received error', error);
},
{
periodMs: 1000
}
);

compass.read()

Returns compass data captured at a specific point in time.
Properties returned:
  • magneticHeading: The heading in degrees from 0-359.99 at a single moment in time. (Number)
  • trueHeading: The heading relative to the geographic North Pole in degrees 0-359.99 at a single moment in time. A negative value indicates that the true heading can't be determined. (Number)
  • headingAccuracy: The deviation in degrees between the reported heading and the true heading. (Number)
  • timestamp: Unix Timestamp when sample was taken

compass.registerListener()

orientation.read()

Returns the orientation of a device with angles measured along a specific reference frame. See here for good depictions of the angles.
Properties returned:
  • alpha: Number value
  • beta: Number value
  • gamma: Number value
  • timestamp: Unix Timestamp when sample was taken

orientation.registerListener()

Example Code

The below example code shows a view that allows a user to read and start/stop watching accelerometer data. The returned data saved to LocalDB objects and is presented in tables.
JavaScript
TypeScript
schema.xml
<?xml version="1.0" encoding="UTF-8"?>
<data-model>
...
<model name="data_row" label="Local: Data Row">
<field name="key" label="Key" type="text" />
<field name="value" label="Value" type="text" />
<display>{key}: {value}</display>
</model>
</data-model>
main.view.xml
<?xml version="1.0" encoding="UTF-8"?>
<view title="Accelerometer" on-back="stopWatch">
<var name="read_timestamp" type="text" />
<var name="listener_timestamp" type="text" />
<var name="read_results" type="array:data_row" />
<var name="watch_results" type="array:data_row" />
<var name="watch_period_ms" type="number" />
<var name="is_watching" type="boolean" />
<button label="Read Sensor" on-press="read" validate="false" />
<object-table show-if="read_results" label="Single Result {read_timestamp}" query="read_results" empty-message="Your items will appear here">
<column heading="Field" fit="shrink">{key}</column>
<column heading="Value m/s^2">{value}</column>
</object-table>
<heading>Watch Sensor</heading>
<text-input label="Sample period (ms)" bind="watch_period_ms" required="true" />
<button hide-if="is_watching" label="Watch Acceleration" on-press="watch" validate="true" />
<button show-if="is_watching" label="Stop watching" on-press="stopWatch" validate="false" />
<object-table show-if="watch_results" label="Watched Result {listener_timestamp}" query="watch_results" empty-message="Your items will appear here">
<column heading="Field" fit="shrink">{key}</column>
<column heading="Value m/s^2">{value}</column>
</object-table>
</view>
main.js
// This function is called when the app navigates to this view (using a link)
function init() {
// initialize any data here that should be available when the view is shown
view.watch_period_ms = 1000;
}
// This function is called when the user returns to this view from another view
function resume(from) { }
function read() {
// For accelerometer data use journey.sensors.accelerometer
// For compass data use journey.sensors.compass
// For orientation data use journey.sensors.orientation
var result = journey.sensors.accelerometer.read();
view.read_results = Object.keys(result).map(function (key) {
return LocalDB.data_row.create({
key: key,
value: result[key]
})
});
view.read_timestamp = result.timestamp.toString();
}
var watchRemover;
function watch() {
// For accelerometer data use journey.sensors.accelerometer
// For compass data use journey.sensors.compass
// For orientation data use journey.sensors.orientation
watchRemover = journey.sensors.accelerometer.registerListener(
function onData(result) {
if (view.watch_results && view.watch_results.length) {
view.watch_results.map(function (item) { item.destroy() });
}
view.watch_results = Object.keys(result).map(function (key) {
return LocalDB.data_row.create({
key: key,
value: result[key]
})
});
view.listener_timestamp = result.timestamp.toString();
journey.forceDigest();
},
function onError(error) {
console.log('Received error', error);
},
{
periodMs: view.watch_period_ms
});
view.is_watching = true;
}
function stopWatch() {
if (watchRemover) {
watchRemover();
watchRemover = null;
};
view.is_watching = false;
}
Important config for TS apps:
  1. 1.
    Be sure to use the "@journeyapps/runtime-build": "^2.0.5" package version (or greater) in package.json
  2. 2.
    After updating package.json, run the “Update yarn.lock” > App package action.
schema.xml
<?xml version="1.0" encoding="UTF-8"?>
<data-model>
...
<model name="data_row" label="Local: Data Row">
<field name="key" label="Key" type="text" />
<field name="value" label="Value" type="text" />
<display>{key}: {value}</display>
</model>
</data-model>
main.view.xml
<?xml version="1.0" encoding="UTF-8"?>
<view title="Accelerometer" on-back="stopWatch">
<var name="read_timestamp" type="text" />
<var name="listener_timestamp" type="text" />
<var name="read_results" type="array:data_row" />
<var name="watch_results" type="array:data_row" />
<var name="watch_period_ms" type="number" />
<var name="is_watching" type="boolean" />
<button label="Read Sensor" on-press="read" validate="false" />
<object-table show-if="read_results" label="Single Result {read_timestamp}" query="read_results" empty-message="Your items will appear here">
<column heading="Field" fit="shrink">{key}</column>
<column heading="Value m/s^2">{value}</column>
</object-table>
<heading>Watch Sensor</heading>
<text-input label="Sample period (ms)" bind="watch_period_ms" required="true" />
<button hide-if="is_watching" label="Watch Acceleration" on-press="watch" validate="true" />
<button show-if="is_watching" label="Stop watching" on-press="stopWatch" validate="false" />
<object-table show-if="watch_results" label="Watched Result {listener_timestamp}" query="watch_results" empty-message="Your items will appear here">
<column heading="Field" fit="shrink">{key}</column>
<column heading="Value m/s^2">{value}</column>
</object-table>
</view>
main.js
// This function is called when the app navigates to this view (using a link)
async function init() {
// initialize any data here that should be available when the view is shown
view.watch_period_ms = 1000;
}
// This function is called when the user returns to this view from another view
async function resume(from: ResumeFrom) { }
async function read() {
const result = await journey.sensors.accelerometer.read();
view.read_results = Object.keys(result).map(key => LocalDB.data_row.create({
key: key,
value: result[key]
}));
view.read_timestamp = result.timestamp.toString();
}
let watchRemover: () => void;
async function watch() {
watchRemover = await journey.sensors.accelerometer.registerListener(
result => {
if (view.watch_results?.length) {
view.watch_results.map(item => item.destroy());
}
view.watch_results = Object.keys(result).map(key => LocalDB.data_row.create({
key: key,
value: result[key]
}));
view.listener_timestamp = result.timestamp.toString();
journey.forceDigest();
},
console.log,
{
periodMs: view.watch_period_ms
});
view.is_watching = true;
}
async function stopWatch() {
if (watchRemover) {
await watchRemover();
watchRemover = null;
}
view.is_watching = false;
}