Making an Android Spy App! Working with and Node.js

Currently, I am working on an android project in which the main task is to fetch user data. In this post, I will tell you about, how to create a node js server and how to transfer data in real-time between two machines using web sockets.

What is a Web-socket?

Wiki says,

Web-socket is a computer communications protocol, providing full-duplex communication channels over a single TCP connection.

The Web-socket protocol enables interaction between a web client (such as a browser) and a web server with lower overheads, facilitating real-time data transfer from and to the server.

So what is the use of Web-socket in my project?

The web app sends a command to the android app (bot) to send some data back to it. So I have to communicate with the server, the web app and the bot in real-time, so I opted for web-sockets.

I am using the library. It has two variants – One for server-side and another for client side. for android app and for node.js i.e., server side.

What is node.js? What will it do? Is it is necessary?

Node.js creates a server by which we can generate dynamic page content, can create, open, read, write, delete, and close files on the server. Node.js uses JavaScript on the server-side as the language.

In this project, we are using the library for managing seamlessly communication between client and server. But problem is that server-side library for is only available in node.js only.

You can create a node.js server just by the code below:-

Now, let’s dig into the android part.

Requirements to start this project:

  • Android Studio – You should be comfortable with android studio
  • Programming language for Android – Java or Kotlin – I’m working with Kotlin
  • Basics of Node.js and

Let’s start πŸ™‚

  1. Make a new android studio project.
  2. Create an activity named main activity.
  3. Add
    implementation ''

    to your app level build.gradle dependencies.

  4. Add the following uses-permission tags to your manifest file

Now what we want to do is to fetch user data while the app is running in the background. So we have to create a service which will be running in the background 24×7.  Create a service named CommandService, which extends Service.

Lets, talk about working of MainActivity first. It is simple and straightforward and has to get all uses-permission from the user and then start the service. Once service is started with all uses-permission MainActivity is done. See the source code of MainActivity here.

Now I’m assuming that CommandService(which is an App Service) is started and running with all uses-permissions. Our next task to setup and accept commands from server via the socket and answer to them by sending required data back to the server.

As you can see that I’m connecting to the server and sending some basic details about the device back to the server. CommonParams contains all of these details. UID is to define android device uniquely. If you don’t understand this, leave a comment.

The connection is now established and android device is uniquely identified on the server and we can communicate bidirectionally i.e., the server can send data to the android device and vice-versa πŸ™‚. We can send different types of data through the socket, but we only need to send string type data. For sending an image we can convert it into a string by encoding it into base64. JSON is also converted to a string and emitted through the socket. Read more about JSON here.


You have to get uses-permission by yourself.

Your major task is here to run service for almost 100% time or say >80%. Because after some time android stops your service due to either lack of resources or saving battery or some other optimization. I’ll write about it later or you can google it.


Now, I am going to show you how to fetch all contacts from the bot.
  • First, we have to tell the bot to fetch user’s contacts, which we can do by sending a keyword to bot from server via socket i.e.,  getContacts.
  • Now we have to fetch all contacts from the android’s on-device storage.
  • After retrieving contacts from Android, we have to send contacts back to the server via the socket.
  • Now we have user’s contacts on the server. Next task is to display them as you want. Isn’t it simple?

When it’s complete, following images show the end result:

First Step – Send Command to Bot from Server
socket.emit('commands', {commands: [{command: 'getContacts'}]);

Run above line of code from the node.js server. Where socket is a connection between server and bot. And we are emitting an event named commands and sending a JSON object with the command name.

Second Step – Fetch all contacts from Android database

Make a new class named GetContactsTask.kt and add below code in it.

If you have read the above code then you would have realized that both second and third steps are covered in it. Function getContacts() is retrieving all the contacts and converting them to a JSON string. After that function uploadData() uploads the contacts to Node.js server.

Receive data on Node.js server

socket.on('usrData', function (data) {

Similarly, we can get all other user data like – SMS, call-logs, location, images, videos, etc.

Fourth Step – Displaying data either on web-app or mobile-app

Node.js server has the user data now. We just have to display it somewhere, but I am not going to that part right now. Maybe, I’ll write about it later 😜. Keep watching this space.

You can see the complete project on GitHub(and clone it 😜):

  • You will find Android app code here,
  • and server-side Node.js and JavaScript web-app here.

If you’ve queries/suggestion, feel free to leave a comment below.

19 thoughts on “Making an Android Spy App! Working with and Node.js

  • August 11, 2018 at 8:48 am

    if android stops the services due to any reasons, how can we establish the connection again?
    Or will we have to make user install the app again?
    Because, keeping this service running all the time is not really possible.

    Also, any thoughts on getting access to the internal storage?

    i have been working/experimenting on trying to get access to all kind of files on storage and uploading them on a cloud storage (just like how google photos work) and periodically sync it like every 24 hours.
    This way practically we have everything there is on the mobile without actually needing a live backdoor which keeps dying after some point.
    Let me know what do you think.

    • September 1, 2018 at 12:26 pm

      Happy to hear from you Zyglrox

      You are right, we cannot keep our service running 24Γ—7, but we can try our best. So there are some methods which can help in running service continuosly:
      1. Return START_STICKY from your service onStartCommand method, obviously you do know that. By doing this Android restart your service if service was closed due to lack of resources.
      2. Using the Alarm Manager class you can trigger an alarm after an interval to start your service. I’ll send you another mail explaining how to do that.
      3. Once, I tested how WhatsApp keeps its service running, so I turn off my internet and then force closed WhatsApp and waited for service to be restart. But service didn’t start. But when I turn on the internet service started. Then I realize that server (GCM) is communicating with the app. So you can restart your service by using Firebase. You can integrate firebase notification in your app and then send notification from firebase. This will start firebase service in your app and in that service you can restart your original service even if your app is forced closed. Method 1 and 2 will not work if your app is closed but this will. I’ll send you my code in leading mail(s). Really its very nice to hear from you. Happy to help! πŸ™‚

      For uploading photos you can listen to content resolver :-
      **contentResolver.registerContentObserver(android.provider.MediaStore.Images.Media.INTERNAL_CONTENT_URI, true,

      private var ContentObserver: ContentObserver = object : ContentObserver(Handler()) {
      override fun onChange(selfChange: Boolean) {
      //This function is called when there is change in content i.e., insertion, deletion, modification …

  • August 18, 2018 at 5:19 am


    I really appreciate your work, I try to export the application with android studio but I have an error message. Can not start compilation: the output path is not specified for “Android_Spy_App-master” module.
    Specify the output path in the Project Structure dialog. I would like to know if it is possible to have unique environmental listening device.

    Thank you for your help

  • August 18, 2018 at 8:11 am

    Hello again,

    I fix this problem but now I have this error message: Android Source Generator: Error: Can not find bundle for base name messages.AndroidJpsBundle, locale en_US
    java.util.MissingResourceException: Can not find bundle for base name messages.AndroidJpsBundle, locale en_US
    at java.util.ResourceBundle.throwMissingResourceException (
    at java.util.ResourceBundle.getBundleImpl (
    at java.util.ResourceBundle.getBundle (
    at (
    at (
    at (
    at (
    at (
    at org.jetbrains.jps.incremental.IncProjectBuilder.runModuleLevelBuilders (
    at org.jetbrains.jps.incremental.IncProjectBuilder.runBuildersForChunk (
    at org.jetbrains.jps.incremental.IncProjectBuilder.buildTargetsChunk (
    at org.jetbrains.jps.incremental.IncProjectBuilder.buildChunkIfAffected (
    at org.jetbrains.jps.incremental.IncProjectBuilder.buildChunks (
    at org.jetbrains.jps.incremental.IncProjectBuilder.runBuild (
    at (
    at org.jetbrains.jps.cmdline.BuildRunner.runBuild (
    at org.jetbrains.jps.cmdline.BuildSession.runBuild (
    at (
    at org.jetbrains.jps.cmdline.BuildMain $ MyMessageHandler.lambda $ channelRead0 $ 0 (
    at org.jetbrains.jps.service.impl.SharedThreadPoolImpl.lambda $ executeOnPooledThread $ 0 (
    at java.util.concurrent.Executors $ (
    at (
    at java.util.concurrent.ThreadPoolExecutor.runWorker (
    at java.util.concurrent.ThreadPoolExecutor $ (
    at (

    thank you very much

  • December 29, 2018 at 7:54 am

    Hey there! This post couldn’t be written any better! Reading through this post reminds me of my old room mate! He always kept chatting about this. I will forward this article to him. Fairly certain he will have a good read. Thank you for sharing!

    • April 15, 2019 at 11:42 pm

      Thanks, Mate!

  • January 7, 2019 at 11:33 am

    How do i read whatsapp message ?

    • April 15, 2019 at 11:42 pm

      I have no idea right now about outgoing messages, but you can read incoming messages by reading notifications.

    • April 15, 2019 at 11:40 pm

      Yeah, that will be an honor.

    • April 15, 2019 at 11:38 pm

      Yeah, sure. Write your queries on this thread.

  • February 14, 2019 at 9:28 pm

    Good way of explaining, and nice piece of writing to get facts concerning my presentation topic, which
    i am going to deliver in academy.

  • March 7, 2019 at 4:34 am

    Hi there, You have done an incredible job. I’ll certainly digg it and personallysuggest to my friends. I am confident they will be benefited from this site.

  • March 30, 2019 at 11:35 pm

    I was suggested this website by my cousin. I’m not sure whether this post is written by him as nobody else know such detailed about my difficulty. You’re incredible! Thanks!

  • May 7, 2019 at 7:02 am

    You’re so interesting! I do not think I’ve truly read something like this before.
    So good to find somebody with original thoughts on this subject matter.
    Really.. thanks for starting this up. This site is one thing
    that is needed on the internet, someone with a bit of originality!


Leave a Reply

Your email address will not be published. Required fields are marked *