6 Tips for Effective Use of Node on Android Devices
Join the DZone community and get the full member experience.
Join For FreeYou can run JavaScript Node applications directly on your Android phone, AVD, or embedded IoT device. I'll show you six tips to use the open source project, Termux, to effectively prototype Node applications on Android.
Choosing Android for the OS of your IoT device allows millions of mobile developers to quickly access your platform. However, choosing a good platform is not enough. You need to make it super easy for many types of developers to bring their creative ideas to the prototype stage.
After two years of helping developers build applications for the RICOH THETA Android-based camera, I've identified two key areas where people struggle: 1) Android app developers may not have experience developing cloud-based IoT systems needed to process data; 2) IoT backend developers may not have experience with Android development.
To help developers rapidly prototype their ideas on Android IoT devices, many people in the community are using Termux for RICOH THETA development. This serves as a knowledge bridge for the backend written in JavaScript or Python and the Android IoT device app written in Java. These techniques are applicable for any Android device, including phones.
The code for the project is available on GitHub.
You may also like: Android Tutorial – Learn Android From Scratch!
Build the Web GUI to Control the Android Device
Build a web GUI to interact with your Android device for testing, configuration, and demos. My device is a networked Android camera, and I use the GUI to take and preview pictures. This is easy to do with Node, Express, and Bootstrap. My photo album example uses a modified Album example from the official Bootstrap site.
It's very cool to run the Node server directly on the camera, as I have direct access to the camera file system and can process images locally inside the camera before pushing the images to another server or application.
In this example, I'm processing each 5MB image inside the camera with GraphicsMagick for Node through the gm package. This allows for transformations, such as a cartoon styling with a single line of code.
Here's an example snippet.
gm('/sdcard/DCIM/100RICOH/' + item)
.edge(30)
.write(__dirname + '/media/paint/' + outputName, function(err) {
For prototyping a concept and showing your peers or boss, Node and Express are super easy. My previous project with Java and the native Android SDK was more difficult. I built the web GUI in Java with NanoHttpd and handled processing with OpenCV using the Android NDK.
With a web GUI and image display, you can immediately convey your concept and show what is happening in the IoT device.
Additional details on building the WebUI is here.
Enable SSH With Keys and Local Storage
On an embedded device, you should download Termux from a site like F-Droid, not from Google Play. I have more details of the setup process in this article. Install the Termux apk with adb:
To get my public ssh key onto my Android device, I am using Vysor, which displays a virtual screen. My physical device doesn't have a screen.
My Android device has Wi-Fi access. To connect to the Internet and use Vysor over USB, I use this command from my workstation:
$ adb shell settings put global usb_debug true
I can then connect my camera to the Internet through my Wi-Fi router.
You can test Internet access with a ping to any known domain.
Update the Termux packages.
In the Android settings, enable permissions for Termux.
Set up Termux storage.
Check Storage. You should be able to access your Android pictures, music, and movies from inside of Termux.
Install OpenSSH with the following command: apt install openssh
.
Add Your Public Key
On your local system, copy your public key into your clipboard. The screenshot below is from the workstation. Copy the contents of id_rsa.pub into your system clipboard. For example, open the file in a text editor and copy it with CTRL-C.
Paste the key into .ssh/authorized_keys
on your Android device.
Set SSHD to Automatically Start
Start SSHD when Termux starts by adding it to your .bashrc.
Login to the Device on Port 8022
Install Emacs or tmux
If you're familiar with Emacs, it's a great way to open up multiple windows through the same ssh session.
If you do not want to use Emacs, you can use tmux for similar functionality.
4) Use Termux:Boot to Start Your Node App Automatically
Get Termux:Boot from F-Droid.
Create a new file ~/.termux/boot/startup
and add these lines:
xxxxxxxxxx
/data/data/com.termux/files/usr/bin/node /data/data/com.termux/files/home/Development/theta-termux-node/index.js
Make sure you have the full path of node index.js. The node command and the index.js file name need to be on the same path.
Adjust the path to the location of your index.js file
I can now start both Termux and my node application with the physical button of my Android device. To do so, follow these steps:
- Make suer the camera is powered off (must be off and not in sleep).
- Power camera on with the physical power button.
- Press the lower mode button for longer than two seconds to put the camera in plug-in mode.
- On one of my devices, I configured the IP address to appear on a small OLED display. On another device, I use network discovery to find the IP address.
Use NeDB Instead of MongoDB
If you're familiar with Node development, you might reach for MongoDB as your database of choice. MongoDB doesn't run on Termux. The good news is that NeDB is pure JavaScript and runs great inside of Termux on Android.
Here's a short example of using NeDB on Android with Node.
xxxxxxxxxx
const fs = require('fs');
const Datastore = require('nedb');
const images = new Datastore({ filename: 'images.db' });
const cameraPictureDir = '/sdcard/DCIM/100RICOH/'
images.loadDatabase();
function loadAll() {
fs.readdir(cameraPictureDir, (fileErr, items)=> {
if (!fileErr) {
console.log("About to insert these items \n" + items);
items.forEach(item => {
const image = {
title: 'Beautiful title for ' + item,
filename: item
}
images.insert(image, (err, doc)=> {
if (!err) {
console.log('Inserted', doc.filename, 'with ID', doc._id);
} else {
console.log(err);
}
});
})
} else {
console.log(fileErr);
}
});
}
function findAll() {
images.find({}, (err, doc)=> {
if (!err) {
console.log(doc);
} else {
console.log(err);
}
});
}
// loadAll();
// images.remove({_id: 'lZaB4KIijYsmIKde'});
findAll();
Since I've enabled storage (see tip on enabling storage above), I can access my camera pictures directly on /sdcard/DCIM/100RICOH/
.
This is the output of the findAll()
function.
Reduce Data Size on Local Device
Most IoT devices have access to more data than can be handled effectively in the cloud. This problem is especially acute when you deal with image and video data. Each image on my camera is 5MB, and a typical session will capture hundreds or thousands of pictures. To help with this problem of transmitting huge data files over the Wi-Fi network, I reduced the file size of the image with gm.
xxxxxxxxxx
// reduce file size by reducing quality
app.post('/reduce-quality', (req, res) => {
let imageArray = [];
fs.readdir(ricohImageDir, (err, items) => {
items.forEach ((item) => {
if (isImage(item)) {
imageArray.push(item);
gm('/sdcard/DCIM/100RICOH/' + item)
.quality(30)
.noProfile()
.write(__dirname + '/public/gallery/' + item, function(err) {
if (!err) console.log('wrote reduced image file size ' + item);
});
}
});
});
});
Original
Average file size of 8MB
Reduced with Lossy Compression
Average file size of 600K
Despite the massive reduction in file size, the image quality looks okay.
30% Quality, 750kB size, 6720x3360 dimensions, 100% scale
100% quality, 8.8MB size, 6720x3360 pixels, 100% scale
You can process the images down to thumbnails. This example shows how to reduce the 9MB image files down to 4K with 200x100 pixel size.
Additional Information on Installing Node
If you're new to using Node on Android, I'll include some information on how to get Node on Android running with Termux.
Steps
- Connect Android device to your Router with Wi-Fi.
- Connect a laptop to the same router.
- SSH into your Android device (assuming you have set up ssh public key) or use Termux from the command line. (See tip above to set up ssh public key.)
- Clone code example from GitHub.
- Run
npm install
- Enter: node index.js.
- Point the browser to http://ip-address:3000.
Note that you need to adjust the JavaScript example for your specific Android device.
Make a directory for Development.
Install git.
Clone the repo.
Install Node
run npm install
Get the IP address if you don’t already know it. I’m getting it with ifconfig
My IP address is 192.168.43.41.
Run node index.js
The server should start on port 3000.
Use a web browser to connect to the IP address and port. See this article for more information. Note that unless you've installed the sample code on a RICOH THETA Android device, most of the commands won't work without modification. However, you can use the code example as a reference for your specific Android device.
Summary
Running Android on Node is a very fast way to build IoT prototypes on Android if the developer is already familiar with Node for backend development. This is a great way to test concepts, show peers, and managers. As most people use Termux on an Android phone with a screen, using Termux on an Android device with no screen can be tricky to set up.
However, once the environment is properly set up, it is a very pleasant and stable development environment. Follow these tips to help you achieve a more blissful and aggravation-free coding experience.
Further Reading
Opinions expressed by DZone contributors are their own.
Trending
-
How To Use Git Cherry-Pick to Apply Selected Commits
-
How To Use Pandas and Matplotlib To Perform EDA In Python
-
A Complete Guide to Agile Software Development
-
Future of Software Development: Generative AI Augmenting Roles and Unlocking Co-Innovation
Comments