Build Mobile Chat App with Pusher in Android Studio

In this blog we will show you how to easily build a mobile chat app with Pusher. As with our previous tutorial, Making ReactJS Realtime With Websockets, together we will build a group​​ chat application, leading you through how to use Pusher to send and show realtime messages in your UI.

Download Android Studio from the link given blow according to your operating system Windows, Mac, Linux, Chrome OS etc.

Link:​​ https://developer.android.com/studio

More downloads are available here.​​ 

Link:​​ https://developer.android.com/studio/archive

Setting Up

Once you’ve set up your application on Android Studio, or your preferred IDE, let’s start with installing Pusher as a dependency. In the build.gradle file of your application module, add:

repositories {

 ​​​​ maven { url 'http://clojars.org/repo' }

}

 

dependencies {

 ​​​​ compile​​ 'com.pusher:pusher-java-client:1.0.0',

 ​​​​ compile 'com.loopj.android:android-async-http:1.4.9', // for our HTTP requests later

 ​​​​ compile 'com.google.code.gson:gson:2.2.4', // for parsing JSON

 ​​​​ compile 'com.squareup.picasso:picasso:2.1.1' // for image rendering

}

Sync the gradle project and Pusher, as long as other modules we’ll need later, should now be installed! Be sure to keep your application credentials to hand when we start adding some realtime magic. You can find your credentials when you create an app after signing up for a free account.

Click the above link to sign up for Pusher and create your free account.

Link:​​ https://pusher.com/

The flow of our app will be like so:​​ the user will input a message in their app, which will send a POST request to our server. In this example, I will use a simple NodeJS server to provide a single API endpoint, for which you can see the code. However, as we have a consistent top-level API across all our server libraries, what is shown here can be easily applied to any other web framework you wish to use.

Once our server receives the POST request, they will trigger a simple Pusher message to all connected clients, which will show the messages​​ in realtime. If you wish to download the demo Android app, you can do so on the Play Store, and this will allow you to chat with our web version to test things out.

If you get stuck at any point, feel free to browse the Android source code here and the NodeJS server code here.

Sending Messages

Client-Side

So to set up, create a new app with an initial blank activity, and use the default name of MainActivity. In activity_main.xml let’s go and create the input bar for our chat messages.

<RelativeLayout

 ​​ ​​ ​​​​ xmlns:android="http://schemas.android.com/apk/res/android"

 ​​ ​​ ​​​​ xmlns:tools="http://schemas.android.com/tools"

 ​​ ​​ ​​​​ android:layout_width="match_parent"

 ​​ ​​ ​​​​ android:layout_height="match_parent"

 ​​ ​​ ​​​​ android:orientation="vertical"

 ​​ ​​ ​​​​ tools:context=".MainActivity"

 ​​ ​​ ​​​​ >

 

 ​​ ​​ ​​​​ <LinearLayout

 ​​ ​​ ​​ ​​ ​​ ​​ ​​​​ android:id="@+id/input_bar"

 ​​ ​​ ​​ ​​ ​​ ​​ ​​​​ android:layout_width="fill_parent"

 ​​ ​​ ​​ ​​ ​​ ​​ ​​​​ android:layout_height="75dp"

 ​​ ​​ ​​ ​​ ​​ ​​ ​​​​ android:layout_alignParentBottom="true"

 ​​ ​​ ​​ ​​ ​​ ​​ ​​​​ android:background="@color/white"

 ​​ ​​ ​​ ​​ ​​ ​​ ​​​​ android:orientation="horizontal" >

 

 ​​ ​​ ​​ ​​ ​​ ​​ ​​​​ <EditText

 ​​ ​​ ​​ ​​ ​​ ​​ ​​ ​​ ​​ ​​ ​​​​ android:id="@+id/message_input"

 ​​ ​​ ​​ ​​ ​​ ​​ ​​ ​​ ​​ ​​ ​​​​ android:layout_weight="0.7"

 ​​ ​​ ​​ ​​ ​​ ​​ ​​ ​​ ​​ ​​ ​​​​ android:layout_width="0dp"

 ​​ ​​ ​​ ​​ ​​ ​​ ​​ ​​ ​​ ​​ ​​​​ android:layout_height="match_parent"

 ​​ ​​ ​​ ​​ ​​ ​​ ​​ ​​ ​​ ​​ ​​​​ android:inputType="text" />

 

 ​​ ​​ ​​ ​​ ​​ ​​ ​​​​ <Button

 ​​ ​​ ​​ ​​ ​​ ​​ ​​ ​​ ​​ ​​ ​​​​ android:id="@+id/send_button"

 ​​ ​​ ​​ ​​ ​​ ​​ ​​ ​​ ​​ ​​ ​​​​ android:layout_width="wrap_content"

 ​​ ​​ ​​ ​​ ​​ ​​ ​​ ​​ ​​ ​​ ​​​​ android:layout_height="wrap_content"

 ​​ ​​ ​​ ​​ ​​ ​​ ​​ ​​ ​​ ​​ ​​​​ android:layout_marginTop=5dp"

 ​​ ​​ ​​ ​​ ​​ ​​ ​​ ​​ ​​ ​​ ​​​​ android:layout_marginRight="20dp"

 ​​​​  ​​ ​​ ​​ ​​ ​​ ​​ ​​ ​​ ​​​​ android:text="Send"/>

 

 ​​ ​​ ​​​​ </LinearLayout>

 

</RelativeLayout>

This will stick to the bottom of our view, and have an input (i.e. an EditText) for typing messages, and a Button for sending them, which we have given the respective IDs of​​ message_input and send_button.

Jnk9UI4AAQIECBAgQOCfwAZHV5UgmJ3lygAAAABJRU5ErkJggg== - Build Mobile Chat App with Pusher in Android Studio

Now in our MainActivity.java class, let’s set up the listener for pressing the ‘Send’ button.

public class MainActivity extends ActionBarActivity implements View.OnClickListener {

 

 ​​ ​​ ​​​​ EditText messageInput;

 ​​ ​​ ​​​​ Button sendButton;

 

 ​​ ​​ ​​​​ @Override

 ​​ ​​ ​​​​ protected void onCreate(Bundle savedInstanceState) {

 ​​ ​​ ​​ ​​ ​​ ​​ ​​​​ super.onCreate(savedInstanceState);

 ​​ ​​ ​​ ​​ ​​ ​​ ​​​​ setContentView(R.layout.activity_main);

 

 ​​ ​​ ​​ ​​ ​​ ​​ ​​​​ // get our input field by its ID

 ​​ ​​ ​​ ​​ ​​ ​​ ​​​​ messageInput = (EditText) findViewById(R.id.message_input);

 

 

 ​​ ​​ ​​ ​​ ​​ ​​ ​​ ​​​​ // get our button by its ID

 ​​ ​​ ​​ ​​ ​​ ​​ ​​​​ sendButton = (Button) findViewById(R.id.send_button);

 

 ​​ ​​ ​​ ​​ ​​ ​​ ​​​​ // set its click listener

 ​​ ​​ ​​ ​​ ​​ ​​ ​​​​ sendButton.setOnClickListener(this);

 ​​ ​​ ​​​​ }

Now we’ll have to implement the​​ View.onClickListener interface. Here we’ll simply get the text of messageInput and POST it to our server.

 ​​ ​​ ​​​​ @Override

 ​​ ​​ ​​​​ public void onClick(View v) {

 ​​ ​​ ​​ ​​ ​​ ​​ ​​​​ postMessage();

 ​​ ​​ ​​​​ }

 

 ​​ ​​ ​​​​ private void postMessage() ​​ {

 ​​ ​​ ​​​​ }

In this tutorial, I’ll be using​​ the AsyncHTTPClient library to send messages to our server. So now, within our MainActivity‘s postMessage method, we’ll get the text of the messageInput, and POST it, along with a username and timestamp. In our example app, we’ve also implemented a LoginActivity to get the user’s Twitter username, but in order to focus on the chat element itself we’re going to skip this. But feel free to browse the source code; it should be fairly straightforward.

Let’s go ahead with creating and sending our request parameters:

import com.loopj.android.http.AsyncHttpClient;

import com.loopj.android.http.RequestParams;

 

 ​​ ​​ ​​​​ private void postMessage() ​​ {

 

 ​​ ​​ ​​ ​​ ​​ ​​ ​​​​ String text = messageInput.getText().toString();

 

 ​​ ​​ ​​ ​​ ​​ ​​ ​​ ​​​​ // return if the text is blank

 ​​ ​​ ​​ ​​ ​​ ​​ ​​​​ if (text.equals("")) {

 ​​ ​​ ​​ ​​ ​​ ​​ ​​ ​​ ​​ ​​ ​​​​ return;

 ​​ ​​ ​​ ​​ ​​ ​​ ​​​​ }

 

 

 ​​ ​​ ​​ ​​ ​​ ​​ ​​​​ RequestParams params = new RequestParams();

 

 ​​ ​​ ​​ ​​ ​​ ​​ ​​​​ // set our JSON object

 ​​ ​​ ​​ ​​ ​​ ​​ ​​​​ params.put("text", text);

 ​​ ​​ ​​ ​​ ​​ ​​ ​​​​ params.put("name", username);

 ​​ ​​ ​​ ​​ ​​ ​​ ​​​​ params.put("time", new Date().getTime());

 

 ​​ ​​ ​​ ​​ ​​ ​​ ​​​​ //​​ create our HTTP client

 ​​ ​​ ​​ ​​ ​​ ​​ ​​​​ AsyncHttpClient client = new AsyncHttpClient();

 ​​ ​​ ​​​​ }

 

Set a MESSAGES_ENDPOINT string in MainActivity to point to the URL of your server. Then let’s make it so that when the request is successful, it clears the messageInput,​​ or when it fails it alerts the user that something went wrong:

client.post(MESSAGES_ENDPOINT, params, new JsonHttpResponseHandler(){

 

 ​​ ​​ ​​​​ @Override

 ​​ ​​ ​​​​ public void onSuccess(int statusCode, Header[] headers, JSONObject response) {

 ​​ ​​ ​​ ​​ ​​ ​​ ​​​​ runOnUiThread(new​​ Runnable() {

 ​​ ​​ ​​ ​​ ​​ ​​ ​​ ​​ ​​ ​​ ​​​​ @Override

 ​​ ​​ ​​ ​​ ​​ ​​ ​​ ​​ ​​ ​​ ​​​​ public void run() {

 ​​ ​​ ​​ ​​ ​​ ​​ ​​ ​​ ​​ ​​ ​​ ​​ ​​ ​​ ​​​​ messageInput.setText("");

 ​​ ​​ ​​ ​​ ​​ ​​ ​​ ​​ ​​ ​​ ​​​​ }

 ​​ ​​ ​​ ​​ ​​ ​​ ​​​​ });

 ​​ ​​ ​​​​ }

 

 ​​ ​​ ​​​​ @Override

 ​​ ​​ ​​​​ public void onFailure(int statusCode, Header[] headers, String responseString, Throwable​​ throwable) {

 ​​ ​​ ​​ ​​ ​​ ​​ ​​​​ Toast.makeText(

 ​​ ​​ ​​ ​​ ​​ ​​ ​​ ​​ ​​ ​​ ​​ ​​ ​​ ​​ ​​​​ getApplicationContext(),

 ​​ ​​ ​​ ​​ ​​ ​​ ​​ ​​ ​​ ​​ ​​ ​​ ​​ ​​ ​​​​ "Something went wrong :(",

 ​​ ​​ ​​ ​​ ​​ ​​ ​​ ​​ ​​ ​​ ​​ ​​ ​​ ​​ ​​​​ Toast.LENGTH_LONG

 ​​ ​​ ​​ ​​ ​​ ​​ ​​​​ ).show();

 ​​ ​​ ​​​​ }

});

Sweet – so now the client is set up to send an input to the server, let’s​​ implement our mini-API.

Server-Side

Install NodeJS and Express if you haven’t already. Generate your chat backend with:

$ express chat-backend​​ 

$ cd chat-backend​​ 

$ npm install

Now install the Pusher Node library with:

$ npm install pusher --save

Now initialize the Pusher object in your server file with your application credentials:

var pusher = new Pusher({

 ​​​​ appId: "your app id",

 ​​​​ key: "your app key",

 ​​​​ secret: "your app secret"

});

Now create the endpoint that receives JSON from the client. Then we’ll​​ fire a Pusher event called new_message on a channel called messages, passing along the data we received from the client.

app.post('/messages', function(req, res){

 ​​​​ var message = req.body;

 ​​​​ pusher.trigger('messages', 'new_message', message);

 ​​​​ res.json({success: 200});

});

At this point, you may wish to store messages, or sanitize them with a library such as sanitize-html so that you can display them on a web view. But this should be enough to demonstrate our chat app at work.

So fire up your server, and run your mobile app either in an emulator or on your device. Meanwhile, open up the Pusher Debug Console for your app on your dashboard. On your emulator or device, you should see an input bar at the bottom of the app. Type in a message and touch the ‘Send’​​ button, and you should see messages pop up in realtime on your Debug Console. Cool, huh?

Showing Live Chat Messages

That might be cool – but it’s not enough. Let’s have our Android client listen for incoming chat messages, and show them in a list.

So in activity_main.xml, add a new ListView as the first child of RelativeLayout and above the LinearLayout that wraps our input bar. Your layout XML should look like so:

<RelativeLayout

 ​​ ​​ ​​​​ xmlns:android="http://schemas.android.com/apk/res/android"

 ​​ ​​ ​​​​ xmlns:tools="http://schemas.android.com/tools"

 ​​ ​​ ​​​​ android:layout_width="match_parent"

 ​​ ​​ ​​​​ android:layout_height="match_parent"

 ​​ ​​ ​​​​ android:orientation="vertical"

 ​​ ​​ ​​​​ tools:context=".MainActivity"

 ​​ ​​ ​​​​ >

 ​​ ​​ ​​​​ <ListView

 ​​ ​​ ​​ ​​ ​​ ​​ ​​​​ android:layout_marginTop="10dp"

 ​​ ​​ ​​ ​​ ​​ ​​ ​​​​ android:layout_marginBottom="80dp"

 ​​ ​​ ​​ ​​ ​​ ​​ ​​​​ android:layout_width="match_parent"

 ​​ ​​ ​​ ​​ ​​ ​​ ​​​​ android:layout_height="500dp"

 ​​ ​​ ​​ ​​ ​​ ​​ ​​​​ android:id="@+id/messages_view"

 ​​ ​​ ​​ ​​ ​​ ​​ ​​​​ android:layout_alignParentTop="true"

 ​​ ​​ ​​ ​​ ​​ ​​ ​​​​ android:layout_alignParentLeft="true"

 ​​ ​​ ​​ ​​ ​​ ​​ ​​​​ android:layout_alignParentStart="true" />

 

 ​​ ​​ ​​​​ <LinearLayout

 ​​ ​​ ​​ ​​ ​​ ​​ ​​​​ android:id="@+id/input_bar"

 ​​ ​​ ​​ ​​ ​​ ​​ ​​​​ android:layout_width="fill_parent"

 ​​ ​​ ​​ ​​ ​​ ​​ ​​​​ android:layout_height="75dp"

 ​​ ​​ ​​ ​​ ​​ ​​ ​​​​ android:layout_alignParentBottom="true"

 ​​ ​​ ​​ ​​ ​​ ​​ ​​​​ android:background="@color/white"

 ​​ ​​ ​​ ​​ ​​ ​​ ​​​​ android:orientation="horizontal" >

 

 ​​ ​​ ​​ ​​ ​​ ​​ ​​​​ <EditText

 ​​ ​​ ​​ ​​ ​​ ​​ ​​ ​​ ​​ ​​ ​​​​ android:id="@+id/message_input"

 ​​ ​​ ​​ ​​ ​​ ​​ ​​ ​​ ​​ ​​ ​​​​ android:layout_weight="0.7"

 ​​ ​​ ​​ ​​ ​​ ​​ ​​ ​​ ​​ ​​ ​​​​ android:layout_width="0dp"

 ​​ ​​ ​​ ​​ ​​ ​​ ​​ ​​ ​​ ​​ ​​​​ android:layout_height="match_parent"

 ​​ ​​ ​​ ​​ ​​ ​​ ​​ ​​ ​​ ​​ ​​​​ android:inputType="text" />

 

 ​​ ​​ ​​ ​​ ​​ ​​ ​​​​ <Button

 ​​ ​​ ​​ ​​ ​​ ​​ ​​ ​​ ​​ ​​ ​​​​ android:id="@+id/send_button"

 ​​ ​​ ​​ ​​ ​​ ​​ ​​ ​​ ​​ ​​ ​​​​ android:layout_width="wrap_content"

 ​​ ​​ ​​ ​​ ​​ ​​ ​​ ​​ ​​ ​​ ​​​​ android:layout_height="wrap_content"

 ​​ ​​ ​​ ​​ ​​ ​​ ​​ ​​ ​​ ​​ ​​​​ android:layout_marginTop="20dp"

 ​​ ​​ ​​ ​​ ​​ ​​ ​​ ​​ ​​ ​​ ​​​​ android:layout_marginRight="20dp"

 ​​ ​​ ​​ ​​ ​​ ​​ ​​ ​​ ​​ ​​ ​​​​ android:text="Send"/>

 

 ​​ ​​ ​​​​ </LinearLayout>

 

</RelativeLayout>

In order to display each message within the ListView, we’ll have to create an adapter that turns a list into a set of views. In our MainActivity#onCreate method, let’s bind our ListViewto this adapter:

public class MainActivity extends ActionBarActivity implements View.OnClickListener {

 

 ​​ ​​ ​​​​ ...

 ​​ ​​ ​​​​ MessageAdapter messageAdapter;

 

 ​​ ​​ ​​​​ @Override

 ​​ ​​ ​​​​ protected void onCreate(Bundle savedInstanceState) {

 

 ​​ ​​ ​​ ​​ ​​ ​​ ​​​​ ...

 

 ​​ ​​ ​​ ​​ ​​ ​​ ​​​​ messageAdapter = new MessageAdapter(this, new ArrayList<Message>());

 ​​ ​​ ​​ ​​ ​​ ​​ ​​​​ final ListView messagesView = (ListView) findViewById(R.id.messages_view);

 ​​ ​​ ​​ ​​ ​​ ​​ ​​​​ messagesView.setAdapter(messageAdapter);

 ​​ ​​ ​​​​ }

Our Message.java class​​ which comprises the list is very straightforward:

public class Message {

 ​​ ​​ ​​​​ public String text;

 ​​ ​​ ​​​​ public String name;

 ​​ ​​ ​​​​ public long time;

}

Now let’s create our MessageAdapter, which is, as you can see above, initialized with our MainActivity‘s context, and the resource (an ArrayList of Messages):

public class MessageAdapter extends BaseAdapter {

 

 ​​ ​​ ​​​​ Context messageContext;

 ​​ ​​ ​​​​ ArrayList<Message> messageList;

 

 ​​ ​​ ​​​​ public MessageAdapter(Context context, ArrayList<Message> messages){

 ​​ ​​ ​​ ​​ ​​ ​​ ​​​​ messageList​​ = messages;

 ​​ ​​ ​​ ​​ ​​ ​​ ​​​​ messageContext = context;

 ​​ ​​ ​​​​ }

When you extend BaseAdapter, your IDE will ask you to implement getCount, getItem and getItemId, which we can do so:

 ​​ ​​ ​​​​ @Override

 ​​ ​​ ​​​​ public int getCount() {

 ​​ ​​ ​​ ​​ ​​ ​​ ​​​​ return messageList.size();

 ​​ ​​ ​​​​ }

 

 ​​ ​​ ​​​​ @Override

 ​​ ​​ ​​​​ public Object getItem(int position) {

 ​​ ​​ ​​ ​​ ​​ ​​ ​​​​ return messageList.get(position);

 ​​ ​​ ​​​​ }

 

 ​​ ​​ ​​​​ @Override

 ​​ ​​ ​​​​ public long getItemId(int position) {

 ​​ ​​ ​​ ​​ ​​ ​​ ​​​​ return position;

 ​​ ​​ ​​​​ }

Finally we’ll have to implement getView, which is needed to convert an item in the ArrayListof Messages to a view. First, we need to create a MessageViewHolder to encapsulate the views we need to be a part of the message. In this case, we’re going to have a thumbnailImageView – for the user’s Twitter avatar – a senderView to show who sent the message, and a bodyView to show the content of the message. Within our MessageAdapter, add a private nested class:

 ​​ ​​ ​​​​ private static class MessageViewHolder {

 ​​ ​​ ​​ ​​ ​​ ​​ ​​​​ public ImageView thumbnailImageView;

 ​​ ​​ ​​ ​​ ​​ ​​ ​​​​ public TextView senderView;

 ​​ ​​ ​​ ​​ ​​ ​​ ​​​​ public TextView bodyView;

 ​​ ​​ ​​​​ }

We must also describe the layout of our message view. Let’s give the view of our thumbnail an ID of img_thumbnail, the view of the sender and ID of message_sender, and the content of the message an ID of message_sender:

<?xml version="1.0" encoding="utf-8"?>

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"

 ​​ ​​ ​​​​ android:layout_width="match_parent" android:layout_height="75dp">

 

 ​​ ​​ ​​​​ <ImageView

 ​​ ​​ ​​ ​​ ​​ ​​ ​​​​ android:id="@+id/img_thumbnail"

 ​​ ​​ ​​ ​​ ​​ ​​ ​​​​ android:layout_marginLeft="25dp"

 ​​ ​​ ​​ ​​ ​​ ​​ ​​​​ android:layout_alignParentLeft="true"

 ​​ ​​ ​​ ​​ ​​ ​​ ​​​​ android:layout_centerVertical="true"

 ​​ ​​ ​​ ​​ ​​ ​​ ​​​​ android:scaleType="centerInside"

 ​​ ​​ ​​ ​​ ​​ ​​ ​​​​ android:layout_width="50dp"

 ​​ ​​ ​​ ​​ ​​ ​​ ​​​​ android:layout_height="50dp" />

 

 ​​ ​​ ​​​​ <TextView

 ​​ ​​ ​​ ​​ ​​ ​​ ​​​​ android:id="@+id/message_sender"

 ​​ ​​ ​​ ​​ ​​ ​​ ​​​​ android:layout_marginLeft="25dp"

 ​​ ​​ ​​ ​​ ​​ ​​ ​​​​ android:layout_toRightOf="@+id/img_thumbnail"

 ​​ ​​ ​​ ​​ ​​ ​​ ​​​​ android:layout_alignTop="@+id/img_thumbnail"

 ​​ ​​ ​​ ​​ ​​ ​​ ​​​​ android:layout_width="wrap_content"

 ​​ ​​ ​​ ​​ ​​ ​​ ​​​​ android:layout_height="wrap_content" />

 

 ​​ ​​ ​​​​ <TextView

 ​​ ​​ ​​ ​​ ​​ ​​ ​​​​ android:layout_width="wrap_content"

 ​​ ​​ ​​ ​​ ​​ ​​ ​​​​ android:layout_height="wrap_content"

 ​​ ​​ ​​ ​​ ​​ ​​ ​​​​ android:id="@+id/message_body"

 ​​ ​​ ​​ ​​ ​​ ​​ ​​​​ android:layout_below="@+id/message_sender"

 ​​ ​​ ​​ ​​ ​​ ​​ ​​​​ android:layout_alignLeft="@+id/message_sender"

 ​​ ​​ ​​ ​​ ​​ ​​ ​​​​ />

</RelativeLayout>

Now that we have a MessageViewHolder to encapsulate the visual elements that comprise a message, and a message layout to inflate those elements into, we can go ahead and implement​​ our MessageAdapter#getView method:

 ​​ ​​ ​​​​ @Override

 ​​ ​​ ​​​​ public View getView(int position, View convertView, ViewGroup parent) {

 

 ​​ ​​ ​​ ​​ ​​ ​​ ​​​​ MessageViewHolder holder;

 

 ​​ ​​ ​​ ​​ ​​ ​​ ​​​​ // if there is not already a view created for an item in the Message list.

 

 ​​ ​​ ​​ ​​ ​​ ​​ ​​​​ if​​ (convertView == null){

 ​​ ​​ ​​ ​​ ​​ ​​ ​​ ​​ ​​ ​​ ​​​​ LayoutInflater messageInflater = (LayoutInflater) messageContext.getSystemService(Activity.LAYOUT_INFLATER_SERVICE);

 

 ​​ ​​ ​​ ​​ ​​ ​​ ​​ ​​ ​​ ​​ ​​​​ // create a view out of our `message.xml` file

 ​​ ​​ ​​ ​​ ​​ ​​ ​​ ​​ ​​ ​​ ​​​​ convertView = messageInflater.inflate(R.layout.message, null);

 

 ​​ ​​ ​​ ​​ ​​ ​​ ​​ ​​ ​​ ​​ ​​​​ // create a MessageViewHolder​​ 

 ​​ ​​ ​​ ​​ ​​ ​​ ​​ ​​ ​​ ​​ ​​​​ holder = new MessageViewHolder();

 

 ​​ ​​ ​​ ​​ ​​ ​​ ​​ ​​ ​​ ​​ ​​​​ // set the holder's properties to elements in `message.xml`

 ​​ ​​ ​​ ​​ ​​ ​​ ​​ ​​ ​​ ​​ ​​​​ holder.thumbnailImageView = (ImageView) convertView.findViewById(R.id.img_thumbnail);

 ​​ ​​ ​​ ​​ ​​ ​​ ​​ ​​ ​​ ​​ ​​​​ holder.senderView = (TextView) convertView.findViewById(R.id.message_sender);

 ​​ ​​ ​​ ​​ ​​ ​​ ​​ ​​ ​​ ​​ ​​​​ holder.bodyView = (TextView) convertView.findViewById(R.id.message_body);

 

 ​​ ​​ ​​ ​​ ​​ ​​ ​​ ​​ ​​ ​​ ​​ ​​​​ // assign the holder to the view we will return

 ​​ ​​ ​​ ​​ ​​ ​​ ​​ ​​ ​​ ​​ ​​​​ convertView.setTag(holder);

 ​​ ​​ ​​ ​​ ​​ ​​ ​​​​ } else {

 

 ​​ ​​ ​​ ​​ ​​ ​​ ​​ ​​ ​​ ​​ ​​ ​​ ​​​​ // otherwise fetch an already-created view holder

 ​​ ​​ ​​ ​​ ​​ ​​ ​​ ​​ ​​ ​​ ​​​​ holder = (MessageViewHolder) convertView.getTag();

 ​​ ​​ ​​ ​​ ​​ ​​ ​​​​ }

 

 ​​ ​​ ​​ ​​ ​​ ​​ ​​ ​​​​ // get the message from its​​ position in the ArrayList

 ​​ ​​ ​​ ​​ ​​ ​​ ​​​​ Message message = (Message) getItem(position);

 

 ​​ ​​ ​​ ​​ ​​ ​​ ​​​​ // set the elements' contents

 ​​ ​​ ​​ ​​ ​​ ​​ ​​​​ holder.bodyView.setText(message.text);

 ​​ ​​ ​​ ​​ ​​ ​​ ​​​​ holder.senderView.setText(message.name);

 

 ​​ ​​ ​​ ​​ ​​ ​​ ​​ ​​​​ // fetch the user's Twitter avatar from their username

 ​​ ​​ ​​ ​​ ​​ ​​ ​​ ​​​​ // and place it into the thumbnailImageView.

 ​​ ​​ ​​ ​​ ​​ ​​ ​​​​ Picasso.with(messageContext).

 ​​ ​​ ​​ ​​ ​​ ​​ ​​ ​​ ​​ ​​ ​​ ​​ ​​ ​​ ​​​​ load("https://twitter.com/" + message.name + "/profile_image?size=original").

 ​​ ​​ ​​ ​​ ​​ ​​ ​​ ​​ ​​ ​​ ​​ ​​ ​​ ​​ ​​​​ placeholder(R.mipmap.ic_launcher).

 ​​ ​​ ​​ ​​ ​​ ​​ ​​ ​​ ​​ ​​ ​​ ​​ ​​ ​​ ​​​​ into(holder.thumbnailImageView);

 

 ​​ ​​ ​​ ​​ ​​ ​​ ​​​​ return convertView;

 

 ​​ ​​ ​​​​ }

This method will either find or create a MessageViewHolder associated with the convertViewat a certain position in the list. When it has done so, it will set the​​ text of the bodyView, senderView, and – as in the demo app linked in our introduction – show the Twitter avatar of the sender.

When we listen for Pusher events we will want to add any new messages to our MessageAdapter. Let’s do so now:

 ​​ ​​ ​​​​ public void add(Message message){

 ​​ ​​ ​​ ​​ ​​ ​​ ​​​​ messageList.add(message);

 ​​ ​​ ​​ ​​ ​​ ​​ ​​​​ notifyDataSetChanged();

 ​​ ​​ ​​​​ }

This will add the message to the messageList and notifyDataSetChange() will refresh the adapter, showing the new message.

So now we can go back to MainActivity and start listening for Pusher messages:

 ​​ ​​ ​​​​ @Override

 ​​ ​​ ​​​​ protected void onCreate(Bundle savedInstanceState) {

 

 ​​ ​​ ​​ ​​ ​​ ​​ ​​ ​​​​ ...

 

 ​​ ​​ ​​ ​​ ​​ ​​ ​​ ​​​​ // initialize Pusher

 ​​ ​​ ​​ ​​ ​​ ​​ ​​​​ Pusher pusher = new Pusher("YOUR_APP_KEY");

 

 

 

 

 ​​ ​​ ​​ ​​ ​​ ​​ ​​ ​​​​ // subscribe to our "messages" channel

 ​​ ​​ ​​ ​​ ​​ ​​ ​​​​ Channel channel = pusher.subscribe("messages");

 

 ​​ ​​ ​​ ​​ ​​ ​​ ​​ ​​ ​​​​ // listen for the "new_message" event

 ​​ ​​ ​​ ​​ ​​ ​​ ​​​​ channel.bind("new_message", new SubscriptionEventListener() {

 ​​ ​​ ​​ ​​ ​​ ​​ ​​ ​​ ​​ ​​ ​​​​ ...

 ​​ ​​ ​​ ​​ ​​ ​​ ​​​​ });

 

 ​​ ​​ ​​ ​​ ​​ ​​ ​​​​ // connect to the Pusher API

 ​​ ​​ ​​ ​​ ​​ ​​ ​​​​ pusher.connect();

 

 ​​ ​​ ​​​​ }

So now that we have initialized Pusher, connected to the API, and subscribed to the messages channel, we can now add our SubscriptionEventListener to execute when an event comes in. All we’ll need to do is parse the JSON (in this example I have used the Gson library into a Message object and then add it to the MessageAdapter:

channel.bind("new_message", new SubscriptionEventListener() {

 

 ​​ ​​ ​​​​ @Override

 ​​ ​​ ​​​​ public void onEvent(String channelName, String eventName, final String data) {

 ​​ ​​ ​​ ​​ ​​ ​​ ​​​​ runOnUiThread(new Runnable() {

 ​​ ​​ ​​ ​​ ​​ ​​ ​​ ​​ ​​ ​​ ​​​​ @Override

 ​​ ​​ ​​ ​​ ​​ ​​ ​​ ​​ ​​ ​​ ​​​​ public void run() {

 ​​ ​​ ​​ ​​ ​​ ​​ ​​ ​​ ​​ ​​ ​​ ​​ ​​ ​​ ​​​​ Gson gson = new Gson();

 ​​ ​​ ​​ ​​ ​​ ​​ ​​ ​​ ​​ ​​ ​​ ​​ ​​ ​​ ​​​​ Message message = gson.fromJson(data, Message.class);

 ​​ ​​ ​​ ​​ ​​ ​​ ​​ ​​ ​​ ​​ ​​ ​​ ​​ ​​ ​​​​ messageAdapter.add(message);

 

 ​​ ​​ ​​ ​​ ​​​​  ​​ ​​ ​​ ​​ ​​ ​​ ​​ ​​ ​​​​ // have the ListView scroll down to the new message

 ​​ ​​ ​​ ​​ ​​ ​​ ​​ ​​ ​​ ​​ ​​ ​​ ​​ ​​ ​​​​ messagesView.setSelection(messageAdapter.getCount() - 1);

 ​​ ​​ ​​ ​​ ​​ ​​ ​​ ​​ ​​ ​​ ​​​​ }

 

 ​​ ​​ ​​ ​​ ​​ ​​ ​​​​ });

 ​​ ​​ ​​​​ }

 

});

Now that whenever we have a new_message event come in, we can simply add it to our​​ MessageAdapter, and new messages will appear in realtime! Run your app on an emulator or device, and give it a spin. If you encounter any issues, do consult the source code.

DyBAgQIECAAIHtERDmtkdPLQECBAgQIEBgkgX6Fy9ePMkteHkCBAgQIECAAIGowP8B6KwpXSmrrUoAAAAASUVORK5CYII= - Build Mobile Chat App with Pusher in Android Studio

​​ Get Pushing

Hopefully you have found this a straightforward example of how to​​ build realtime mobile apps with Pusher. There are many ways you can extend this tutorial for an improved application:

  • Use Pusher client events to send messages from one client to another. You could use our webhooks to notify your server when messages are​​ sent, allowing you to persist them in your database.

  • Use Pusher presence channels to create live user lists and show who’s online in realtime.

  • Use our REST API to determine whether a user is connected to Pusher. If they are, go ahead and send them a message as normal. If not, send them a native push notification leading them back to your app.

Even with such a basic app, hopefully I have shown you how easy and few lines of code it is to drop in Pusher to any Android app. Feel more than free to let us know what you end up building with Pusher and Android!