You 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





Basic application UI

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.

Improved application UI with Bootstrap

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.

Adding effects with GraphicsMagick

Here's an example snippet.

JavaScript







x



1 gm ( '/sdcard/DCIM/100RICOH/' + item ) 2 . edge ( 30 ) 3 . write ( __dirname + '/media/paint/' + outputName , function ( err ) {









Link on GitHub.

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.

Project workflow

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:

Installing Termux

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.

Adding ssh key to Android device

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.

Testing internet connection

Update the Termux packages.

Updtaing Termux

In the Android settings, enable permissions for Termux.

Enabling permissions for Termux

Set up Termux storage.

Setting up Termux storage

Check Storage. You should be able to access your Android pictures, music, and movies from inside of Termux.

Accessing files from Termux

Install OpenSSH with the following command: apt install openssh .

Installing 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.

Adding SSH key to Android device

Set SSHD to Automatically Start

Start SSHD when Termux starts by adding it to your .bashrc.

Adding SSHD to .bashrc

Login to the Device on Port 8022

Logging into device

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.

Opening multiple windows with Emacs





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:

Shell







xxxxxxxxxx 1



1 2 /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.

JavaScript







xxxxxxxxxx 1 48



1 const fs = require ( 'fs' ); 2 const Datastore = require ( 'nedb' ); 3 const images = new Datastore ({ filename : 'images.db' }); 4 5 const cameraPictureDir = '/sdcard/DCIM/100RICOH/' 6 7 8 images . loadDatabase (); 9 10 11 function loadAll () { 12 fs . readdir ( cameraPictureDir , ( fileErr , items ) => { 13 if ( ! fileErr ) { 14 console . log ( "About to insert these items

" + items ); 15 items . forEach ( item => { 16 const image = { 17 title : 'Beautiful title for ' + item , 18 filename : item 19 } 20 images . insert ( image , ( err , doc ) => { 21 if ( ! err ) { 22 console . log ( 'Inserted' , doc . filename , 'with ID' , doc . _id ); 23 } else { 24 console . log ( err ); 25 } 26 }); 27 }) 28 29 } else { 30 console . log ( fileErr ); 31 } 32 }); 33 } 34 35 36 function findAll () { 37 images . find ({}, ( err , doc ) => { 38 if ( ! err ) { 39 console . log ( doc ); 40 } else { 41 console . log ( err ); 42 } 43 }); 44 } 45 46 47 48 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.

Running findall with neDB

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.

JavaScript







xxxxxxxxxx 1 21



1 2 3 4 app . post ( '/reduce-quality' , ( req , res ) => { 5 6 let imageArray = []; 7 fs . readdir ( ricohImageDir , ( err , items ) => { 8 items . forEach (( item ) => { 9 if ( isImage ( item )) { 10 imageArray . push ( item ); 11 gm ( '/sdcard/DCIM/100RICOH/' + item ) 12 . quality ( 30 ) 13 . noProfile () 14 . write ( __dirname + '/public/gallery/' + item , function ( err ) { 15 if ( ! err ) console . log ( 'wrote reduced image file size ' + item ); 16 }); 17 } 18 }); 19 }); 20 21 });









Original

Average file size of 8MB

Original file sizes

Reduced with Lossy Compression

Average file size of 600K

Reduced file sizes

Despite the massive reduction in file size, the image quality looks okay.

30% Quality, 750kB size, 6720x3360 dimensions, 100% scale

Quality reduction after compression

100% quality, 8.8MB size, 6720x3360 pixels, 100% scale





Full quality after compression

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.

Processing images to thumbnails

Compression output

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.

Making deployment directory

Install git.

Installing git

Clone the repo.

Cloning the repo

Install Node



Installing 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