Sensor & Sensoribility
Reading Sensors
The next step is actually making the app do something; this is when things got hairy. Cordova relies heavily on plugins to extend functionality. There is a nicely stocked repository online [4], and searching for "sensors" coughed up some interesting results.
Besides, you can install plugins quite easily with:
docker run --rm -i -v /$PWD:/workspace -w /workspace --privileged beevelop/cordova cordova plugin add <plugin location>
But I found that some of the sensor plugins were surprisingly old and unmaintained. Others had emptied out repositories, or the plugin list links that led to 404 errors. And then there were those loudly labeled as obsolete.
It was very confusing. It made no sense that really no one was interested in maintaining plugins that accessed a mobile phone's sensors.
Unless there was no point, of course.
The clue came from one plugin that said the work had been obsolete ever since the World Wide Web Consortium (W3C, the organization that establishes what goes into HTML, CSS, and JavaScript) had decided to take on the standardization of how to interact with mobile-device sensors [5]. That's right: The reason there is no need for plugins is because reading sensors is now as part of the web as the <blink>
and <marquee>
tags.
This means two things:
1. You can now have web pages like, (Figure 7) [6] that integrate sensor data from the visitor's device into the content

2. You can integrate sensor data into your Cordova apps.
The good news is that initializing, starting, and reading from a sensor using JavaScript is mercifully simple. First, you create a sensor object by initializing the sensor you want to read from:
var <sensor_object> = new <Sensor_name>();
For example, to initialize the accelerometer, you would do:
var my_sensor = new Accelerometer();
The W3C spec lists 10 sensors you can pick from: Accelerometer
, AmbientLightSensor
, Magnetometer
, Gyroscope
, OrientationSensor
, LinearAccelerationSensor
, AbsoluteOrientationSensor
, RelativeOrientationSensor
, GeolocationSensor
, and ProximitySensor
. Note that not all sensors will work on all devices, and there are some that won't work on any device, since there are no web engines that have implemented them yet.
You can include as a parameter in the initialization the frequency with which you will be polling the sensor. To poll the accelerometer 60 times a second, you can do:
var my_sensor = new Accelerometer({frequency: 60});
Next, you have to define a callback function for the sensor, that is, the function that will run every time there is new data from the sensor:
my_sensor.addEventListener( 'reading', <function>);
addEventListener()
is a method that is a standard part of JavaScript. It listens for the events you specify. You could add a 'click'
event to a listener for a button, or a 'change'
event to a text box for when someone types something new in it. For a sensor, you use the special 'reading'
event.
You can call the callback function by name, like in:
sensor.addEventListener( 'reading', listener); [...] function listener( event ) { [...]
Or you can do like in Listing 3, line 12, and embed the function directly into the addEventListener()
method.
Listing 3
index.js
01 var sensorSelect = document.getElementById("sensor"); 02 var startButton = document.getElementById("start"); 03 var dataText = document.getElementById("data"); 04 05 startButton.onclick = function() { 06 if (startButton.innerHTML == "Start") { 07 startButton.innerHTML = "Stop"; 08 try { 09 var sensor = new window[sensorSelect.value](); 10 dataText.innerHTML = sensorSelect.value; 11 12 sensor.addEventListener('reading', function(event) { 13 dataText.innerHTML= 'x: ' + event.target.x + ' y: ' + event.target.y + ' z: ' + event.target.z; 14 }); 15 sensor.start(); 16 17 } catch(error) { 18 dataText.innerHTML = 'Error creating sensor'; 19 } 20 } else { 21 startButton.innerHTML = "Start"; 22 dataText.innerHTML = ""; 23 } 24 };
Finally, you start listening to your sensor with:
sensor.start();
There's not much more to it. Listing 3 shows how things would work when you put everything together for your app. Lines 1 to 3 map HTML elements (the select field, button, and text area) to JavaScript variables; then, on line 5, you listen for a click event on the button.
When a user clicks the button, you take the value from the selector (Accelerometer
, Gyroscope
, or LinearAccelerationSensor
) and use it to initialize the sensor (line 9).
As you are only going to print the data out, the callback function (lines 12 to 14) is short. The callback function takes a parameter (event
) that holds the data from the sensor.
The event
's target
retrieves the element that triggered the event, in this case, the sensor itself. The x
, y
, and z
attributes are common to the three sensors in the list – which is why they are in the list, as other sensors have different properties. The point is you print out the sensor's x
, y
, and z
values on line 13.
And that's it. All told, the HTML for the front end is just 30 lines long, including the head section that you haven't even touched. And the code is fewer than 25 lines of pretty straightforward, uncomplicated JavaScript.
Trial Run
To build the app and launch it on your phone, first make sure your phone is in developer mode by going to Settings | About phone and scrolling down until you see the Build number section. Tap on that several times until your phone says you are a developer.
Connect your phone to your computer using a USB cable and move back to Settings. You will see there is a new submenu called Developer options. Tap on that and scroll down until you see the USB debugging option. Activate it.
Now check that Cordova can talk to your device by running the following instruction:
docker run --rm -i --privileged -v /dev/bus/usb:/dev/bus/usb beevelop/cordova adb devices
Cordova is using the Android Debug Bridge (adb
) to try and locate your phone. The devices
option shows a list of connected devices.
The first time around, your device may show up as unauthorized. This is normal. Go into Settings | Developer options again and make sure you have enabled USB debugging. While you are there, run
docker run --rm -i --privileged -v /dev/bus/usb:/dev/bus/usb beevelop/cordova adb devices
again, and a dialog will pop up on your phone asking you to authorize your computer. Give your computer permission, and try listing your devices again. Your phone should now appear as available.
Now you can push your app to your phone with:
docker run --rm -i -v /$PWD:/workspace-w /workspace --privileged -v /dev/bus/usb/:/dev/bus/usb/ beevelop/cordova cordova run android
Cordova will automatically install and run the app. The final result will look like Figure 8.

Conclusion
The universal sensor API combined with Cordova makes building sophisticated, sensor-enabled mobile apps ridiculously easy. If you know HTML and some basic JavaScript, you have all you need to get started.
In my next installment, you will learn how to extend your Cordova app, so it can transfer data to you computer. You will also learn how to integrate the data into a desktop application, so you can use your phone as a controller.
Infos
- "Tutorial – GPSD" by Paul Brown, Linux Magazine, issue 210, May 2018, p. 90: http://www.linux-magazine.com/Issues/2018/210/Tutorial-gpsd/
- SSJ Creator: https://play.google.com/store/apps/details?id=hcm.ssj.creator
- "Tutorial – Docker 101" by Paul Brown, Linux Magazine, issue 215, October 2018, p. 90: http://www.linux-magazine.com/Issues/2018/215/Tutorials-Docker
- Cordova's plugin repository: https://cordova.apache.org/plugins/
- The W3C's Generic Sensor API: https://www.w3.org/TR/generic-sensor/
- A web page with a compass: https://mobiforge.gitlab.io/sensors/compass.html
« Previous 1 2
Buy this article as PDF
(incl. VAT)
Buy Linux Magazine
Direct Download
Read full article as PDF:
Price $2.95
Subscribe to our Linux Newsletters
Find Linux and Open Source Jobs
Subscribe to our ADMIN Newsletters
Support Our Work
Linux Magazine content is made possible with support from readers like you. Please consider contributing when you've found an article to be beneficial.
News
-
Armbian 23.05 is Now Available
Based on Debian 12, the latest version of the ARM/RISC-V distribution is now available to download and install.
-
Linux Mint Finally Receiving Support for Gestures
If you use the Linux Mint Cinnamon desktop, you'll be thrilled to know that 21.2 is getting support for gestures on touchscreen devices and touchpads.
-
An All-Snap Version of Ubuntu is In The Works
Along with the standard deb version of the open-source operating system, Canonical will release an-all snap version.
-
Mageia 9 Beta 2 Ready for Testing
The latest beta of the popular Mageia distribution now includes the latest kernel and plenty of updated applications.
-
KDE Plasma 6 Looks to Bring Basic HDR Support
The KWin piece of KDE Plasma now has HDR support and color management geared for the 6.0 release.
-
Bodhi Linux 7.0 Beta Ready for Testing
The latest iteration of the Bohdi Linux distribution is now available for those who want to experience what's in store and for testing purposes.
-
Changes Coming to Ubuntu PPA Usage
The way you manage Personal Package Archives will be changing with the release of Ubuntu 23.10.
-
AlmaLinux 9.2 Now Available for Download
AlmaLinux has been released and provides a free alternative to upstream Red Hat Enterprise Linux.
-
An Immutable Version of Fedora Is Under Consideration
For anyone who's a fan of using immutable versions of Linux, the Fedora team is currently considering adding a new spin called Fedora Onyx.
-
New Release of Br OS Includes ChatGPT Integration
Br OS 23.04 is now available and is geared specifically toward web content creation.