com.airbop.client.GCMIntentService.java Source code

Java tutorial

Introduction

Here is the source code for com.airbop.client.GCMIntentService.java

Source

/*
 * Copyright 2012 Indigo Rose Software Design Corporation
 * Copyright 2012 Google Inc.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *   http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package com.airbop.client;

import static com.airbop.client.CommonUtilities.GOOGLE_PROJECT_NUMBER;
import static com.airbop.client.CommonUtilities.displayMessage;

import android.support.v4.app.NotificationCompat.Builder;
import android.support.v4.app.NotificationCompat;
import android.app.Notification;
import android.app.NotificationManager;
import android.app.PendingIntent;
import android.content.Context;
import android.content.Intent;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.net.Uri;
import android.os.Bundle;
import android.util.Base64;
import android.util.Log;

//import com.airbop.gcm.demo.R;
import com.google.android.gcm.GCMBaseIntentService;
import com.google.android.gcm.GCMRegistrar;

/**
 * IntentService responsible for handling GCM messages.\
 * Docs: http://developer.android.com/guide/google/gcm/client-javadoc/com/google/android/gcm/GCMBaseIntentService.html
 */
public class GCMIntentService extends GCMBaseIntentService {

    //@SuppressWarnings("hiding")
    private static final String TAG = "GCMIntentService";

    public GCMIntentService(boolean withLocation) {
        super(GOOGLE_PROJECT_NUMBER);
    }

    public GCMIntentService() {
        super(GOOGLE_PROJECT_NUMBER);
    }

    /**
    * Called after the app has been registered on the GCM service
    * We now have the regID that we can use to register with the
    * AirBop servers.
    */
    @Override
    protected void onRegistered(Context context, String registrationId) {

        Log.i(TAG, "Device registered: regId = " + registrationId);
        displayMessage(context, getString(R.string.gcm_registered));
        //Get our data for the server
        AirBopServerUtilities server_data = AirBopServerUtilities.fillDefaults(registrationId);
        //server_data.loadCurrentLocation(context);
        server_data.loadDataFromPrefs(context);
        // Get rid of the location from the prefs so we requery next time
        AirBopServerUtilities.clearLocationPrefs(context);
        AirBopServerUtilities.register(getApplicationContext(), server_data);
    }

    /**
    * Called after the device has been unregisterd from the GCM server.
    * We we are registered on the AirBop servers we should unregister
    * from there as well.
    */
    @Override
    protected void onUnregistered(Context context, String registrationId) {

        Log.i(TAG, "Device unregistered");
        displayMessage(context, getString(R.string.gcm_unregistered));
        //If we are still registered with AirBop it is time to unregister
        if (GCMRegistrar.isRegisteredOnServer(context)) {
            AirBopServerUtilities.unregister(context, registrationId);
        } else {
            // This callback results from the call to unregister made on
            // ServerUtilities when the registration to the server failed.
            Log.i(TAG, "Ignoring unregister callback");

        }
    }

    /**
    * We have received a push notification from GCM, analyze
    * the intents bundle for the payload.
    */
    @Override
    protected void onMessage(Context context, Intent intent) {

        Log.i(TAG, "Received message");
        displayMessage(context, "Message Received");
        String message = null;
        String title = null;
        String url = null;
        String image_url = null;
        String large_icon = null;

        if (intent != null) {
            //Check the bundle for the pay load body and title
            Bundle bundle = intent.getExtras();
            if (bundle != null) {
                displayMessage(context, "Message bundle: " + bundle);

                Log.i(TAG, "Message bundle: " + bundle);
                message = bundle.getString("message");
                title = bundle.getString("title");
                url = bundle.getString("url");
                image_url = bundle.getString("image_url");
                large_icon = bundle.getString("large_icon");
            }
        }
        // If there was no body just use a standard message
        if (message == null) {
            message = getString(R.string.airbop_message);
        }

        if (image_url != null) {
            generateImageNotification(context, title, message, url, image_url, large_icon);
        } else {
            generateNotification(context, title, message, url, large_icon);
        }
    }

    @Override
    protected void onDeletedMessages(Context context, int total) {
        /*
         * Called when the GCM servers tells that app that 
         * pending messages have been deleted because the
         * device was idle.
         */
        Log.i(TAG, "Received deleted messages notification");
        String message = getString(R.string.gcm_deleted, total);
        displayMessage(context, message);
        // notifies user
        generateNotification(context, "", message);
    }

    /**
     * Called on registration or unregistration error. 
     * Whatever this error is, it is not recoverable
     */
    @Override
    public void onError(Context context, String errorId) {

        Log.i(TAG, "Received error: " + errorId);
        displayMessage(context, getString(R.string.gcm_error, errorId));
    }

    /**
     * Called on a registration error that could be retried.
    * By default, it does nothing and returns true, but could be
    * overridden to change that behavior and/or display the error. 
    */
    @Override
    protected boolean onRecoverableError(Context context, String errorId) {
        // log message
        Log.i(TAG, "Received recoverable error: " + errorId);
        displayMessage(context, getString(R.string.gcm_recoverable_error, errorId));
        return super.onRecoverableError(context, errorId);
    }

    /**
     * Decode a base64 string into a Bitmap
     */
    private static Bitmap decodeImage(String image_data) {
        // Decode the encoded string into largeIcon
        Bitmap largeIcon = null;
        if ((image_data != null) && (!image_data.equals(""))) {
            byte[] decodedImage = Base64.decode(image_data, Base64.DEFAULT);
            if (decodedImage != null) {
                largeIcon = BitmapFactory.decodeByteArray(decodedImage, 0, decodedImage.length);
            }
        }
        return largeIcon;
    }

    /**
     * Issues a notification to inform the user that server has sent a message.
     */
    private static void generateNotification(Context context, String title, String message) {
        int icon = R.drawable.ic_stat_gcm;
        long when = System.currentTimeMillis();
        NotificationManager notificationManager = (NotificationManager) context
                .getSystemService(Context.NOTIFICATION_SERVICE);

        if ((title == null) || (title.equals(""))) {
            title = context.getString(R.string.app_name);
        }
        Intent notificationIntent = new Intent(context, DemoActivity.class);
        // set intent so it does not start a new activity
        notificationIntent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP | Intent.FLAG_ACTIVITY_SINGLE_TOP);
        PendingIntent intent = PendingIntent.getActivity(context, 0, notificationIntent, 0);

        Notification notification = new NotificationCompat.Builder(context).setContentTitle(title)
                .setContentText(message).setContentIntent(intent).setSmallIcon(icon).setWhen(when)
                .setStyle(new NotificationCompat.BigTextStyle().bigText(message)).build();

        notification.flags |= Notification.FLAG_AUTO_CANCEL;
        notificationManager.notify(0, notification);
    }

    private static void generateNotification(Context context, String title, String message, String url,
            String large_icon) {

        int icon = R.drawable.ic_stat_gcm;
        long when = System.currentTimeMillis();
        NotificationManager notificationManager = (NotificationManager) context
                .getSystemService(Context.NOTIFICATION_SERVICE);

        if ((title == null) || (title.equals(""))) {
            title = context.getString(R.string.app_name);
        }

        Intent notificationIntent = null;
        if ((url == null) || (url.equals(""))) {
            //just bring up the app
            notificationIntent = new Intent(context, DemoActivity.class);
        } else {
            //Launch the URL
            notificationIntent = new Intent(Intent.ACTION_VIEW);
            notificationIntent.setData(Uri.parse(url));
            notificationIntent.addCategory(Intent.CATEGORY_BROWSABLE);
        }

        // set intent so it does not start a new activity
        notificationIntent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP | Intent.FLAG_ACTIVITY_SINGLE_TOP);
        PendingIntent intent = PendingIntent.getActivity(context, 0, notificationIntent, 0);

        Notification notification = new NotificationCompat.Builder(context).setContentTitle(title)
                .setContentText(message).setContentIntent(intent).setSmallIcon(icon)
                .setLargeIcon(decodeImage(large_icon)).setWhen(when)
                .setStyle(new NotificationCompat.BigTextStyle().bigText(message)).build();

        notification.flags |= Notification.FLAG_AUTO_CANCEL;
        notificationManager.notify(0, notification);
    }

    private static void generateImageNotification(Context context, String title, String message, String url,
            String image_url, String large_icon) {

        // The bitmap to download
        Bitmap message_bitmap = null;
        // Should we download the image?
        if ((image_url != null) && (!image_url.equals(""))) {
            message_bitmap = AirBopImageDownloader.downloadBitmap(image_url);
        }
        // If we didn't get the image, we're out of here
        if (message_bitmap == null) {
            generateNotification(context, title, message, url, large_icon);
            return;
        }

        int icon = R.drawable.ic_stat_gcm;
        long when = System.currentTimeMillis();
        NotificationManager notificationManager = (NotificationManager) context
                .getSystemService(Context.NOTIFICATION_SERVICE);

        if ((title == null) || (title.equals(""))) {
            title = context.getString(R.string.app_name);
        }

        Intent notificationIntent = null;
        if ((url == null) || (url.equals(""))) {
            //just bring up the app
            notificationIntent = new Intent(context, DemoActivity.class);
        } else {
            //Launch the URL
            notificationIntent = new Intent(Intent.ACTION_VIEW);
            notificationIntent.setData(Uri.parse(url));
            notificationIntent.addCategory(Intent.CATEGORY_BROWSABLE);
        }

        // set intent so it does not start a new activity
        notificationIntent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP | Intent.FLAG_ACTIVITY_SINGLE_TOP);
        PendingIntent intent = PendingIntent.getActivity(context, 0, notificationIntent, 0);

        Notification notification = new NotificationCompat.Builder(context).setContentTitle(title)
                .setContentText(message).setContentIntent(intent).setSmallIcon(icon)
                .setLargeIcon(decodeImage(large_icon)).setWhen(when)
                .setStyle(new NotificationCompat.BigPictureStyle().bigPicture(message_bitmap)).build();

        notification.flags |= Notification.FLAG_AUTO_CANCEL;
        notificationManager.notify(0, notification);
    }

}