是setContentIntent(PendingIntent)要求NotificationCompat.Builder?PendingIntent、setContentIntent、Builder、

2023-09-13 23:55:25 作者:过犹不及

电话:

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);
}

的onCreate()我的主要活动产生:

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

注意的 contentIntent 要求。

然而,文档不能更清楚

要求的通报内容

一个通知对象必须包含以下内容:

A Notification object must contain the following:

  

有一个小图标,通过setSmallIcon设置()

A small icon, set by setSmallIcon()

一个称号,被setContentTitle设置()

A title, set by setContentTitle()

详细文本,由setContentText设置()

Detail text, set by setContentText()

可选的通知内容,并设置

所有其他通知设置和内容都是可选的。为了更多地了解他们,请参阅NotificationCompat.Builder的参考文档。

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

这个观点反映在各种 SO的答案并导致SO questions (和another一个)。

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

解决方法:

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

但是,这是真正需要的?都是这种情况的另一个的 Android的文档错误的?它是API依赖?

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

注:我的目标SDK是17,并在2.3.7手机上运行这个

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

推荐答案

如果你使用像waybackmachine缓存服务和你的$p$pvious版本的通知导游,你会看到提示不告诉你, contentIntent 是必需的。

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.

这反映在Android的来源。显示之前 NotificationManagerService 处理通知的检查。

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

在Gingerbread,作为 enqueueNotificationInternal()方法的一部分,它有这个检查:

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);
    }
}

在之后的And​​r​​oid版本,如Ice Cream Sandwich的 ,即检查了:

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);
    }
}

因此​​, contentIntent 终止的需要的关于姜饼及以下。

Thus, a contentIntent is required on Gingerbread and below.