如何无意中关闭通知?

How to dismiss notification without intent?

我想在应用程序中显示一条通知,当点击通知时不启动 activity。

我使用了一个空的意图并且它有效:

Intent intent = new Intent();
PendingIntent contentIntent = PendingIntent.getActivity(context, (int)System.currentTimeMillis(), intent, PendingIntent.FLAG_UPDATE_CURRENT);

NotificationCompat.Builder mBuilder = new NotificationCompat.Builder(context, "")
                .setSmallIcon(R.drawable.icon)
                .setContentTitle(title)
                .setContentText(text)
                .setAutoCancel(true)
                .setTicker(text);
                .setContentIntent(contentIntent);

但是,有一些崩溃:

java.lang.RuntimeException: bad array lengths
    at android.os.Parcel.readIntArray(Parcel.java:789)
    at android.app.INotificationManager$Stub$Proxy.enqueueNotificationWithTag(INotificationManager.java:339)
    at android.app.NotificationManager.notify(NotificationManager.java:139)
    at android.app.NotificationManager.notify(NotificationManager.java:112)
    ...

根据 this SO answer 的说法,崩溃似乎是因为 intent 没有启动 activity。

一个通知可以通过它的 ID 关闭,但是当没有 activity 启动和调用关闭方法时我不能关闭它。

如何在不使用空 intent 的情况下关闭应用内点击时的通知?


更新:

根据 this SO questions 这似乎是一个 Android 问题。我报告的崩溃也发生在 Android 4.3.

更新 2:

根据this SO answer,这似乎是由于 setLargeIcon 设置的位图太大所致。所以我现在用 Glide 减小位图大小。

您可以创建一个调用 BroadcastReceiver 的意图,然后取消通知。

您的 PendingIntent 可以这样创建:

private PendingIntent getCancelNotificationIntent() {
    Intent cancelIntent = new Intent(context, CancelNotification.class);
    return PendingIntent.getBroadcast(context, 0, cancelIntent, PendingIntent.FLAG_UPDATE_CURRENT);
}

CancelNotification.java class 看起来类似于:

public class CancelNotification extends BroadcastReceiver {

    @Override
    public void onReceive(Context context, Intent intent) {
        notificationManager.cancel(NOTIFICATION_ID);
    }
}

编辑:
NOTIFICATION_ID 是您定义并传递给 NotificationManager 的常量,如下所示:

notificationManager.notify(NOTIFICATION_ID, yourNotificationObject);

注意:不要忘记像这样在清单文件中注册接收器:

<receiver android:name="com.example.package.CancelNotification" />

如果您不想在用户点击通知时启动 activity 您可以构建一个发送广播或启动服务的未决意图。

这是一个例子:

PendingIntent.getBroadcast(context, 12, new Intent("any intent action"), PendingIntent.FLAG_UPDATE_CURRENT)

但是是什么阻止了您的 activity 实现这样的功能:

@Override
public void onCreate(Bundle savedInstanceState) {}

清单中有额外的 nodisplay 主题:

android:theme="@android:style/Theme.NoDisplay"

它只是一个 no-op