Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Is setContentIntent(PendingIntent) required in NotificationCompat.Builder?

Calling :

public static void triggerTestNotification(Context ctx, String tag, int id) {
    Notification not = new NotificationCompat.Builder(ctx)
        .setContentTitle("Title").setContentText("Text")
        .setAutoCancel(true) // cancel on click
        .setSmallIcon(R.drawable.ic_launcher).build();
    NotificationManager notificationManager = (NotificationManager) ctx
        .getSystemService(Context.NOTIFICATION_SERVICE);
    notificationManager.notify(tag, id, not);
}

in onCreate() of my main activity yields :

11-17 15:58:46.198: E/AndroidRuntime(1507): FATAL EXCEPTION: main
11-17 15:58:46.198: E/AndroidRuntime(1507): java.lang.RuntimeException: Unable to start activity ComponentInfo{gr.uoa.di.monitoring.android/gr.uoa.di.monitoring.android.activities.MainActivity}: java.lang.IllegalArgumentException: contentIntent required: pkg=gr.uoa.di.monitoring.android id=0 notification=Notification(vibrate=null,sound=null,defaults=0x0,flags=0x10)
//...
11-17 15:58:46.198: E/AndroidRuntime(1507): Caused by: java.lang.IllegalArgumentException: contentIntent required: pkg=gr.uoa.di.monitoring.android id=0 notification=Notification(vibrate=null,sound=null,defaults=0x0,flags=0x10)
11-17 15:58:46.198: E/AndroidRuntime(1507):     at android.os.Parcel.readException(Parcel.java:1326)
11-17 15:58:46.198: E/AndroidRuntime(1507):     at android.os.Parcel.readException(Parcel.java:1276)
11-17 15:58:46.198: E/AndroidRuntime(1507):     at android.app.INotificationManager$Stub$Proxy.enqueueNotificationWithTag(INotificationManager.java:274)
11-17 15:58:46.198: E/AndroidRuntime(1507):     at android.app.NotificationManager.notify(NotificationManager.java:133)
11-17 15:58:46.198: E/AndroidRuntime(1507):     at gr.uoa.di.monitoring.android.C.triggerTestNotification(C.java:200)
11-17 15:58:46.198: E/AndroidRuntime(1507):     at gr.uoa.di.monitoring.android.activities.MainActivity.onCreate(MainActivity.java:44)
11-17 15:58:46.198: E/AndroidRuntime(1507):     at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1047)
11-17 15:58:46.198: E/AndroidRuntime(1507):     at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:1722)
11-17 15:58:46.198: E/AndroidRuntime(1507):     ... 11 more

Notice the contentIntent required.

However the docs could not be more clear :

Required notification contents

A Notification object must contain the following:

  • A small icon, set by setSmallIcon()

  • A title, set by setContentTitle()

  • Detail text, set by setContentText()

Optional notification contents and settings

All other notification settings and contents are optional. To learn more about them, see the reference documentation for NotificationCompat.Builder.

This opinion is reflected in various SO answers and results in SO questions (and another one).

workaround :

final Intent emptyIntent = new Intent();
PendingIntent pi = PendingIntent.getActivity(ctx, NOT_USED,
    emptyIntent, PendingIntent.FLAG_UPDATE_CURRENT);
//...
.setContentIntent(pi).build;

But is this really needed ? Is all this situation another Android docs bug ? Is it API dependent ?

NB my target SDK is 17 and running this on a 2.3.7 phone

like image 309
Mr_and_Mrs_D Avatar asked Nov 17 '13 15:11

Mr_and_Mrs_D


People also ask

Why do we use PendingIntent in Android?

A PendingIntent itself is simply a reference to a token maintained by the system describing the original data used to retrieve it. This means that, even if its owning application's process is killed, the PendingIntent itself will remain usable from other processes that have been given it.

What is pending intent in notification?

In other words, PendingIntent lets us pass a future Intent to another application and allow that application to execute that Intent as if it had the same permissions as our application, whether or not our application is still around when the Intent is eventually invoked.

Which intent is employed for generating notification in Android?

MainActivity. The NotificationManager. notify() method is used to display the notification. The Intent class is used to call another activity (NotificationView.


1 Answers

If you use a caching service like waybackmachine and you look for previous versions of the Notifications guide, you will see that the guide does tell you that the contentIntent is required.

This is reflected in the Android source as well. NotificationManagerService handles the checking of Notifications before displaying them.

In Gingerbread, as part of the enqueueNotificationInternal() method, it has this check:

if (notification.icon != 0) {
    if (notification.contentView == null) {
          throw new IllegalArgumentException("contentView required: pkg=" + pkg
                    + " id=" + id + " notification=" + notification);
    }
    if (notification.contentIntent == null) {
        throw new IllegalArgumentException("contentIntent required: pkg=" + pkg
                + " id=" + id + " notification=" + notification);
    }
}

On later Android versions, such as Ice Cream Sandwich, that check is gone:

if (notification.icon != 0) {
    if (notification.contentView == null) {
       throw new IllegalArgumentException("contentView required: pkg=" + pkg
              + " id=" + id + " notification=" + notification);
    }
}

Thus, a contentIntent is required on Gingerbread and below.

like image 172
A--C Avatar answered Oct 13 '22 04:10

A--C