> ## Documentation Index
> Fetch the complete documentation index at: https://documentation.onesignal.com/llms.txt
> Use this file to discover all available pages before exploring further.

# 管理通知栏

> OneSignal 移动推送通知在 Android 和 iOS 通知栏中的行为：点击和清除处理、恢复的通知、徽章、以编程方式清除通知以及服务扩展。

使用本指南了解并控制推送通知在设备上显示后的后续行为：点击和清除会发生什么、Android 何时会重新显示通知、徽章如何保持同步，以及哪些 SDK 工具可以让您在应用代码中管理通知栏。

本页涵盖移动推送（Android 和 iOS）。有关 Web 推送行为，请参阅 [Web 推送通知行为](./push)。

***

## 通知栏中的通知生命周期

SDK 会跟踪设备上显示的每条 OneSignal 通知。接下来发生的事情决定了它是否可能重新出现：

| 事件                                                                         | 发生什么                                                                                       | 是否会重新出现？                                      |
| -------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------ | --------------------------------------------- |
| **用户点击它**                                                                  | 从通知栏中移除，标记为已点击，[点击监听器](./mobile-sdk-reference#addclicklistener-push)触发，启动 URL 或 Intent 运行。 | 否                                             |
| **用户清除它**（滑动删除或"全部清除"）                                                     | 标记为已清除。                                                                                    | 否                                             |
| **您的应用使用 [OneSignal SDK 方法](#clearing-notifications-programmatically)清除它** | 从通知栏中移除并标记为已清除。                                                                            | 否                                             |
| **您的应用使用 Android 原生 `NotificationManager` 取消它**                            | 从通知栏中移除，但**不会**标记为已清除。                                                                     | 是，在 Android 上会在下次应用重启时恢复                      |
| **Android 强制移除它**（设备重启、应用更新、强制退出）                                          | 由操作系统在无用户操作的情况下移除。                                                                         | 是，请参阅[恢复的通知](#restored-notifications-android) |

<Warning>
  在 Android 上，请始终使用 OneSignal SDK 方法清除通知，而不是使用 Android 原生的 `NotificationManager.cancel()` 或 `cancelAll()`。使用原生 API 取消的通知不会被标记为已清除，因此 SDK 会在应用下次重启时恢复它们。
</Warning>

***

## 点击和清除行为

**点击**通知会打开您的应用（或通知的启动 URL），从通知栏中移除该通知，并触发 [`addClickListener()`](./mobile-sdk-reference#addclicklistener-push) 回调，回调携带通知载荷和被点击的操作按钮 ID。如果被点击的通知属于某个分组，SDK 会更新或移除分组摘要。已点击的通知绝不会被恢复。

**清除**通知（滑动删除或点按通知栏中的"全部清除"）会将其标记为已清除，并更新徽章计数和任何分组摘要。已清除的通知绝不会被恢复。SDK 不提供清除监听器；清除行为由内部跟踪。

当应用处于前台时显示的通知会先经过[前台生命周期监听器](./mobile-sdk-reference#addforegroundlifecyclelistener-push)，您可以在其中阻止显示。

***

## 恢复的通知（Android）

Android 可以在无用户操作的情况下强制移除通知：设备重启、应用更新和强制退出（包括某些设备上激进的电池管理器）。Android SDK 会在应用下次冷启动时自动重新显示（恢复）受影响的通知，因此用户从未看到或清除的已投递消息不会丢失。

恢复的通知会在低重要性的[已恢复类别](./android-notification-categories#restored)上静默地重新出现。只有未被点击或清除、仍在其 TTL 之内且在过去 7 天内收到的通知才会被恢复，最多 49 条。

完整的恢复资格规则和控制方法请参阅[恢复的通知（Android）](./osnotification-payload#restored-notifications-android)。要减少恢复，请在发送时使用较短的 `ttl`，或使用[下面的 SDK 方法](#clearing-notifications-programmatically)清除已被消费的通知。iOS 没有恢复行为。

***

## 徽章行为

在 **iOS** 上，徽章由通知载荷设置（`ios_badgeType` 和 `ios_badgeCount`），并且需要 App Group 以便服务扩展能够准确更新计数。默认情况下，SDK 会在应用打开时清除徽章。

在 **Android** 上，应用图标徽章反映通知栏中活动的 OneSignal 通知数量，并通过[通知类别](./android-notification-categories)管理。SDK 会在通知被显示、清除、点击或清理时自动更新计数，并在您调用 `clearAllNotifications()` 时将其重置为 `0`。

设置、各平台选项和故障排除请参阅[通知徽章](./badges)。

***

## 以编程方式清除通知

请在通知内容已在应用中被消费时清除通知，而不是在应用生命周期事件上清除。常见模式：

* **内容消费同步**：用户打开了通知指向的界面（收件箱、消息中心或动态流），这些通知因此变得多余。清除所有通知，或者如果只有部分内容被消费，则使用定向方法。
* **登出**：清除所有内容，使上一个用户的通知不会被下一个用户看到。

避免在每次应用启动或进入前台时清除通知来"保持通知栏干净"。通知栏中的通知能带动再互动，清除它们会移除这一入口。如果您要控制通知堆积，请在发送时使用 `collapse_id` 来替换通知而不是堆叠它们，或使用较短的 TTL 让未投递的通知过期。

### `clearAllNotifications()`

从通知栏中移除您应用的通知，并将徽章计数重置为 `0`。在 Android 上，这只会移除由 OneSignal 创建的通知，并将它们标记为已清除，因此不会被恢复。在 iOS 上，这会移除您应用的**所有**已投递通知，包括本地通知和来自其他提供商的推送。请参阅[完整方法参考](./mobile-sdk-reference#clearallnotifications)。

<Note>
  如果您在应用启动时清除通知以防止恢复的通知，请在跨平台应用中将该调用限定为仅在 Android 上执行。在 iOS 上，它还会移除本地通知和来自其他提供商的推送。
</Note>

### `removeNotification()` 和 `removeGroupedNotifications()`（Android）

按 Android 通知 ID 移除单条通知，或按分组键移除分组中的所有通知。被移除的通知会被标记为已清除且不会被恢复。当通知栏中只有部分内容被消费时（例如多个会话中的一个），请使用这些方法。请参阅[方法参考](./mobile-sdk-reference#removenotification-removegroupednotifications-android)。

***

## 延迟后自动清除通知

没有发送时参数可以在设定时间后移除已显示的通知。各平台可实现的方式不同：

* **Android 8.0（API 26）及更新版本**：在[通知服务扩展](./service-extensions)中使用 `setTimeoutAfter()` 设置超时。超时到期后，Android 会将通知从通知栏中移除。在低于 API 26 的设备上，该调用会被忽略，通知会保留到用户与其交互为止。
* **iOS**：不支持。iOS 无法让已投递的通知自动过期。最接近的选择是通过 [`collapse_id`](./push#collapse-id-mobile-push) 用更新的通知替换它，或在收到后续推送时通过 Notification Service Extension 使用 Apple 的 [`removeDeliveredNotifications(withIdentifiers:)`](https://developer.apple.com/documentation/usernotifications/unusernotificationcenter/removedeliverednotifications\(withidentifiers:\)) 移除它。

<CodeGroup>
  ```kotlin Kotlin theme={null}
  class NotificationServiceExtension : INotificationServiceExtension {
      override fun onNotificationReceived(event: INotificationReceivedEvent) {
          event.notification.setExtender { builder ->
              // 10 分钟后将此通知从通知栏中移除（仅限 API 26+）
              builder.setTimeoutAfter(10 * 60 * 1000L)
          }
      }
  }
  ```

  ```java Java theme={null}
  public class NotificationServiceExtension implements INotificationServiceExtension {
      @Override
      public void onNotificationReceived(INotificationReceivedEvent event) {
          event.getNotification().setExtender(builder ->
              // 10 分钟后将此通知从通知栏中移除（仅限 API 26+）
              builder.setTimeoutAfter(10 * 60 * 1000L)
          );
      }
  }
  ```
</CodeGroup>

要让超时按消息设置而不是固定在代码中，请在发送时通过 [`additionalData`](./osnotification-payload) 传入时长，并在服务扩展中从事件里读取。

<Note>
  被 `setTimeoutAfter()` 移除的通知由系统清除，因此 OneSignal SDK 不会恢复它。不要将其与 `ttl` 混淆——`ttl` 控制未投递的消息为离线设备等待多长时间，绝不会移除已显示的通知。
</Note>

***

## 使用服务扩展自定义通知

[服务扩展](./service-extensions)在通知显示之前运行，让您可以修改其外观、接收后台数据或完全阻止显示：

* 在 **Android** 上，实现 `INotificationServiceExtension` 并使用 `setExtender()` 更改 `NotificationCompat` 选项，或调用 `event.preventDefault()` 抑制显示。
* 在 **iOS** 上，使用 `UNNotificationServiceExtension`（设置期间创建的 `OneSignalNotificationServiceExtension`）实现富媒体、徽章递增和确认投递。

<Warning>
  在 Android 上，您的服务扩展也会针对[恢复的通知](#restored-notifications-android)运行。`onNotificationReceived` 中的副作用（分析调用、API 请求、数据库写入）会在通知恢复时重新执行，而 `setChannelId()` 等 extender 更改同样适用于恢复的通知，这可能使它们大声提醒。请设计您的扩展，使提醒选项仅应用于新投递的通知。
</Warning>

***

## 常见问题

### 为什么在 Android 上打开应用时旧通知会重新出现？

Android SDK 会恢复被强制从通知栏中移除的通知，例如在设备重启、应用更新或强制退出之后。用户已清除或点击的通知不会被恢复。有关资格规则和控制方法，请参阅[恢复的通知（Android）](./osnotification-payload#restored-notifications-android)。

### TTL 过期后会将通知从通知栏中移除吗？

不会。TTL 控制未投递的消息为离线设备等待多长时间，在 Android 上它还限定哪些通知可以被恢复。它绝不会移除已在通知栏中显示的通知。要移除已显示的通知，请使用[清除方法](#clearing-notifications-programmatically)。要在 Android 上于设定时间后移除它们，请参阅[延迟后自动清除通知](#dismiss-notifications-automatically-after-a-delay)。

### 我可以在不清空通知栏的情况下清除徽章吗？

在 iOS 上可以：徽章会在应用打开时自动清除（除非已禁用），通知栏内容保持不变。在 Android 上，徽章反映通知栏中活动的通知，因此无法独立于它们进行设置。请参阅[通知徽章](./badges)。

### 有用户清除通知时的监听器吗？

没有。SDK 在内部跟踪清除行为以防止恢复已清除的通知，但不公开清除事件。[点击监听器](./mobile-sdk-reference#addclicklistener-push)仅涵盖点击。

***

<Columns cols={3}>
  <Card title="移动 SDK 参考" icon="code" href="./mobile-sdk-reference">
    通知方法和监听器的完整参考。
  </Card>

  <Card title="OSNotification 载荷" icon="brackets-curly" href="./osnotification-payload">
    载荷字段和恢复通知规则。
  </Card>

  <Card title="移动服务扩展" icon="puzzle-piece" href="./service-extensions">
    在显示之前拦截和自定义通知。
  </Card>
</Columns>
