Documentation : Push notifications - Android

This example shows how to send push notifications to all users or just to one specified user.

Push notifications on Android devices are provided Google Cloud Messaging (GCM). Basic knowledge of it's mechanisms are necessary to complete this tutorial. 

Main screen of an application contains three buttons, one for sending push notifications to all users and two for sending push notification to specified users. When application recieve notifications, toast message will be shown. There are two users in the system and there's a possibility to switch user on application life time.

Obtain an API Key and Sender ID

Before we start designing our application in App Designer we have to configure new one in Google API's Consle. Follow first three paragraphs of this instruction to get your own API Key and Sender ID. They are necessarily to configure push notifications in App Designer.

Design Your App

Open Mobeelizer App Designer and reate application called PushNotifications.

Because there are no models in application we can move to push notification section. There we enable push notifications. Now edit push notifications for Android devices in test environment. Next we have to type API key in displayed dialog.

When everything is done in Create mode, deploy our application to test environment, and create two users with passwords:

  • a - usera
  • b - userb

Last thing to do in App Designer is download configured template. It really important to set Package name starting with lowercase letter and remember to set yours target SDK.

Use the Mobeelizer SDK

Extract downloaded zip file then open eclipse and import project.

Add resource files

Before we start  implementing our example we will add some resource files into the project:

Prepare main screen

We will start with creating main screen controls. As you can read before main screen contains 3 buttons to send notifications and one to switch between users , let's create them.

main.xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="fill_parent"
    android:layout_height="fill_parent"
    android:orientation="vertical" >
    <RelativeLayout
        android:layout_width="match_parent"
        android:layout_height="wrap_content">
        <TextView
            android:layout_marginTop="20dip"
            android:layout_marginLeft="50dip"
            android:textSize="25dip"
            android:id="@+id/currentUser"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:layout_alignParentTop="true"
            android:bufferType="spannable"
            android:text="Push notifications" />
                 
        <ImageButton
            android:layout_height="50dip"
            android:layout_width="50dip"
            android:layout_marginLeft="260dip"
            android:layout_marginTop="10dip"
            android:id="@+id/userSwitch"
            android:layout_alignParentLeft="true"/>
    </RelativeLayout>
    <View
        android:id="@+id/titleBarSeparator"
        android:layout_width="fill_parent"
        android:layout_height="2dip"
        android:layout_alignParentLeft="true"
        android:background="#FFB4B4B4" />
    <ScrollView
        android:layout_margin="10dip"
        android:layout_width="match_parent"
        android:layout_height="0dp"
        android:layout_weight="1" >
        <LinearLayout
            android:layout_width="fill_parent"
            android:layout_height="wrap_content" 
            android:orientation="vertical" >
            <TextView
                android:id="@+id/TextView01"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:text="Send to everyone" />
		    <Button
		        android:layout_marginLeft="10dip"
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
		        android:id="@+id/pushNotificationsSendToAllButton"
		        android:onClick="performSendToAll"
		        android:text="Send push notification" />
		    <TextView
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
		        android:id="@+id/textView1"
		        android:text="Send to users" />
		    <Button
		        android:layout_marginLeft="10dip"
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
		        android:id="@+id/pushNotificationsSendToAButton"
		        android:onClick="performSendToA"
		        android:text="Send to A" />
		    <Button
		        android:layout_marginLeft="10dip"
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
		        android:id="@+id/pushNotificationsSendToBButton"
		        android:layout_marginTop="10dp"
		        android:onClick="performSendToB"
		        android:text="Send to B" />
    	</LinearLayout>
    </ScrollView>
</LinearLayout>

To keep clean in our code we will create an interface to define operations supported by our main screen. First of all there shoud be posibility to disable and enable all buttons, and to get or set currenty logged in user.

MainScreen.java
public interface MainScreen {
	
	    void disableButtons();
	     
	    void enableButtons();
	     
	    String getCurrentUser();
	     
	    void setCurrentUser(String user);
}

When interface is ready let's implement it on PushNotificationsActivity. In constructor we will get all created controls in layout definition and store it in class private fields. 

PushNotificationsActivity.java
 public class PushNotificationsActivity extends Activity implements MainScreen {
		
	private Button mSendToAllButton;
	
	private Button mSendToAButton;
	
	private Button mSendToBButton;
	
	private ImageButton mSwitchUserButton;
    
    private String currenUser;
	
    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.main);
        mSendToAllButton = (Button)findViewById(R.id.pushNotificationsSendToAllButton);
        mSendToAButton = (Button)findViewById(R.id.pushNotificationsSendToAButton);
        mSendToBButton = (Button)findViewById(R.id.pushNotificationsSendToBButton);
        mSwitchUserButton = (ImageButton)findViewById(R.id.userSwitch);
        
       // TODO: create onClick listeners 
    }

	public void disableButtons() {
		boolean enabled = false; 
		mSendToAllButton.setEnabled(enabled);
		mSendToAButton.setEnabled(enabled);
		mSendToBButton.setEnabled(enabled);
		mSwitchUserButton.setEnabled(enabled);
	}
	public void setCurrentUser(String user) {
		currenUser = user;
        if(user != null){
        	if(currenUser.equals("a")){
        		mSwitchUserButton.setImageResource(R.drawable.bt_user_a_big);
        	}
        	else if(currenUser.equals("b")){
        		mSwitchUserButton.setImageResource(R.drawable.bt_user_b_big);
        	}
        }
	}
	public void enableButtons() {
		boolean enabled = true; 
		mSendToAllButton.setEnabled(enabled);
		mSendToAButton.setEnabled(enabled);
		mSendToBButton.setEnabled(enabled);
		mSwitchUserButton.setEnabled(enabled);
	}
	public String getCurrentUser() {
        return currenUser;
	}
}

Switch beetwen users

Let's create some business logic, we will start with switching user operation. We will create separated class for that called "SwichUserOperations", this class will implement OnClickListener interface, so object of this class can be set as onClickListener in 'Switch' button. This class will also implement MobeelizerOperationCallback interface and we will use it as a login method callback. 

SwitchUserOperations.java
public class SwitchUserOperations implements OnClickListener , MobeelizerOperationCallback{
    
   private static final String USER_A_LOGIN = "a";
    
   private static final String USER_B_LOGIN = "b";
    
   private static final String USER_A_PASS = "usera";
    
   private static final String USER_B_PASS = "userb";
   private String userToLoggIn;
   private String password;
    
   private MainScreen page;
    
   public SwitchUserOperations(MainScreen page){
       this.page= page;
   }
    
   public void onClick(View v) {
       page.disableButtons();
       if(page.getCurrentUser() == USER_A_LOGIN){
           userToLoggIn = USER_B_LOGIN;
           password = USER_B_PASS;
       }
       else {
           userToLoggIn = USER_A_LOGIN;
           password = USER_A_PASS; 
       }
       Mobeelizer.login(userToLoggIn, password, this);
   }
   public void onFailure(MobeelizerOperationError arg0) {
       page.setCurrentUser(null);
       page.enableButtons();
   }
   public void onSuccess() {
       page.setCurrentUser(userToLoggIn);
       page.enableButtons();
   }
}

It is easy, right? When user click on switch button, we will check which user was logged in recently and then we will login other one. We have to also disable all buttons before login. When login will finish with success we will set current user value into MainScreen and then enable all buttons. 

Now, set object of just created class to button as a onclick listener.

PushNotificationsActivity.java
	@Override
    public void onCreate(Bundle savedInstanceState) {
        ...
        SwitchUserOperations switchOperations = new SwitchUserOperations(this);
        mSwitchUserButton.setOnClickListener(switchOperations);
        switchOperations.onClick(null);
		...
    }

There is one thing more to implement here, we also want to retrieve last logged in user after reopening application. To do it we will create new method called retrieveLastSession in PushNotificationsActivity.

PushNotificationsActivity.java
    private static String LAST_LOGGED_IN_USER = "last_logged_in_user";
 
    public void onCreate(Bundle savedInstanceState) {
        ...
        retrieveLastSession(operation);
    }
	private void retrieveLastSession(SwitchUserOperations operation) {
		SharedPreferences settings = getSharedPreferences("SETTINGS", 0);
		String lastLoggedIn = settings.getString(LAST_LOGGED_IN_USER, "");
		if(lastLoggedIn.equals("a")){
			currenUser = "b";
		}
		else if(lastLoggedIn.equals("b")){
			currenUser = "a";
		}
        operation.onClick(null);
	}

In this method we are getting saved user from shared preferences, set current user to other one and then start switching user operation.

Last thing to do is to save current user into shared preferences when logging in finishes with success.

PushNotificationsActivity.java
    public void setCurrentUser(String user) {
		SharedPreferences settings = getSharedPreferences("SETTINGS", 0);
		settings.edit().putString(LAST_LOGGED_IN_USER, user).commit();
        ...
	} 

Send push notifications

Ok we can switch between users now and it is time to send push notifications. To do it we will create SendPushOperation class implementing OnClickListener interface. We are sending push notifications in different thread because send methods are sync and can block UI thread in case of failure.

SendPushOperation
public class SendPushOperation implements OnClickListener {
	
	public enum Destination{
		ALL,
		A,
		B
	}
	
	private Destination mDestination;
	
	public SendPushOperation(Destination destination){
		mDestination = destination;
	}
	public void onClick(View v) {
		Thread sendThread = new Thread(){
			@Override
			public void run(){
				List<String> users = new ArrayList<String>();
		        switch(mDestination){
					case A:
						users.add("a");
						Mobeelizer.sendRemoteNotificationToUsers(createMssage("Android device greets user A!"), users);
						break;
					case ALL:
						Mobeelizer.sendRemoteNotification(createMssage("Android device greets all users!"));
						break;
					case B:
						users.add("b");
						Mobeelizer.sendRemoteNotificationToUsers(createMssage("Android device greets user B!"), users);
						break;
					default:
						break;
		        }
			}
		};
		sendThread.start();
	}
	
	private Map<String, String> createMssage(String content){
        Map<String, String> message = new HashMap<String, String>();
        message.put("alert", content);
        message.put("X-NotificationClass", "2"); // microsoft notification priority
        message.put("X-WindowsPhone-Target", "toast"); // notification type
        message.put("Text1", "Push received!");
        message.put("Text2", content);
        message.put("Param", "/View/MainPage.xaml"); // wp7 toast page
        return message;
	}
}

Constructor of our operation class gets information if notification need to be send to all users or to specified user. In onClick method we are sending notification with specified destination using Mobeelizer methods. 

It is time now to create this operations in PushNotificationsActivity onCreateMethod.

PushNotificationsActivity.java
...
    public void onCreate(Bundle savedInstanceState) {
        ...
        mSendToAllButton.setOnClickListener(new SendPushOperation(Destination.ALL));
        mSendToAButton.setOnClickListener(new SendPushOperation(Destination.A));
        mSendToBButton.setOnClickListener(new SendPushOperation(Destination.B));
    }
...

Register for receiving notifications

We can send push notifications to all users or just to one specified user, to complite this example we have to register for receiving them. Actually everyting what we have to do is described in this document

First we have to add gcm.jar file into libs directory and then add this library into project build path. When we do it we have to open application manifest file and make some changes there. 

  1. Declare and use a custom permission so only this application can receive GCM messages:

    AndroidManifest.xml
    	<permission android:name="com.test.PushNotifications.permission.C2D_MESSAGE" android:protectionLevel="signature" />
    	<uses-permission android:name="com.test.PushNotifications.permissions.C2D_MESSAGE" />
  2. Add the following permissions:

    AndroidManifest.xml
    <!-- App receives GCM messages. -->
    <uses-permission android:name="com.google.android.c2dm.permission.RECEIVE" />
    <!-- GCM connects to Google Services. -->
    <uses-permission android:name="android.permission.INTERNET" /> 
    <!-- GCM requires a Google account. -->
    <uses-permission android:name="android.permission.GET_ACCOUNTS" />
    <!-- Keeps the processor from sleeping when a message is received. -->
    <uses-permission android:name="android.permission.WAKE_LOCK" />


  3. Add the following broadcast receiver into application node:

    AndroidManifest.xml
    		<receiver android:name="com.google.android.gcm.GCMBroadcastReceiver" android:permission="com.google.android.c2dm.permission.SEND" >
    		  <intent-filter>
    		    <action android:name="com.google.android.c2dm.intent.RECEIVE" />
    		    <action android:name="com.google.android.c2dm.intent.REGISTRATION" />
    		    <category android:name="com.test.PushNotifications" />
    		  </intent-filter>
    		</receiver>


  4. Add the following intent service into application node:
     

    AndroidManifest.xml
    <service android:name="com.test.PushNotifications.GCMIntentService" />

    "com.test.PushNotifications" - is Package name that we sets in AppDesinger before downloading configurated template, if you set different name use your own. 

When everything in manifest file is done we have to create GCMIntentService class in main package. Implement it as follows.

GCMIntentService.java
 public class GCMIntentService extends GCMBaseIntentService{
	
    private static int i = 0;
    
	@Override
	protected void onError(Context arg0, String arg1) {
		// TODO Auto-generated method stub
		
	}
	@Override
	protected void onMessage(Context context, Intent intent) {
		String message = intent.getStringExtra("alert");
        String title = "Push received!";
        Notification notification = new Notification(R.drawable.ic_launcher, message, System.currentTimeMillis());
        notification.setLatestEventInfo(context, title, message, null);
        notification.flags |= Notification.FLAG_AUTO_CANCEL;
        NotificationManager notificationManager = (NotificationManager) context
                .getSystemService(Context.NOTIFICATION_SERVICE);
        notificationManager.notify(i++, notification);
	}
	@Override
	protected void onRegistered(Context arg0, String regId) {
        Mobeelizer.registerForRemoteNotifications(regId);
	}
	@Override
	protected void onUnregistered(Context arg0, String arg1) {
        Mobeelizer.unregisterForRemoteNotifications();
	}
}

Last thing to do is to write this code in PushNotificationsActivity onCreate method. 

PushNotificationsActivity.java
...
        GCMRegistrar.checkManifest(this);
        final String regId = GCMRegistrar.getRegistrationId(this);
        if (regId.equals("")) {
            GCMRegistrar.register(this, "Sender ID"); // you get this id on the beging of this tutorial in 'Obtain an API Key and Sender ID' paragraph
        } else {
            Mobeelizer.registerForRemoteNotifications(regId);
        }
...

Conclusion

Great, push notification example is done, we can send push notifications to all users in the system or to specified users. We can also send push notifications between other devices, implement same example on Android or iOS platform and check it by your self.