Sensor & Sensoribility
Tutorials – Cordova Sensor
Frameworks like Cordova make creating simple mobile apps quite easy. Making apps that use your phone's sensor is slightly trickier, but, thanks to a new universal standard, things are not as hard as you may think.
In the May 2018 issue of Linux Magazine, you learned how to read and transfer GPS data from a phone to a computer [1]. That made me wonder if you could also play with data collected from other sensors on your phone. The answer I knew immediately would be "yes," but could it be done in simple enough way that would allow me to explain it in a shortish tutorial written in plain English?
My first instinct was to use an existing app. I found several apps that looked promising but ended up having to discard them all, because they were proprietary and tended to leak data, or they were unstable and crashed, or the code was very old and no longer maintained.
There was one that caught my eye: SSJ Creator [2], which is open source, developed by researchers, and has an interesting node-based interface (Figure 1) that lets you configure which sensor gets read and where you pipe its output (Figure 2).
However, it is a bit of overkill: The amount of options and settings make it confusing, and it also crashed consistently when I tried to pipe output to a socket that would allow me to read it from my laptop.
Running out of options, I had to ditch the idea of using an off-the-shelf utility altogether. I have always believed that one way of better understanding something is to build it yourself. I mean, how hard could it be? Besides, in last month's issue, we already talked about the Docker-Cordova combo [3] and how it helps create apps for Android easily.
So down the rabbit hole of integrating sensor data into a Cordova-based app I went.
Sensors
Apart from the geolocation sensor you saw in the article about GPS [1], most devices come with several other sensors. In mobile phones, accelerometers are used to detect the device's orientation. Manufacturers use them to determine when to put the screen in landscape or portrait mode, for example.
Older phones (and by older, I mean pre-2011 handsets) will not have gyroscopes, but most modern devices will. Gyroscopes do something similar to what an accelerometer does, but there is an important difference: Gyroscopes also detect rotation. Sit in a swivel chair and hold your phone stationary in front of your face. Swivel around on your chair and the accelerometer will not detect anything, but the gyroscope will. Gyroscopes are also useful for gestures: If you have one of those phones that you flip quickly to activate the camera, that's the operating system checking the gyroscope.
Another difference is that gyroscopes are more jittery than accelerometers. While an accelerometer will not emit a lot of different data if your phone is at rest, the gyroscope will. Ultimately, many applications usually use data sent by both sensors to detect how your phone is positioned and where it is going.
The linear acceleration sensor is very simple by comparison: It calculates the phone's acceleration in any given direction. If you are holding your phone upright in front of your face and you drop it, for example, it will register 9.8 m/s2 on the Y axis. For the record, the X axis is, again if you are holding your phone upright, from side to side; the Z axis is the horizontal line moving away from you (Figure 3).
These are the most common sensors on mobile devices, and the three we are going to talk about in this article, although there are many more. There are sensors to detect ambient light intensity, magnetic north (i.e., a compass), magnetic fields, proximity, humidity, and so on. Smartwatches may also come with heartbeat and blood pressure sensors.
Not all devices will come with all sensors, but you are more or less guaranteed that even the cheapest phone will have the three mentioned above.
Visiting Cordova
As saw in last month's issue, you can use a Docker image to make everything simpler – especially when it comes to writing Android applications, so install Docker:
sudo apt install docker
Start the docker daemon
sudo systemctl start docker sudo systemctl enable docker
and grab the Cordova/Android Docker image
docker pull beevelop/cordova
and you are ready to go.
To start creating a Cordova app, first you must create a skeleton application. cd
into the directory you want your application to live in and run:
docker run --rm -i -v /$PWD:/workspace -w /workspace--privileged beevelop/cordova cordova create sensors com.LPM.sensors Sensors
This will create a sensors/
directory containing the basic files you need to create your app.
cd
into sensors
and run:
docker run --rm -i -v /$PWD:/workspace -w /workspace --privileged beevelop/cordova cordova platforms add android browser
to pull all the tools you will need to create an Android application. It is also a good idea to download what you need for a browser application, as it is easier to debug your HTML, CSS, and JavaScript in a browser than directly on your Android device.
You Got the Look
Cordova applications are a combination of HTML5, CSS, and JavaScript, so the front end (what your users are going to see) is going to be a web page with its CSS. Having created a skeleton app, you already have a demo application that, when loaded on an Android device, looks like Figure 4.
The web part of the application is the index.html
file that lives in the www/
directory.
You are going to exchange the Apache Cordova logo for a drop-down selection field (from which you will be able to choose the sensor you want to read), a button (that will start the reading from the sensor), and a text area field (that will show the data read from the sensor). It will look like Figure 5.
Open index.html
in your favorite text editor. You don't have to touch anything in the <head> ... </head>
section, but rip out everything between the <body>
and </body>
tags and substitute it for what you can see in Listing 1.
Listing 1
index.html (partial)
01 <body> 02 <div class="container" style="padding: 10px"> 03 <h2>Choose a sensor</h2> 04 <select id="sensor" style="width:100%"> 05 <option value="Accelerometer">Accelerometer</option> 06 <option value="Gyroscope">Gyroscope</option> 07 <option value="LinearAccelerationSensor">LinearAccelerationSensor</option> 08 </select> 09 <br /> 10 <button id="start">Start</button> 11 <br /> 12 <br /> 13 <h2>Sensor data</h2> 14 <textarea id="data" rows="10" readonly style="width: 100%"> 15 Sensor data shows up here. 16 </textarea> 17 </div> 18 <script type="text/javascript" src="js/index.js"></script> 19 </body>
This is pretty basic HTML. From lines 1 to 8, you have the drop-down field with the sensor names you can choose (Figure 6); line 10 is the Start button and line 14 is the text area. Finally, on line 18, you load in a JavaScript file that is going to give you the code that makes everything work.
But before that, you may want to tweak the CSS. The CSS file you are looking for is in www/css/
; it is called index.css
. You can change the body
section so it looks like what you see in Listing 2. Your app will look, if not beautiful, a bit better than if it used the default CSS.
Listing 2
index.css (partial)
[...] body { -webkit-touch-callout: none; -webkit-text-size-adjust: none; -webkit-user-select: none; background-color:#F8F8F8; background-attachment:fixed; font-family:'HelveticaNeue-Light', 'HelveticaNeue', Helvetica, Arial, sans-serif; font-size:12px; height:100%; margin:0px; padding:0px; width:100%; } [...]
Buy this article as PDF
(incl. VAT)