Thursday, 24 November 2011

FATAL EXCEPTION: IntentService due to NullPointerException on PendingIntent.getActivity()

When sending a message to your Android device you use the default GWT template provided:

C2DM web service

You must have used a registered email address (see previous post) otherwise you'll get a Failure. If all is fine you'll get a Success: message sent message.
However, just because all things are rosy this side, doesn't mean that your phone has picked up the message:

11-24 17:37:35.586: E/AndroidRuntime(1339): FATAL EXCEPTION: IntentService[role@yrdomain.com]
11-24 17:37:35.586: E/AndroidRuntime(1339): java.lang.NullPointerException
11-24 17:37:35.586: E/AndroidRuntime(1339):   
at android.app.PendingIntent.getActivity(PendingIntent.java:195)
11-24 17:37:35.586: E/AndroidRuntime(1339):   
at com.example.yourname.Util.generateNotification(Util.java:120)
11-24 17:37:35.586: E/AndroidRuntime(1339):   
at com.example.yourname.MessageDisplay.displayMessage(MessageDisplay.java:44)
11-24 17:37:35.586: E/AndroidRuntime(1339):   
at com.example.yourname.C2DMReceiver.onMessage(C2DMReceiver.java:82)
11-24 17:37:35.586: E/AndroidRuntime(1339):   
at com.google.android.c2dm.C2DMBaseReceiver.onHandleIntent(C2DMBaseReceiver.java:112)
11-24 17:37:35.586: E/AndroidRuntime(1339):   
at android.app.IntentService$ServiceHandler.handleMessage(IntentService.java:65)
11-24 17:37:35.586: E/AndroidRuntime(1339):   
at android.os.Handler.dispatchMessage(Handler.java:99)
11-24 17:37:35.586: E/AndroidRuntime(1339):     at android.os.Looper.loop(Looper.java:137)
11-24 17:37:35.586: E/AndroidRuntime(1339):   
at android.os.HandlerThread.run(HandlerThread.java:60)

This is due to the default code that comes with the standard New install of the Android Cloud to Device Messaging (C2DM):

    /**
     * Display a notification containing the given string.
     */
    public static void generateNotification(Context context, String message) {
        int icon = R.drawable.status_icon;
        long when = System.currentTimeMillis();

        Notification notification = new Notification(icon, message, when);
        notification.setLatestEventInfo(context, "C2DM Example", message,
                PendingIntent.getActivity(context, 0, null, PendingIntent.FLAG_CANCEL_CURRENT));
        notification.flags |= Notification.FLAG_AUTO_CANCEL;

        SharedPreferences settings = Util.getSharedPreferences(context);
        int notificatonID = settings.getInt("notificationID", 0);

        NotificationManager nm = (NotificationManager) context
                .getSystemService(Context.NOTIFICATION_SERVICE);
        nm.notify(notificatonID, notification);

        SharedPreferences.Editor editor = settings.edit();
        editor.putInt("notificationID", ++notificatonID % 32);
        editor.commit();    

    }
 
Besides the fact that they really should be using the new Notification.Builder (introduced in Honeycomb API 11), this piece of code gives a NullPointerException because of the null value given where an Intent is expected.

PendingIntent.getActivity(context, 0, null, PendingIntent.FLAG_CANCEL_CURRENT));
 
All you have to do is add an Intent:

PendingIntent.getActivity(context, 0, new Intent(Util.DUMMY_PENDING_INTENT)
PendingIntent.FLAG_CANCEL_CURRENT));

You could use an existing one declared in Util.java, or you can create a new one like I did here called DUMMY_PENDING_INTENT. It doesn't matter because we are not going to use the Intent to start an activity, it's just an example to display a message on the notification bar. In a real program you would launch your app, just as an email notification launches your email app, etc.

No comments:

Post a Comment