Creating your First Android App (User-to-User chat)
This guide walks you through how to build a new Android Mobile app that will enable in-app user-to-user chat between platforms.
Create a new App
Open Magnet Studio.
Click the Create App button in the navigation bar.

Enter a name for your app. Click Save to create your new app.

Download magnetmax.properties
and place it in app/src/main/res/raw
. Create a "raw" directory if required.

Add the Magnet Message client library as a dependency to the build.gradle
scripts.
build.gradle
repositories {
maven {
url "https://repo.magnet.com/artifactory/public"
}
}
app/build.gradle
dependencies {
compile ("com.magnet.max.android:magnet-max-android-sdk:2.3.0@aar") {
transitive=true
}
}
It is common to initialize the Magnet Message SDK during the creation of the application.
MyApplication.java
public void onCreate() {
super.onCreate();
//First thing to do is init the Max API.
Max.init(this.getApplicationContext(),
new MaxAndroidPropertiesConfig(this, R.raw.magnetmax));
}
Register yourself as a Magnet Message User.
User.register(new UserRegistrationInfo.Builder()
.userName("jane.doe")
.firstName("Jane")
.password("magnet")
.build(), new ApiCallback<User>() {
public void success(User user) {
Log.d(TAG, "register user succeeded");
}
public void failure(ApiError apiError) {
Log.d(TAG, "register user failed because: " + apiError);
}
});
Log in with the user created in the previous step.
String username = "jane.doe";
String password = "magnet";
User.login(username, password, false, new ApiCallback<Boolean>() {
public void success(Boolean aBoolean) {
Log.d(TAG, "login(): success! boolean=" + aBoolean);
Max.initModule(MMX.getModule(), new ApiCallback<Boolean>() {
public void success(Boolean aBoolean) {
//If an EventListener has already been registered, start the MMX messaging service
//You MUST call start when you are ready to start sending and receiving messages.
//Login may not always be the best time to call it.
MMX.start();
}
public void failure(ApiError apiError) {
Toast.makeText(MyActivity.this, "Unable to initialize MMX: " + apiError, Toast.LENGTH_LONG).show();
}
});
}
public void failure(ApiError apiError) {
Log.d(TAG, "login(): failure! error=" + apiError);
//login failed, probably an incorrect password
}
});
Get current user after logging in with the code below.
//getCurrentUser() will return null if not currently logged in
User currentUser = User.getCurrentUser();
Get Users. To get a User by their username, use the code below.
List<String> usernames = ...;
User.getUsersByUserNames(usernames, new ApiCallback<List<User>>() {
public void success(List<User> users) {
...
}
public void failure(ApiError apiError) {
//failed to retrieve users
}
});
Find Users. For example, to find all users whose display-name starts with a J
, use the code below.
//specify pagination
int limit = 10;
int offset = 0;
...
User.search("userName:j*", limit, offset, null, new ApiCallback<List<User>>() {
public void success(List<User> users) {
...
}
public void failure(ApiError apiError) {
Log.e(TAG, "User search failed: " + apiError, apiError.getCause());
}
});
Create a chat channel with recipients. NOTE: In most cases the chat channel should be private. Only channel owners can invite people into the chat.
MMXChannel myChatChannel = null;
MMXChannel.create(name, summary, false, MMXChannel.PublishPermission.SUBSCRIBER, users,
new MMXChannel.OnFinishedListener<MMXChannel>() {
public void onSuccess(MMXChannel result) {
myChatChannel = result;
}
public void onFailure(MMXChannel.FailureCode code, Throwable ex) {
}
});
Send the message.
HashMap<String, String> content = new HashMap<String, String>();
content.put("foo", "bar");
// Build the message
MMXMessage message = new MMXMessage.Builder()
.content(content)
.build();
myChatChannel.publish(message, MMXChannel.OnFinishedListener<String>() {
public void onSuccess(String s) {
// do something
}
public void onFailure(MMXMessage.FailureCode failureCode, Throwable e) {
// do something
}
});
Add a listener to receive the message and chat invitation. </a>
MMX.EventListener eventListener =
new MMX.EventListener() {
public boolean onMessageReceived(MMXMessage message) {
Log.d(TAG, "onMessageReceived(): " + message.getId());
for (Map.Entry<String,String> entry : message.getContent().entrySet()) {
//receivedContent.put(entry.getKey(), entry.getValue());
}
return false;
}
@Override
public boolean onInviteReceived(MMXChannel.MMXInvite invite) {
String comment = invite.getInviteInfo().getComment();
//display something for the user to accept or decline
...
}
};
MMX.registerListener(eventListener);
//be sure to make the corresponding call to MMX.unregisterListener(eventListener) to prevent leaking the listener
Invite more users into the chat using the same invitation process used in the Private Discussion Group.
Get the chat history.
int limit = 10;
int offset = 0;
Date now = new Date();
Date anHourAgo = new Date(now.getTime() - (60 * 60 * 1000l));
boolean ascending = false;
myChatChannel.getMessages(anHourAgo, now, limit, offset, ascending, new MMXChannel.OnFinishedListener<ListResult<MMXMessage>>(){
@Override
public void onSuccess(ListResult<MMXMessage> messages) {
}
@Override
public void onFailure(MMXChannel.FailureCode failureCode, Throwable throwable) {
}
});
Get all chat recipients.
MMXChannel myChatChannel = ...;
myChatChannel.getAllSubscribers(limit, offset, new MMXChannel.OnFinishedListener<ListResult<User>>() {
@Override
public void onSuccess(ListResult<User> userListResult) {
//Success
}
@Override
public void onFailure(MMXChannel.FailureCode failureCode, Throwable throwable) {
//Failure
}
});
Advanced: Wakeup Users
We provide the capability to add a mechanism that notifies the app there is a pending incoming message to registered users who are not currently online. This capability leverages the platform's push technology—in the case of Android: GCM.
NOTE: Configuring GCM for your application is a prerequisite. Please see our detailed documentation on how to setup GCM for your application.
Add the GCM Sender ID (Project ID) to the app.
app/src/main/res/raw/magnetmax.properties
...
mmx-gcmSenderId=Your GCM Sender ID
Declare dependencies. As of version 1.10.+, the Magnet Message SDK for Android no longer declares the Google Play dependencies. It is up to the application developer to add these dependencies to the app/build.gradle
file.
NOTE: If you are using a version prior to 1.10.+, you do NOT need to declare the dependencies separately; doing so may cause dex errors during compilation if the versions do not match against the versions specified by the SDK (7.8.0).
app/build.gradle
dependencies {
...
compile 'com.google.android.gms:play-services-base:8.1.0'
compile 'com.google.android.gms:play-services-gcm:8.1.0'
}
Update the AndroidManifest.xml. Google Cloud Messaging has very specific requirements for AndroidManifest.xml. Your app needs to:
- Declare a new permission.
<permission>
- "Use" that permission.
<uses-permission>
- Protect GCM BroadcastReceiver with this permission.
Set the appropriate Intent filter for these messages.
app/src/main/AndroidManifest.xml
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android" package="com.magnet.demo.mmx.starter" >
<permission android:name="com.magnet.demo.mmx.starter.permission.C2D_MESSAGE" android:protectionLevel="signature" />
...
<uses-permission android:name="com.magnet.demo.mmx.starter.permission.C2D_MESSAGE" />
...
<receiver android:name="com.magnet.mmx.client.MMXGcmBroadcastReceiver" android:permission="com.google.android.c2dm.permission.SEND" >
<intent-filter>
<action android:name="com.google.android.c2dm.intent.RECEIVE" />
<category android:name="com.magnet.demo.mmx.starter" />
</intent-filter>
</receiver>
...
</manifest>
Implement and declare a BroadcastReceiver to handle the wakeup or push message. It is up to you to decide how you should handle the wakeup and push message. A common implementation of the receiver is to show a notification and launch an activity:
import java.util.Map;
import com.magnet.mmx.client.api.MMXPushEvent;
import com.magnet.mmx.protocol.PubSubNotification;
import android.app.Notification;
import android.app.NotificationManager;
import android.app.PendingIntent;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
public class MyBroadcastReceiver extends BroadcastReceiver {
...
public void onReceive(Context context, Intent intent) {
MMXPushEvent event = MMXPushEvent.fromIntent(intent);
if (event == null) {
// Received a non-MMX GCM; developer should handle the intent directly
} else if ("retrieve".equals(event.getType())) {
// A wake-up event for a new ad-hoc message; it has no payload.
// After the login and start MMX. the message will automatically arrive.
showNotification(context, "New message is available", null);
} else if (PubSubNotification.getType().equals(event.getType())) {
// A wake-up event for a channel; get its payload as an object.
// After the login and start MMX, fetch messages from the channel manually.
PubSubNotification pubsub = event.getCustomObject(PubSubNotification.class);
showNotification(context, pubsub.getText(), pubsub.getChannel().toString());
} else {
// Push message from another client; get the custom payload as a Map
Map<String, Object> payload = event.getCustomMap();
...
}
}
// Show a notification in status bar and start the Activity with action=MAIN,
// category=DEFAULT if tapped. The activity should perform the login and
// initialize the MMX module.
private void showNotification(Context context, String title, String text) {
PendingIntent pIntent = PendingIntent.getActivity(context, 0,
new Intent(Intent.ACTION_MAIN)
.addCategory(Intent.CATEGORY_DEFAULT)
.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK)
.setPackage(context.getPackageName()),
PendingIntent.FLAG_UPDATE_CURRENT);
Notification note = new Notification.Builder(context)
.setAutoCancel(true)
.setSmallIcon(context.getApplicationInfo().icon)
.setContentTitle(title)
.setContentText(text)
.setContentIntent(pIntent)
.build();
NotificationManager noteMgr = (NotificationManager)
context.getSystemService(Context.NOTIFICATION_SERVICE);
noteMgr.notify(9999, note);
}
}
...
Then, declare it in the AndroidManifest.xml file:
<application ...>
...
<receiver android:name=".MyBroadcastReceiver" android:exported="false">
<intent-filter>
<action android:name="MY_WAKEUP_ACTION" />
</intent-filter>
</receiver>
...
</application>
- Register your implementation with MMX.
// register a wakeup listener for GCM
MMX.registerWakeupBroadcast(context, new Intent("MY_WAKEUP_ACTION"));
Next Steps
See how to send Rich Messages in your app.