Amazon SNS Push Notification Tutorial on Android using GCM

Do you have a project where an Android device needs to receive push notifications from an endpoint registered on Amazon Simple Notification Service (SNS)? Amazon has a sample Android app, but, unfortunately the only thing this sample app does is register with Google Cloud Messaging (GCM). You can find the sample app here, SNSMobilePush.zip.

There are a lot more steps involved to enable your device to receive push notifications from an Amazon endpoint. Let’s get started.

First, we need to register the device to GCM. For that, we call a task that will handle the registration in the onCreate event of our first activity:

public class MyActivity extends Activity{

    ….

    @Override

    protected void onCreate(Bundle savedInstanceState) {

        super.onCreate(savedInstanceState);

        

        //let's register this app to the gcm if it hasn't been registered already.

        SharedPreferences sp = PreferenceManager.getDefaultSharedPreferences(this);

        String gcmToken = sp.getString(getString(R.string.gcm_pref_token), null);

        GoogleCloudMessaging gcm = GoogleCloudMessaging.getInstance(getApplicationContext());

        if(TextUtils.isEmpty(gcmToken)){

            new GCMRegisterTask(this, gcm).execute();

        }

    }

}

Now we need the Task that is going to actually register our App to the GCM. The string R.string.gcm_project_number is the Project number given to you by the google console when you register your project:

public class GCMRegisterTask extends AsyncTask<String, Void, Boolean> {

    private Context context;

    private GoogleCloudMessaging gcm;

    public GCMRegisterTask(Context context, GoogleCloudMessaging gcm){

        super();

        this.context = context;

        this.gcm = gcm;

    }

    @Override

    protected Boolean doInBackground(String... params) {

        String token;

        try {

            token = gcm.register(context.getString(R.string.gcm_project_number));

            SharedPreferences sp = PreferenceManager.getDefaultSharedPreferences(context);

            sp.edit().putString(context.getString(R.string.gcm_pref_token), token).apply();

            return true;

        }

        catch (IOException e) {

            Log.i("Registration Error", e.getMessage());

        }

        return false;

    }

}

Keep the token received from the GCM on your preferences. You’re going to need it when creating the endpoint on the Amazon SNS.

Now the device has been registered and is able to receive push notifications thru GCM, but we still need to map our GCM account to a SNS endpoint. The GCM is unique for the device. The SNS, however, is where you’ll filter your push notifications by using the customData property. So, if you’re registering for your users, you’ll probably want to register it on login and unregister it on logout.

To create an endpoint on the login, we can use a task:

public class AWSCreateEndpointTask extends AsyncTask<String, Void,  CreatePlatformEndpointResult> {

    Context context;

    public AWSCreateEndpointTask(Context context ){

        super();

        this.context = context;

    }

    @Override

    protected CreatePlatformEndpointResult doInBackground( String[] params ) {

        if(params.length < 3){

            return null;

        }

        String arn = params[0];

        String gcmToken = params[1];

        String userData = params[2];

        try {

            CreatePlatformEndpointRequest request = new CreatePlatformEndpointRequest();

            request.setCustomUserData(userData);

            request.setToken(gcmToken);

            request.setPlatformApplicationArn(arn);

            return AWSManager.getSNSClient().createPlatformEndpoint(request);

        }catch(Exception ex){

            return null;

        }

    }

    @Override

    protected void onPostExecute(CreatePlatformEndpointResult result) {

        if(result != null) {

        SharedPreferences prefs = context.getSharedPreferences( “my_prefs” , Context.MODE_PRIVATE );

            String endpointArn = result.getEndpointArn();

            prefs.edit().putString( context.getString(R.string.endpoint_arn), endpointArn ).apply();

        }

    }

}

This task received 3 parameters to run. Arn is the code you receive for the GCM endpoint when creating your GCM integration on Amazon. GCMToken is the token we got before and stored on the preferences. And userData is the data we will use to filter the push notifications on our backend.

So, to run this task, we can do something like:

String token = PreferenceManager.getDefaultSharedPreferences(this).getString( 

this.getString(R.string.gcm_pref_token), null );

        if(!TextUtils.isEmpty(token)) {

            new AWSCreateEndpointTask(this).execute(

                    “arn:aws:sns:region:XXXXXXXXXXXX:app/GCM/AppName”

                    token,

                    email);

        }

After registering the endpoint on SNS, you need to keep the arn so you can, later, unregister it. It’s easy to remove an endpoint once you have the arn from the endpoint:

public class AWSRemoveEndpointTask extends AsyncTask<String, Void, Boolean> {

    Context context;

    public AWSRemoveEndpointTask(Context context ){

        super();

        this.context = context;

    }

    @Override

    protected Boolean doInBackground( String[] params ) {

        if(params.length < 1){

            return false;

        }

        String arn = params[0];

        if(TextUtils.isEmpty(arn)){

            return false;

        }

        try {

            DeleteEndpointRequest request = new DeleteEndpointRequest();

            request.setEndpointArn(arn);

            AWSManager.getSNSClient().deleteEndpoint(request);

            return true;

        }catch(Exception ex){

            return false;

        }

    }

}

And now use the unregister task on your logout process.

You’re now ready to create your broadcast receivers, and your Android app will be ready to start receiving push notifications sent by AWS SNS.

Cheers!