WebSockets and Andoid

29 Nov 2017 | Java

Not so long ago, there was a desire to begin to deal with the OS Android 7.1, for a couple of days of reading the documentation and various forums - appeared my first application. The application allows you to exchange messages between clients in real time, and consumes very few resources both on the client and on the server.

Server

To run the application, you need to install node.js with npm. Then install socket.io

$ npm install socket.io

Create file server.js:

var io = require('socket.io')(3000);

io.on('connection', function (socket) {
    socket.on('send message', function (text) {
        console.log(text);

        // Отправка сообщения всем клинтам и самому себе
        socket.emit('get message', {
            message: text
        });

        socket.broadcast.emit('get message', {
            message: text
        });
    });
});

And run in the console:

$ node server.js

Everything, the server works, it can be accessed at 127.0.0.1:3000

Note that 127.0.0.1 here and on - you need to replace it with your server's address.

Client

import com.github.nkzawa.socketio.client.IO;
import com.github.nkzawa.socketio.client.Socket;
import com.github.nkzawa.emitter.Emitter;

public class MainActivity extends AppCompatActivity {
    private static final String TAG = "MainActivity";

    private Socket mSocket;

    private Emitter.Listener onGetMessage = new Emitter.Listener() {
        @Override
        public void call(final Object... args) {
            MainActivity.this.runOnUiThread(new Runnable() {
                @Override
                public void run() {
                    JSONObject data = (JSONObject) args[0];
                    String message;

                    try {
                        message = data.getString("message");
                    } catch (JSONException e) {
                        return;
                    }

                    sendNotification("New notify", message);
                }
            });
        }
    };

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        final Button connect3000 = findViewById(R.id.connect3000);
        connect3000.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                try {
                    mSocket = IO.socket("http://127.0.0.1:3000");
                } catch (URISyntaxException e) {
                    Log.e(TAG, e.getMessage());
                }

                mSocket.connect();
                // Subscription to event 'get message'
                mSocket.on("get message", onGetMessage);
            }
        });

        final Button disconnect = findViewById(R.id.disconnect);
        disconnect.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                // Unsubscribe from event 'get message'
                mSocket.off("get message", onGetMessage);

                mSocket.disconnect();
            }
        });

        final EditText message = findViewById(R.id.message);
        final ImageButton sendMessage = findViewById(R.id.sendMessage);

        sendMessage.setOnClickListener(new View.OnClickListener() {
            public void onClick(View v) {
                mSocket.emit("send message", message.getText());
                message.setText("");
            }
        });
    }

    protected void sendNotification(String title, String message) {
        // Sending notifications about a new message to the notification center
        NotificationCompat.Builder notificationBuilder = new NotificationCompat.Builder(this, "M_CH_ID");

        notificationBuilder.setAutoCancel(true)
                .setDefaults(Notification.DEFAULT_ALL)
                .setWhen(System.currentTimeMillis())
                .setSmallIcon(android.R.drawable.ic_dialog_info)
                .setTicker("Hearty365")
                .setContentTitle(title)
                .setContentText(message)
                .setContentInfo("Info");

        NotificationManager notificationManager = (NotificationManager) this.getSystemService(Context.NOTIFICATION_SERVICE);
        notificationManager.notify(1, notificationBuilder.build());
    }
}