Code Monkey home page Code Monkey logo

node-on-android's Introduction

Node on Android

Make Node.js apps for Android (Currently only supports ARM64)

Installing

First install the command line tool from npm

npm install -g node-on-android

Or get it from git:

git clone https://github.com/node-on-mobile/node-on-android
cd cli/
npm i

You also need to fetch the Android SDK if you haven't (See "Get just the command line tools" here) and unpack them somewhere.

Then install apktool from brew or similar

brew install apktool

That's it! You are now ready to write Node.js apps for Android.

Building an app

Node on android works by running your Node.js inside the android app using a shared library. It then bundles a WebView that hosts your UI code. All UI is just classic html/css/js.

In the node app you can require node-on-android to get access to the WebView. You can use this to load an html page in the WebView

// in the node app
var android = require('node-on-android')

// will load localhost:1000 in the webview
android.loadUrl('http://localhost:10000')

You can call loadUrl as many times as you want. It'll just change the WebView address.

Here is an example app

// save me as my-app/index.js
var http = require('http')
var android = require('node-on-android')

var server = http.createServer(function (req, res) {
  res.end(`
    <html>
    <body>
      <h1>Welcome to Node.js hacking on Android</h1>
    </body>
    </html>
  `)
})

server.listen(0, function () {
  android.loadUrl(`http://localhost:${server.address().port}`)
})

To bundle up the Node.js app into an apk file use the command line tool

node-on-android ./my-app -o my-app.apk -b ./path/to/android/build/tools

If you installed Android Studio on Mac the build tools are usually installed in a path similar to ~/Library/Android/sdk/build-tools/26.0.1/.

After the above succeds you should be able to install my-app.apk on your Android phone and run the Node.js app.

Happy mobile hacking!

Instructions for GNU/Linux

To install apktool go to the apktool website and follow the installation guide for linux. Here it is in script form (but make sure you get the latest versions):

cd /tmp
wget https://raw.githubusercontent.com/iBotPeaches/Apktool/master/scripts/linux/apktool
wget https://bitbucket.org/iBotPeaches/apktool/downloads/apktool_2.2.4.jar
mv apktool_2.2.4.jar apktool.jar
chmod 755 apktool apktool.jar
sudo mv apktool apktool.jar /usr/local/bin/

In order to get the appsigner and zipalign commands you'll need to download the Android SDK tools and use the sdkmanager commmand.

On GNU/Linux you can download the sdk-tools package from the android website, e.g. sdk-tools-linux-3859397.zip and extract it to e.g. /opt/android-sdk-tools

Then to install the required appsigner and zipalign tools first use the sdkmanager command to list available packages:

/opt/android-sdk-tools/bin/sdkmanager --list

Find the latest build-tools version listed and install it with e.g:

/opt/android-sdk-tools/bin/sdkmanager --sdk_root=/opt/android-sdk-tools 'build-tools;26.0.1'

Make sure you run the previous command as a user that has write access to your sdk directory (in this case /opt/android-sdk-tools/bin.

Now you should have zipalign and apksigner available in:

/opt/android-sdk-tools/build-tools/26.0.1

You can use this path as your -b argument for the node-on-android command but you should really put zipalign and apksigner in your path like so:

cd /usr/local/bin
sudo ln -s /opt/android-sdk-tools/build-tools/26.0.1/zipalign
sudo ln -s /opt/android-sdk-tools/build-tools/26.0.1/apksigner

Example

There is an example app ready to try in the example/ directory.

First ensure that the dependencies are installed:

cd cli/
npm i
cd ..

You will also need to change the -b argument in build command in example/package.json if you don't have symlinks to zipalign and apksigner in /usr/local/bin.

cd example/
npm run build

To send it to your phone, enable adb debug mode on your android device, connect it over USB and run:

adb install build/example.apk

The app will show up in your app list as "Node On Android". You can also launch it using:

adb shell
am start -n com.mafintosh.nodeonandroid/com.mafintosh.nodeonandroid.MainActivity

License

MIT

node-on-android's People

Contributors

chrisekelley avatar juul avatar mafintosh avatar simoarpe avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

node-on-android's Issues

app stops when using back button

Reproduce:

  • Open node on android
  • Hit back button
  • See error: Node on Android has stopped

Normally on Android back button either goes back in the app history or exits the app.

won't install on chromebook

I've got a Samsung Chromebook Plus (arm chip) that is in dev mode, so I can sideload android APKs, but it says its not compatible.

screenshot 2017-07-29 at 4 38 03 pm

Anything I can do to help you get this working on chromebooks?

Node service thread is stopped incorrectly

In NodeService.java at NodeService.java#L25 the thread is stopped incorrectly which will lead to memory leaks and eventually crashes.

    @Override
    public void onDestroy() {
        super.onDestroy();
        if (t != null) {
            t.stop();
            t = null;
        }
    }

In this code t.stop() has been deprecated (for 11 years already, it was a mistake to ever add it) and is implemented with an UnsupportedOperationException.
Also setting the thread to null does not help. While the reference to the thread is gone, there is still a reference to it in the ThreadPool causing it to not be GC'ed and keeps happily running.

The way to implement stopping the node service is by letting the thread stop itself. You could do this by signalling t.interrupt() so thread can check Thread.currentThread().isInterrupted().

Problem is the thread is in private native void startNode(String... app) and will not detect this if this call is blocking (I didn't test, but I have similar issues with J2V8 nodeJs.handleMessage() now, where the node app is running an express server).

The solution for this last issue should be report to node app that it should (gracefully) stop running tasks that are blocking, then stop its execution, so the thread can continue to terminate itself.

The screen on android phone doesn't appear

doneapk
indexjs
nodejs
image

I succeeded in creating an apk file And
Run it on linux and test succeeded.
but i downloaded the apk file and run it. but the screen on android phone doesn't appear.........
i'm so sad :<.. please help me

Include Chromium

Hello, what happen if I want to use Chromium to take picture from a website or use it with puppeteer?

How can I add the chromium files inside the apk file?.

I installed userLAnd/debian and installed this version of chromium and it works fine:

> wget http://security.debian.org/debian-security/pool/updates/main/c/chromium-browser/chromium_70.0.3538.110-1~deb9u1_arm64.deb

> sudo dpkg -i chromium_70.0.3538.110-1~deb9u1_arm64.deb

And then I just run
chrome --headless --disable-gpu --screenshot https://www.chromestatus.com/

or in node:

const { execSync } = require('child_process');
let stdout = execSync('chrome --headless --disable-gpu --screenshot https://www.chromestatus.com/');

and it generate the screenshot.png

Error: dlopen failed: library "libnode.so.57" not found

I got this error below while i run app on my phone and I read the issue #4 but still didn't know which so file should be replaced. Anyone could help me?

10-10 01:21:23.381 29706-29751/? E/ActivityThread: Failed to find provider info for com.google.settings
10-10 01:21:23.541 27996-29705/? E/Market-ConnectionRSA: get key exception : com.android.org.bouncycastle.util.encoders.DecoderException: unable to decode base64 string: invalid characters encountered in base64 data
10-10 01:21:23.651 29706-29706/? E/art: dlopen("/data/app/com.mafintosh.nodeonandroid-1/lib/arm64/libnative-lib.so", RTLD_LAZY) failed: dlopen failed: library "libnode.so.57" not found
10-10 01:21:23.651 29706-29706/? E/AndroidRuntime: FATAL EXCEPTION: main
                                                   Process: com.mafintosh.nodeonandroid, PID: 29706
                                                   java.lang.UnsatisfiedLinkError: dlopen failed: library "libnode.so.57" not found
                                                       at java.lang.Runtime.loadLibrary(Runtime.java:371)
                                                       at java.lang.System.loadLibrary(System.java:988)
                                                       at com.mafintosh.nodeonandroid.NodeService.<clinit>(NodeService.java:97)
                                                       at java.lang.reflect.Constructor.newInstance(Native Method)
                                                       at java.lang.Class.newInstance(Class.java:1606)
                                                       at android.app.ActivityThread.handleCreateService(ActivityThread.java:2764)
                                                       at android.app.ActivityThread.access$1800(ActivityThread.java:154)
                                                       at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1400)
                                                       at android.os.Handler.dispatchMessage(Handler.java:102)
                                                       at android.os.Looper.loop(Looper.java:135)
                                                       at android.app.ActivityThread.main(ActivityThread.java:5290)
                                                       at java.lang.reflect.Method.invoke(Native Method)
                                                       at java.lang.reflect.Method.invoke(Method.java:372)
                                                       at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:911)
                                                       at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:706)

libnode.so for 32 bit is missing

okay it looks like I got it installed, it says it built successfully, but when I tried to run it on my phone I got this error:

Error:error: '../../../../src/main/jniLibs/armeabi-v7a/libnode.so', needed by '../../../../build/intermediates/cmake/debug/obj/armeabi-v7a/libnative-lib.so', missing and no known rule to make it

I'm trying to figure out where libnode.so comes from?
okay, a bit of searching led me here: nodejs/node#14158

gonna check that out...

btw, I changed line 14 of app/build.gradle to

abiFilters 'armeabi-v7a', 'arm64-v8a'

INSTALL_PARSE_FAILED_NO_CERTIFICATES

$ adb install example.apk
adb: failed to install example.apk: Failure [INSTALL_PARSE_FAILED_NO_CERTIFICATES: Failed to collect certificates from /data/app/vmdl425632899.tmp/base.apk: Attempt to get length of null array]

distribute debug base apk as well

i could be wrong, but i think base.apk is the release version. if i wanna do e.g. adb shell, run-as com.mafintosh.nodeonandroid i get is not debuggable because the debug.apk built by gradle isnt exposed via the npm version of node-on-android. would be nice if there was a --debug flag that made an apk derived from a debug base apk

roundIcon resource error

No resource identifier found for attribute 'roundIcon' in package 'android'

According to my reading the base apk is not forward-compatible to newer sdk versions which do not allow roundIcon. Hacking it out fixes the issue, but I don't know what the build infrastructure is like or what shape the PR should have.

Full output belog:

$ npm run build

> [email protected] build /home/k/node-on-android/example
> ../cli/bin.js app -o ../build/app.apk -b /usr/local/bin

I: Using Apktool 2.3.1-dirty on base.apk
I: Loading resource table...
I: Decoding AndroidManifest.xml with resources...
I: Loading resource table from file: /home/k/.local/share/apktool/framework/1.apk
I: Regular manifest package...
I: Decoding file-resources...
I: Decoding values */* XMLs...
I: Baksmaling classes.dex...
I: Copying assets and libs...
I: Copying unknown files...
I: Copying original files...
I: Using Apktool 2.3.1-dirty
I: Checking whether sources has changed...
I: Smaling smali folder into classes.dex...
I: Checking whether resources has changed...
I: Building resources...
W: /tmp/node-on-android-1515582291466/base/AndroidManifest.xml:5: error: No resource identifier found for attribute 'roundIcon' in package 'android'
W: 
Exception in thread "main" brut.androlib.AndrolibException: brut.androlib.AndrolibException: brut.common.BrutException: could not exec (exit code = 1): [/usr/bin/aapt, p, --min-sdk-version, 19, --target-sdk-version, 24, --version-code, 1, --version-name, 1.0, --no-version-vectors, -F, /tmp/APKTOOL1865625931939927759.tmp, -0, arsc, -0, js, -0, arsc, -I, /home/k/.local/share/apktool/framework/1.apk, -S, /tmp/node-on-android-1515582291466/base/res, -M, /tmp/node-on-android-1515582291466/base/AndroidManifest.xml]
        at brut.androlib.Androlib.buildResourcesFull(Androlib.java:492)
        at brut.androlib.Androlib.buildResources(Androlib.java:426)
        at brut.androlib.Androlib.build(Androlib.java:305)
        at brut.androlib.Androlib.build(Androlib.java:270)
        at brut.apktool.Main.cmdBuild(Main.java:227)
        at brut.apktool.Main.main(Main.java:75)
Caused by: brut.androlib.AndrolibException: brut.common.BrutException: could not exec (exit code = 1): [/usr/bin/aapt, p, --min-sdk-version, 19, --target-sdk-version, 24, --version-code, 1, --version-name, 1.0, --no-version-vectors, -F, /tmp/APKTOOL1865625931939927759.tmp, -0, arsc, -0, js, -0, arsc, -I, /home/k/.local/share/apktool/framework/1.apk, -S, /tmp/node-on-android-1515582291466/base/res, -M, /tmp/node-on-android-1515582291466/base/AndroidManifest.xml]
        at brut.androlib.res.AndrolibResources.aaptPackage(AndrolibResources.java:456)
        at brut.androlib.Androlib.buildResourcesFull(Androlib.java:478)
        ... 5 more
Caused by: brut.common.BrutException: could not exec (exit code = 1): [/usr/bin/aapt, p, --min-sdk-version, 19, --target-sdk-version, 24, --version-code, 1, --version-name, 1.0, --no-version-vectors, -F, /tmp/APKTOOL1865625931939927759.tmp, -0, arsc, -0, js, -0, arsc, -I, /home/k/.local/share/apktool/framework/1.apk, -S, /tmp/node-on-android-1515582291466/base/res, -M, /tmp/node-on-android-1515582291466/base/AndroidManifest.xml]
        at brut.util.OS.exec(OS.java:95)
        at brut.androlib.res.AndrolibResources.aaptPackage(AndrolibResources.java:450)
        ... 6 more
mv: cannot stat '/home/k/node-on-android/example/build/app.apk.aligned': No such file or directory
Done! apk file is stored in:
/home/k/node-on-android/example/build/app.apk

Cannot find module '/data/user/0/com.mafintosh.nodeonandroid/cache/node'

App launches to blank screen. adb logcat has this:

11-15 18:32:54.434 15631 15650 D Node.js : module.js:487
11-15 18:32:54.434 15631 15650 D Node.js :     throw err;
11-15 18:32:54.434 15631 15650 D Node.js :     ^
11-15 18:32:54.434 15631 15650 D Node.js : 
11-15 18:32:54.434 15631 15650 D Node.js : Error: Cannot find module '/data/user/0/com.mafintosh.nodeonandroid/cache/node'
11-15 18:32:54.434 15631 15650 D Node.js :     at Func
11-15 18:32:54.434 15631 15650 D Node.js : tion.Module._resolveFilename (module.js:485:15)
11-15 18:32:54.434 15631 15650 D Node.js :     at Function.Module._load (module.js:437:25)
11-15 18:32:54.434 15631 15650 D Node.js :     at Function.Module.runMain 
11-15 18:32:54.434 15631 15650 D Node.js : (module.js:605:10)
11-15 18:32:54.434 15631 15650 D Node.js :     at startup (bootstrap_node.js:158:16)
11-15 18:32:54.434 15631 15650 D Node.js :     at bootstrap_node.js:575:3
11-15 18:32:54.464  2939  4745 I ActivityManager: Process node.service (pid 15631) has died
11-15 18:32:54.464  2939  4745 D ActivityManager: cleanUpApplicationRecord -- 15631
11-15 18:32:54.464  2939  4745 W ActivityManager: App Op not allow to restart app com.mafintosh.nodeonandroid/10156

I poked around in adb sh and found the apk path:

ASUS_Z01H_1:/ $ pm list packages -f | grep mafintosh                                                                                                                                
package:/data/app/com.mafintosh.nodeonandroid-1/base.apk=com.mafintosh.nodeonandroid
ASUS_Z01H_1:/ $ ls /data/app
ls: /data/app: Permission denied
1|ASUS_Z01H_1:/ $ ls /data/app/com.mafintosh.nodeonandroid-1
base.apk lib oat 
ASUS_Z01H_1:/ $ ls /data/app/com.mafintosh.nodeonandroid-1/lib                                                                                                                      
arm64
ASUS_Z01H_1:/ $ ls /data/app/com.mafintosh.nodeonandroid-1/lib/arm64/                                                                                                               
libc++_shared.so libnative-lib.so libnode.so 

but no cached folder in there...

relevant code is here: https://github.com/node-on-mobile/node-on-android/blob/master/app/src/main/java/com/mafintosh/nodeonandroid/NodeService.java#L37

apk?

just a reminder to post an APK because getting the build env setup is way too hard!

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.