Create an Android™ client application within minutes
that connects to the Diffusion™ server. This example creates a client that
prints the value of a topic to the console when the topic is updated.
To complete this example, you need Android Studio installed on
your development system and a Diffusion server.
You also require that anonymous client connections are assigned a role with the
select_topic and read_topic permissions. For example, the
"CLIENT" role. For more information about roles and permissions, see Role-based authorization.
This example steps through the lines of code required to subscribe to a topic. The
full code example is provided after the steps.
-
Set up a project in Android Studio that uses the Diffusion
Unified API.
-
Create a new project using API Level 21 or later.
-
Copy the
diffusion-android-x.x.x.jar
into the libs folder of your project.
-
Open the Dependency window in the project's module
settings and add
diffusion-android-x.x.x.jar
as a file dependency.
-
In your project's AndroidManifest.xml file set the
INTERNET permission.
<uses-permission android:name="android.permission.INTERNET"/>
This permission is required to use the
Diffusion
API.
-
Open your project's MainActivity.java file.
This file is where you develop the code to interact with
the Diffusion server.
The empty
MainActivity.java file contains the following
boilerplate
code:
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.view.Menu;
import android.view.MenuItem;
public class MainActivity extends AppCompatActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
}
@Override
public boolean onCreateOptionsMenu(Menu menu) {
// Inflate the menu; this adds items to the action bar if it is present.
getMenuInflater().inflate(R.menu.menu_main, menu);
return true;
}
@Override
public boolean onOptionsItemSelected(MenuItem item) {
// Handle action bar item clicks here. The action bar will
// automatically handle clicks on the Home/Up button, so long
// as you specify a parent activity in AndroidManifest.xml.
int id = item.getItemId();
//noinspection SimplifiableIfStatement
if (id == R.id.action_settings) {
return true;
}
return super.onOptionsItemSelected(item);
}
}
-
Import the following packages and classes:
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.util.Log;
import android.view.Menu;
import android.view.MenuItem;
import com.pushtechnology.diffusion.client.Diffusion;
import com.pushtechnology.diffusion.client.callbacks.ErrorReason;
import com.pushtechnology.diffusion.client.content.Content;
import com.pushtechnology.diffusion.client.features.Topics;
import com.pushtechnology.diffusion.client.features.Topics.TopicStream;
import com.pushtechnology.diffusion.client.session.Session;
import com.pushtechnology.diffusion.client.session.SessionFactory;
import com.pushtechnology.diffusion.client.types.UpdateContext;
public class MainActivity extends AppCompatActivity {
}
-
Create a TopicStreamLogcat static inner class that extends
TopicStream.Default.
Inside the inner class, override the onTopicUpdate to
print any topic updates received by your Android client to the log console.
private static class TopicStreamLogcat extends TopicStream.Default {
@Override
public void onTopicUpdate(String topic, Content content,
UpdateContext context) {
Log.i("Topic Stream", topic + ": " + content.asString());
}
}
-
Create a SessionHandler inner class that implements
SessionFactory.OpenCallback.
This inner class will contain the code that interacts with
the Diffusion server.
private class SessionHandler implements SessionFactory.OpenCallback {
private Session session = null;
@Override
public void onOpened(Session session) {
}
@Override
public void onError(ErrorReason errorReason) {
}
public void close() {
if ( session != null ) {
session.close();
}
}
}
-
In the onOpened method, create the code required to
subscribe to the foo/counter
topic.
-
Get the Topics feature.
// Get the Topics feature to subscribe to topics
final Topics topics = session.feature( Topics.class );
-
Add an instance of TopicStreamLogcat as the topic
stream for the foo/counter
topic.
// Add a new topic stream for 'foo/counter'
topics.addTopicStream(">foo/counter", new TopicStreamLogcat());
-
Subscribe to the foo/counter
topic.
// Subscribe to the topic 'foo/counter'
topics.subscribe("foo/counter", new Topics.CompletionCallback.Default());
-
In the MainActivity class, declare an instance of session
handler.
private SessionHandler sessionHandler = null;
-
Override the onCreate method of the
MainActivity class to open the session with the Diffusion server.
Note: Ensure that you use the asynchronous open() method
with a callback. Using the synchronous open() method
might open a connection on the same thread as the UI and cause a runtime
exception. However, the synchronous open() method can be
used in any thread that is not the UI thread.
if ( sessionHandler == null ) {
sessionHandler = new SessionHandler();
// Connect anonymously
// Replace 'host' with your hostname
Diffusion.sessions().open("ws://host:port", sessionHandler );
}
You can connect securely, using
Secure Sockets Layer (SSL):
Diffusion.sessions().open("wss://host:port", sessionHandler);
Or you can connect with a principal and credentials if that principal is
assigned a role with the
select_topic and
read_topic permissions:
Diffusion.sessions().principal("principal").password("password").open("wss://host:port", sessionHandler);
Replace the host, port, principal, and
password values with your own information.
-
Override the onDestroy method of the
MainActivity class to close the session with the Diffusion server.
if ( sessionHandler != null ) {
sessionHandler.close();
sessionHandler = null;
}
super.onDestroy();
-
Compile and run your client.
The client outputs the value to the log console every time the value of the
foo/counter topic is updated. You can
update the value of the foo/counter topic
by creating a publishing client to update the
topic. To create and publish to the foo/counter topic, you require a user with the modify_topic and update_topic permissions. For more
information, see Start publishing with Android.
Full example
The completed
MainActivity class contains the following
code:
package com.pushtechnology.demo.subscribe;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.util.Log;
import android.view.Menu;
import android.view.MenuItem;
import com.pushtechnology.diffusion.client.Diffusion;
import com.pushtechnology.diffusion.client.callbacks.ErrorReason;
import com.pushtechnology.diffusion.client.content.Content;
import com.pushtechnology.diffusion.client.features.Topics;
import com.pushtechnology.diffusion.client.features.Topics.TopicStream;
import com.pushtechnology.diffusion.client.session.Session;
import com.pushtechnology.diffusion.client.session.SessionFactory;
import com.pushtechnology.diffusion.client.types.UpdateContext;
public class MainActivity extends AppCompatActivity {
/**
* A topic stream that prints updates to logcat.
*/
private static class TopicStreamLogcat extends TopicStream.Default {
@Override
public void onTopicUpdate(String topic, Content content,
UpdateContext context) {
Log.i("Topic Stream", topic + ": " + content.asString());
}
}
/**
* A session handler that maintains the diffusion session.
*/
private class SessionHandler implements SessionFactory.OpenCallback {
private Session session = null;
@Override
public void onOpened(Session session) {
this.session = session;
// Get the Topics feature to subscribe to topics
final Topics topics = session.feature( Topics.class );
// Add a new topic stream for 'foo/counter'
topics.addTopicStream(">foo/counter", new TopicStreamLogcat());
// Subscribe to the topic 'foo/counter'
topics.subscribe("foo/counter",
new Topics.CompletionCallback.Default());
}
@Override
public void onError(ErrorReason errorReason) {
Log.e( "Diffusion", "Failed to open session because: " + errorReason.toString() );
session = null;
}
public void close() {
if ( session != null ) {
session.close();
}
}
}
private SessionHandler sessionHandler = null;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
if ( sessionHandler == null ) {
sessionHandler = new SessionHandler();
// Connect anonymously
// Replace 'host' with your hostname
Diffusion.sessions().open("ws://host:port", sessionHandler );
}
}
@Override
protected void onDestroy() {
if ( sessionHandler != null ) {
sessionHandler.close();
sessionHandler = null;
}
super.onDestroy();
}
@Override
public boolean onCreateOptionsMenu(Menu menu) {
// Inflate the menu; this adds items to the action bar if it is present.
getMenuInflater().inflate(R.menu.menu_main, menu);
return true;
}
@Override
public boolean onOptionsItemSelected(MenuItem item) {
// Handle action bar item clicks here. The action bar will
// automatically handle clicks on the Home/Up button, so long
// as you specify a parent activity in AndroidManifest.xml.
int id = item.getItemId();
//noinspection SimplifiableIfStatement
if (id == R.id.action_settings) {
return true;
}
return super.onOptionsItemSelected(item);
}
}