---
title: "在 Flutter SDK 中控制商店消息"
description: "选择 Flutter 应用在何时显示 App Store 和 Google Play 关于价格上涨、账单问题及付款拒绝的消息，避免中断流程或用户引导。"
---

> **AI agents**: to search Adapty docs faster and with fewer tokens, install the Adapty skills: `npx adapty skills install --yes`

App Store 和 Google Play 有时需要向用户显示有关其订阅的消息：

- **App Store**：请求用户同意价格上涨、账单问题通知或赢回优惠的弹窗。默认情况下，StoreKit 会在应用处于前台时自动显示这些消息。
- **Google Play**：订阅付款被拒且需要更新支付方式的通知。默认情况下，Adapty SDK 会在每次 `Activity` 启动后（包括应用返回前台、流程或用户引导打开或关闭时）请求这些消息。

无论如何，消息都可以显示在流程、用户引导或结账页面的上方。如需自行控制显示时机，请将 Adapty SDK 切换至手动消息处理模式，并在不影响用户操作时调用 `showStoreMessages`。

:::warning
在手动模式下，商店不会自动显示消息。如果你的应用从未调用 `showStoreMessages`，用户将永远看不到涨价同意请求、账单问题通知或支付拒绝通知。
:::

## 开始之前 \{#before-you-start\}

你需要：

- **Adapty Flutter SDK 4.3.0 或更高版本**：更低版本不支持 store messages API。
- **iOS 16 或更高版本**（用于 App Store 消息）：StoreKit 不会向运行更低版本的应用投递消息。在 iOS 15 上，`getPendingStoreMessageTypes` 和 `showStoreMessages` 会返回 `decodingFailed` 错误，因此如果你的应用需要支持 iOS 15，请仅在 iOS 16 及更高版本上调用这两个方法。

## 启用手动处理 \{#enable-manual-handling\}

若要仅在应用调用 `showStoreMessages` 时显示商店消息，请在[激活 SDK](sdk-installation-flutter#activate-adapty-module-of-adapty-sdk) 时使用 `AdaptyStoreMessagesHandling.manual` 调用 `withStoreMessagesHandling`：

```dart showLineNumbers title="main.dart"
await Adapty().activate(
  configuration: AdaptyConfiguration(apiKey: 'YOUR_PUBLIC_SDK_KEY')
    ..withStoreMessagesHandling(AdaptyStoreMessagesHandling.manual), // auto is the default
);
```

在 iOS 上，SDK 会将每条 App Store 消息添加到当前应用会话的待处理列表中。在 Android 上，SDK 会停止自行请求 Google Play 消息。使用默认的 `auto` 值时，SDK 不会捕获 App Store 消息，因此在 iOS 上，`getPendingStoreMessageTypes` 和 `showStoreMessages` 将没有任何内容可以返回或显示。

## 获取待处理消息类型 \{#get-pending-message-types\}

在 iOS 上，若要查看是否有待处理的 App Store 消息，请调用 `getPendingStoreMessageTypes`。该方法会返回待处理消息的类型，但不会显示或移除这些消息：

```dart showLineNumbers
final pendingTypes = await Adapty().getPendingStoreMessageTypes();

if (pendingTypes == null) {
  // Android: Google Play decides whether a message applies when you show it
} else if (pendingTypes.contains(AdaptyStoreMessageType.billingIssue)) {
  // For example, skip the upsell and show the billing message first
}
```

在 Android 上，该方法返回 `null`：Google Play 不报告待处理消息，只有当应用主动请求时才会决定是否应用某条消息。空列表表示 iOS 上没有待处理消息。在 `activate` 完成之前，列表始终为空。

每条 App Store 消息都属于以下类型之一：

| 类型 | 消息 |
|:-----|:--------|
| `AdaptyStoreMessageType.generic` | 通用 App Store 消息。 |
| `AdaptyStoreMessageType.priceIncreaseConsent` | 订阅涨价同意请求。 |
| `AdaptyStoreMessageType.billingIssue` | 订阅账单问题通知。适用于 iOS 16.4 及更高版本。 |
| `AdaptyStoreMessageType.winBackOffer` | 符合条件的[赢回优惠](app-store-offers#win-back-offers)。适用于 iOS 18 及更高版本。 |

SDK 无法识别的消息类型，其 `value` 为 `storekit_<number>`。请使用 `==` 进行类型比较，而不要假设只有这四种类型。

## 显示消息 \{#show-messages\}

当应用到达不会打扰用户的时机——例如用户关闭流程或完成用户引导之后——调用 `showStoreMessages`：

```dart showLineNumbers
try {
  await Adapty().showStoreMessages();
} on AdaptyError catch (adaptyError) {
  // handle the error
} catch (e) {
  // handle other errors
}
```

- **iOS**：SDK 会逐条显示待处理消息。StoreKit 显示某条消息后，SDK 会将其从待处理列表中移除。如果 StoreKit 无法显示某条消息，SDK 会保留该消息留待下次调用，并继续处理其他消息。
- **Android**：SDK 会针对当前 `Activity` 请求 Google Play 消息。Google Play 会自行判断消息是否适用于该用户，因此请求不一定会触发消息显示。调用会立即返回，不会等待 Google Play，也不会失败。如果用户通过消息修复了支付方式，SDK 会将用户的购买记录与 Adapty 同步，您的[用户画像监听器](flutter-listen-subscription-changes)将收到更新后的访问等级。

### 在 Android 上启动时显示消息 \{#show-messages-at-launch-on-android\}

在默认的 `auto` 模式下，在 `activate` 之前启动的 `Activity` 不会触发请求，因此 Google Play 消息不会在启动时显示。要在启动时显示这些消息，请在 `activate` 之后调用一次 `showStoreMessages`，仅限 Android：

```dart showLineNumbers title="main.dart"

await Adapty().activate(
  configuration: AdaptyConfiguration(apiKey: 'YOUR_PUBLIC_SDK_KEY'),
);

if (Platform.isAndroid) {
  await Adapty().showStoreMessages();
}
```

不要在 iOS 上调用此方法：在 `auto` 模式下，它没有任何内容可显示；而在 iOS 15 上，调用会失败。

### 仅显示部分消息类型 \{#show-only-some-message-types\}

如需仅显示部分待处理的 App Store 消息，可通过 `iosFilter` 传入消息类型。其他消息将保持待处理状态：

```dart showLineNumbers
await Adapty().showStoreMessages(
  iosFilter: [
    AdaptyStoreMessageType.billingIssue,
    AdaptyStoreMessageType.priceIncreaseConsent,
  ],
);
```

不传 `iosFilter` 时，SDK 会显示所有待处理消息，包括无法识别的类型。传入空列表则不显示任何消息。Android 会忽略 `iosFilter`，并请求所有 Google Play 消息。

### 错误 \{#errors\}

在 iOS 上，`showStoreMessages` 失败时会返回一个 [`AdaptyError`](error-handling-on-flutter-react-native-unity)，错误码如下：

| 错误码 | 名称 | 原因 |
|:-----|:-----|:------|
| 2006 | `decodingFailed` | 设备运行的是 iOS 15 或更早版本。请仅在 iOS 16 及以上版本调用此方法。 |
| 3201 | `operationInProgress` | 另一个 `showStoreMessages` 调用仍在显示消息中。请等待其完成后再重试。 |
| 3202 | `resolverFailure` | SDK 未找到处于前台活跃状态的窗口场景来显示消息。请在应用处于前台时再次调用该方法。 |