> ## 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.

# Android SDK 设置

> 使用 OneSignal 的 Android SDK 为您的 Android 应用添加推送通知和应用内消息。

export const SdkReleasesIframe = ({sdkFilter = undefined, viewMode = undefined, height, ...frameProps}) => {
  const baseUrl = 'https://onesignal.github.io/sdk-releases';
  const buildUrl = (theme, sdkFilter, viewMode) => {
    const url = new URL(baseUrl);
    const params = new URLSearchParams();
    if (theme) {
      params.set('theme', theme);
    }
    if (sdkFilter) {
      params.set('sdk', sdkFilter);
    }
    if (viewMode) {
      params.set('viewMode', viewMode);
    }
    if (params.toString()) {
      url.search = params.toString();
    }
    return url.toString();
  };
  const detectTheme = () => {
    if (document.documentElement.classList.contains('dark')) {
      return 'dark';
    }
    return 'light';
  };
  const [theme, setTheme] = useState('light');
  const [iframeSrc, setIframeSrc] = useState(() => {
    const initialTheme = detectTheme();
    return buildUrl(initialTheme, sdkFilter, viewMode);
  });
  useEffect(() => {
    const currentTheme = detectTheme();
    setTheme(currentTheme);
    setIframeSrc(buildUrl(currentTheme, sdkFilter, viewMode));
    const mediaQuery = window.matchMedia('(prefers-color-scheme: dark)');
    const handleThemeChange = () => {
      const newTheme = detectTheme();
      setTheme(newTheme);
      setIframeSrc(buildUrl(newTheme, sdkFilter, viewMode));
    };
    if (mediaQuery.addEventListener) {
      mediaQuery.addEventListener('change', handleThemeChange);
    } else {
      mediaQuery.addListener(handleThemeChange);
    }
    window.addEventListener('storage', handleThemeChange);
    const observer = new MutationObserver(handleThemeChange);
    observer.observe(document.documentElement, {
      attributes: true,
      attributeFilter: ['class', 'data-theme']
    });
    return () => {
      if (mediaQuery.removeEventListener) {
        mediaQuery.removeEventListener('change', handleThemeChange);
      } else {
        mediaQuery.removeListener(handleThemeChange);
      }
      window.removeEventListener('storage', handleThemeChange);
      observer.disconnect();
    };
  }, [sdkFilter, viewMode]);
  const getIframeHeight = () => {
    if (viewMode === 'table') {
      return '450';
    }
    if (viewMode === 'mini') {
      return '170';
    }
    return '800';
  };
  const iframeHeight = height || getIframeHeight();
  return <Frame {...frameProps}>
      <iframe src={iframeSrc} width="100%" height={iframeHeight} frameBorder="0" style={{
    border: "none"
  }} title="SDK Releases" key={iframeSrc} />
    </Frame>;
};

<SdkReleasesIframe sdkFilter="android" viewMode="mini" />

本指南将引导您使用 Android Studio 将 OneSignal 添加到您的 Android 应用中。您将安装我们的 SDK，设置推送通知和应用内消息，并发送测试消息以确认一切正常工作。

如果这是您首次使用 OneSignal，请按顺序完成这些步骤。如果您有经验，可以直接跳转到需要的部分。

<Info>
  **使用 AI 编程助手？**
  如需 AI 驱动的安装，请使用以下提示：

  ```
  Integrate the OneSignal Android SDK into this codebase.

  Follow the instructions at:
  https://raw.githubusercontent.com/OneSignal/sdk-ai-prompts/main/docs/android/ai-prompt.md
  ```
</Info>

## 步骤 0. 在 OneSignal 中配置 FCM（推送送达必需）

您可以在未完成此步骤的情况下安装和初始化 OneSignal Android SDK。但是，在 OneSignal 应用中配置 Firebase Cloud Messaging (FCM) 凭据之前，**推送通知将无法送达**。

<Note>
  如果您的公司已有 OneSignal 账户，请[要求以管理员角色被邀请](./manage-team-members)以配置该应用。否则，请[注册免费账户](https://onesignal.com)开始使用。
</Note>

<Accordion title="配置 OneSignal 应用的步骤。">
  这些步骤将您的 OneSignal 应用连接到 Firebase Cloud Messaging (FCM)。每个应用只需执行一次。

  1. 登录 [https://onesignal.com](https://onesignal.com) 并创建或选择您的应用。
  2. 导航到 **Settings > Push & In-App**。
  3. 选择 **Google Android (FCM)** 并 **Continue** 完成设置向导。
  4. 输入您的 [Firebase 服务器密钥或服务账户](./android-firebase-credentials)详细信息。
  5. 继续完成设置向导以获取您的 App ID。这将用于初始化 SDK。

  <Info>有关完整的设置说明，请参阅我们的[移动推送设置](./mobile-push-setup)指南。</Info>
</Accordion>

***

## 设置合约和要求

本节总结了本指南中使用的工具、版本和前提条件。

* **SDK 版本：** `5.6.1+`（最新版：查看 [releases](https://github.com/OneSignal/OneSignal-Android-SDK/releases)）
* **AI 设置说明：** `https://raw.githubusercontent.com/OneSignal/sdk-ai-prompts/main/docs/android/ai-prompt.md`
* **SDK 仓库：** `https://github.com/OneSignal/OneSignal-Android-SDK`
* **Android Studio：** Meerkat+（2024.2.1+）
* **Android API：** 最低 23+（Android 6.0+），推荐 31+（Android 12+）
* **设备/模拟器：** Android 7.0+ 且已安装 Google Play Services
* **必需依赖：** `com.onesignal:OneSignal:[5.6.1, 5.9.99]`
* **Application 类：** SDK 正确初始化所必需
* **App ID 格式：** 36 个字符的 UUID（示例：`12345678-1234-1234-1234-123456789012`）— 在 OneSignal 控制面板 > Settings > Keys & IDs 中查找
* **初始化：** `OneSignal.initWithContext(this, "YOUR_APP_ID")`
* **电池优化：** 可能影响后台通知
* **推荐：** 通过 `OneSignal.login("user_id")` 分配 External ID 以统一跨设备用户

***

## Android 设置步骤

完成以下步骤后，您将：

* 在您的 Android 应用中安装并初始化 OneSignal SDK
* 在真实设备上正确提示推送通知权限
* 成功送达测试推送和应用内消息

<Info>
  如果您跳过了**步骤 0（在 OneSignal 中配置 FCM）**，您仍然可以完成以下 Android Studio 设置。请在测试或发送推送通知之前完成步骤 0。
</Info>

### 步骤 1. 添加 OneSignal SDK

1. 在 Android Studio 中，打开您的 `build.gradle.kts (Module: app)` 或 `build.gradle (Module: app)` 文件
2. 将 OneSignal 添加到您的 `dependencies` 部分：

<CodeGroup>
  ```kotlin app/build.gradle.kts theme={null}
  implementation("com.onesignal:OneSignal:[5.6.1, 5.9.99]")
  ```

  ```groovy app/build.gradle theme={null}
  implementation 'com.onesignal:OneSignal:[5.6.1, 5.9.99]'
  ```
</CodeGroup>

<Frame caption="示例展示了将 OneSignal 添加到应用的 build.gradle.kts 文件中。">
  <img src="https://mintcdn.com/onesignal/dlRpLVMLP5Sd65F4/images/sdk/android-add-onesignal-to-build-gradle.png?fit=max&auto=format&n=dlRpLVMLP5Sd65F4&q=85&s=a1e031945c35197d41335c7c2956739e" width="3052" height="2030" data-path="images/sdk/android-add-onesignal-to-build-gradle.png" />
</Frame>

3. **同步 Gradle：** 点击出现的横幅中的 **Sync Now** 或前往 **File > Sync Project with Gradle Files**

<Check>
  验证 Gradle 同步成功完成且没有依赖冲突。
</Check>

### 步骤 2. 创建并配置 Application 类

最佳实践是在 `Application` 类的 `onCreate` 方法中初始化 OneSignal，以确保在所有入口点都能正确设置 SDK。

**如果您还没有 Application 类，请创建一个：**

1. **File > New > Kotlin Class/File**（或 Java Class）
2. 名称：`ApplicationClass`（或您首选的名称）

<Frame caption="示例展示了创建一个名为 ApplicationClass 的新 Kotlin 类。">
  <img src="https://mintcdn.com/onesignal/dlRpLVMLP5Sd65F4/images/sdk/android-create-application-class-kotlin.png?fit=max&auto=format&n=dlRpLVMLP5Sd65F4&q=85&s=7ce9f314acb72ff74311c2695368f5cf" width="2810" height="1798" data-path="images/sdk/android-create-application-class-kotlin.png" />
</Frame>

**将以下 OneSignal 代码添加到 Application 类中。**

将 `YOUR_APP_ID` 替换为您在 Dashboard > Settings > [Keys & IDs](./keys-and-ids) 中获取的实际 OneSignal App ID。

<CodeGroup>
  ```kotlin ApplicationClass.kt theme={null}
  // FILE: ApplicationClass.kt
  // PURPOSE: Initialize OneSignal when your app launches
  // REQUIREMENT: Must be registered in AndroidManifest.xml

  package com.your.package.name // Replace with your actual package name

  import android.app.Application
  import kotlinx.coroutines.CoroutineScope
  import kotlinx.coroutines.Dispatchers
  import kotlinx.coroutines.launch

  import com.onesignal.OneSignal
  import com.onesignal.debug.LogLevel

  class ApplicationClass : Application() {
      override fun onCreate() {
          super.onCreate()

          // Enable verbose logging to debug issues (remove in production)
          OneSignal.Debug.logLevel = LogLevel.VERBOSE

          // Replace with your 36-character App ID from Dashboard > Settings > Keys & IDs
          OneSignal.initWithContext(this, "YOUR_APP_ID")

          // Prompt user for push notification permission
          // In production, consider using an in-app message instead for better opt-in rates
          CoroutineScope(Dispatchers.IO).launch {
              OneSignal.Notifications.requestPermission(false)
          }
      }
  }
  ```

  ```java ApplicationClass.java theme={null}
  // FILE: ApplicationClass.java
  // PURPOSE: Initialize OneSignal when your app launches
  // REQUIREMENT: Must be registered in AndroidManifest.xml

  package com.your.package.name; // Replace with your actual package name

  import android.app.Application;

  import com.onesignal.Continue;
  import com.onesignal.OneSignal;
  import com.onesignal.debug.LogLevel;

  public class ApplicationClass extends Application {
      @Override
      public void onCreate() {
          super.onCreate();

          // Enable verbose logging to debug issues (remove in production)
          OneSignal.getDebug().setLogLevel(LogLevel.VERBOSE);

          // Replace with your 36-character App ID from Dashboard > Settings > Keys & IDs
          OneSignal.initWithContext(this, "YOUR_APP_ID");

          // Prompt user for push notification permission
          // In production, consider using an in-app message instead for better opt-in rates
          OneSignal.getNotifications().requestPermission(false, Continue.none());
      }
  }
  ```
</CodeGroup>

<Frame caption="示例 ApplicationClass.kt 文件。">
  <img src="https://mintcdn.com/onesignal/dlRpLVMLP5Sd65F4/images/sdk/android-application-class-kotlin.png?fit=max&auto=format&n=dlRpLVMLP5Sd65F4&q=85&s=e035c8995472b308f10e42ed82478a0a" width="3052" height="2030" data-path="images/sdk/android-application-class-kotlin.png" />
</Frame>

<Warning>
  不建议在 `Activity`（如 `MainActivity`）中初始化，因为通过深度链接或通知冷启动应用时可能不会调用它。请始终在 `Application` 类中初始化 OneSignal 以确保可靠性。
</Warning>

**注册 Application 类：**

1. 打开应用的 `AndroidManifest.xml`
2. 在 `<application>` 标签中添加 `android:name=".ApplicationClass"`（如果您设置了不同的类名，请替换 `.ApplicationClass`）。

```xml AndroidManifest.xml theme={null}
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools">

    <application
        android:name=".ApplicationClass"
        android:icon="@mipmap/ic_launcher"
        android:label="@string/app_name"
        ...
      </application>

  </manifest>
```

<Frame caption="包含 .ApplicationClass 名称的 AndroidManifest.xml。">
  <img src="https://mintcdn.com/onesignal/dlRpLVMLP5Sd65F4/images/sdk/android-androidmanifest-application-class.png?fit=max&auto=format&n=dlRpLVMLP5Sd65F4&q=85&s=289b016975723e22e23d1871457ae21f" width="3052" height="2030" data-path="images/sdk/android-androidmanifest-application-class.png" />
</Frame>

<Check>
  验证应用构建并运行无错误。
</Check>

### 步骤 3. 配置默认通知图标（推荐）

自定义[通知图标](./notification-icons)以匹配您的应用品牌。此步骤是可选的，但为了专业外观建议完成。

### 步骤 4. 测试集成

**验证订阅创建：**

1. 在带有 Google Play Services 的设备或模拟器上启动应用
2. 检查 Dashboard > **Audience > Subscriptions** — 状态显示 "Never Subscribed"
3. 当权限提示出现时接受
4. 刷新控制面板 — 状态变为 "Subscribed"

<Frame caption="iOS 和 Android 推送权限提示示例">
  <img src="https://mintcdn.com/onesignal/RWtLFPeffHrC81wI/images/docs/a90c2cc443f5fe9e7c80368c680a16cf1ca6203f7b28a0a6eec212add8510f80-Untitled_design_11.png?fit=max&auto=format&n=RWtLFPeffHrC81wI&q=85&s=96dbf224b3ae93b3d814712cdc5416ba" alt="iOS 和 Android 推送权限提示示例。" width="1920" height="1080" data-path="images/docs/a90c2cc443f5fe9e7c80368c680a16cf1ca6203f7b28a0a6eec212add8510f80-Untitled_design_11.png" />
</Frame>

<Frame caption="控制面板显示状态为 'Never Subscribed' 的订阅">
  <img src="https://mintcdn.com/onesignal/mJXnj6xKtiaVBd7y/images/dashboard/subscription-never-subscribed.png?fit=max&auto=format&n=mJXnj6xKtiaVBd7y&q=85&s=f6412faa44ca1c0dfbd07dc39e82fc08" alt="控制面板显示状态为 'Never Subscribed' 的订阅。" width="2472" height="1066" data-path="images/dashboard/subscription-never-subscribed.png" />
</Frame>

<Frame caption="允许推送权限后，刷新控制面板可看到订阅状态更新为 'Subscribed'">
  <img src="https://mintcdn.com/onesignal/mJXnj6xKtiaVBd7y/images/dashboard/subscription-subscribed.png?fit=max&auto=format&n=mJXnj6xKtiaVBd7y&q=85&s=cef79235b64703bc1a1bbffab775366e" alt="允许推送权限后，刷新控制面板可看到订阅状态更新为 'Subscribed'。" width="2472" height="1066" data-path="images/dashboard/subscription-subscribed.png" />
</Frame>

<Check>
  您已成功创建了一个[移动订阅](./subscriptions)。
  移动订阅在用户首次在设备上打开您的应用或卸载后重新安装时创建。
</Check>

#### 创建测试订阅和细分

1. 点击订阅旁边的 **⋮** > **Add to Test Users** > 为其命名
2. 前往 **Audience > Segments > New Segment**
3. 名称：`Test Users`，添加 **Test Users** 筛选器 > **Create Segment**

<Frame caption="添加测试订阅">
  <img src="https://mintcdn.com/onesignal/NCUI56Tiw7V-s0dT/images/dashboard/add-to-test-subscriptions.png?fit=max&auto=format&n=NCUI56Tiw7V-s0dT&q=85&s=2455d4cd74ea4ad686f76730cd95bbaa" alt="添加测试订阅。" width="1188" height="742" data-path="images/dashboard/add-to-test-subscriptions.png" />
</Frame>

<Frame caption="使用 Test Users 筛选器创建 'Test Users' 细分">
  <img src="https://mintcdn.com/onesignal/NCUI56Tiw7V-s0dT/images/dashboard/create-test-users-segment.png?fit=max&auto=format&n=NCUI56Tiw7V-s0dT&q=85&s=91b8a021be6e83662854e68ec3e1da04" alt="使用 Test Users 筛选器创建 'Test Users' 细分。" width="1188" height="742" data-path="images/dashboard/create-test-users-segment.png" />
</Frame>

<Check>
  您已成功创建了一个测试用户细分。

  现在我们可以测试向该设备和测试用户组发送消息。
</Check>

#### 通过 API 发送测试推送

1. 导航到 **Settings > [Keys & IDs](./keys-and-ids)**。
2. 在提供的代码中，将下方代码中的 `YOUR_APP_API_KEY` 和 `YOUR_APP_ID` 替换为您的实际密钥。此代码使用我们之前创建的 `Test Users` 细分。

```bash theme={null}
curl -X POST 'https://api.onesignal.com/notifications' \
  -H 'Content-Type: application/json; charset=utf-8' \
  -H 'Authorization: Key YOUR_APP_API_KEY' \
  -d '{
    "app_id": "YOUR_APP_ID",
    "target_channel": "push",
    "name": "Testing basic setup",
    "headings": { "en": "👋" },
    "contents": {"en": "Hello world!"},
    "included_segments": ["Test Users"],
    "big_picture": "https://avatars.githubusercontent.com/u/11823027?s=200&v=4"
  }'
```

<Frame caption="折叠通知视图中图片会显示较小。展开通知可查看完整图片。">
  <img src="https://mintcdn.com/onesignal/Z6xkXGfmy814If53/images/docs/e4e3e812eb6841ff11795a6ee0ea36eff483920ea9266733d6948ed34df3def3-Untitled_design_9.png?fit=max&auto=format&n=Z6xkXGfmy814If53&q=85&s=9bf6f4a73e38ec424b8cfec75a474a26" alt="推送通知中的图片在折叠通知视图中显示较小。展开通知可查看完整图片。" width="1200" height="800" data-path="images/docs/e4e3e812eb6841ff11795a6ee0ea36eff483920ea9266733d6948ed34df3def3-Untitled_design_9.png" />
</Frame>

<Frame caption="显示确认送达的投递统计（免费计划不可用）">
  <img src="https://mintcdn.com/onesignal/r7d-mmGxYBGknd0e/images/dashboard/delivery-stats-confirmed-delivery.png?fit=max&auto=format&n=r7d-mmGxYBGknd0e&q=85&s=9949b389aec0cc2e08fc338eaad941de" alt="显示确认送达的投递统计（免费计划不可用）。" width="2444" height="1462" data-path="images/dashboard/delivery-stats-confirmed-delivery.png" />
</Frame>

<Check>
  验证测试设备收到了包含以下内容的通知：

  * 您的自定义图标（如已配置）
  * 展开时的大图
  * Dashboard > **Delivery > Sent Messages** 显示 "Confirmed" 状态（免费计划不可用）。
</Check>

<Warning>
  * 未收到通知？请参阅[移动推送未显示](./notifications-show-successful-but-are-not-being-shown)。
  * 没有自定义图标？请验证图标名称为 `onesignal_small_icon_default` 且位于正确的 drawable 文件夹中。
  * 遇到问题？请将 API 请求和从应用启动到结束的日志复制粘贴到 `.txt` 文件中，然后将两者发送至 `support@onesignal.com`。
</Warning>

#### 测试应用内消息

1. 关闭应用 30 秒以上
2. Dashboard > **Messages > In-App > New In-App** > 选择 **Welcome** 模板
3. 受众：**Test Users** 细分
4. 触发器：**On app open**
5. 计划：**Every time trigger conditions are satisfied**
6. 点击 **Make Message Live**
7. 打开应用

<Frame caption="使用应用内消息定向 'Test Users' 细分">
  <img src="https://mintcdn.com/onesignal/mJXnj6xKtiaVBd7y/images/dashboard/targeting-test-users-segment-with-in-app-message.png?fit=max&auto=format&n=mJXnj6xKtiaVBd7y&q=85&s=4f2e70263b932745cf929bad9030c819" alt="使用应用内消息定向 'Test Users' 细分。" width="2444" height="712" data-path="images/dashboard/targeting-test-users-segment-with-in-app-message.png" />
</Frame>

<Frame caption="应用内 Welcome 消息的自定义示例">
  <img src="https://mintcdn.com/onesignal/r7d-mmGxYBGknd0e/images/dashboard/example-customization-of-in-app-welcome-message.png?fit=max&auto=format&n=r7d-mmGxYBGknd0e&q=85&s=3decc127e575020980828a95eb7f96ce" alt="应用内 Welcome 消息的自定义示例。" width="2440" height="1488" data-path="images/dashboard/example-customization-of-in-app-welcome-message.png" />
</Frame>

<Frame caption="应用内消息调度选项">
  <img src="https://mintcdn.com/onesignal/r7d-mmGxYBGknd0e/images/dashboard/in-app-message-scheduling-options.png?fit=max&auto=format&n=r7d-mmGxYBGknd0e&q=85&s=d7a46112e5ac3e12bc83b4f8e408159e" alt="应用内消息调度选项。" width="2440" height="1074" data-path="images/dashboard/in-app-message-scheduling-options.png" />
</Frame>

<Frame caption="设备上显示的 Welcome 应用内消息">
  <img src="https://mintcdn.com/onesignal/RWtLFPeffHrC81wI/images/docs/a7ed4bb02be56900a65d2519e3d69f9c9b2c2a1c65fe740f07789e4ffe79cd67-Untitled_design_10.png?fit=max&auto=format&n=RWtLFPeffHrC81wI&q=85&s=6f692b569706ca39df0b4cc2b70f3de2" alt="设备上显示的 Welcome 应用内消息。" width="1920" height="1080" data-path="images/docs/a7ed4bb02be56900a65d2519e3d69f9c9b2c2a1c65fe740f07789e4ffe79cd67-Untitled_design_10.png" />
</Frame>

<Check>
  验证测试设备收到了应用内消息。有关更多详情，请参阅[应用内消息设置](./in-app-messages-setup)指南。
</Check>

<Warning>
  未看到消息？

  * 开始新会话
    * 您必须关闭或将应用置于后台至少 30 秒后再重新打开。这确保启动新的会话。
    * 有关更多信息，请参阅[应用内消息的显示方式](./in-app-messages-setup#how-are-iams-displayed%3F)。
  * 仍在 `Test Users` 细分中？
    * 如果您重新安装或切换了设备，请将设备重新添加到[测试订阅](./test-users)并确认它属于 Test Users 细分。
  * 遇到问题？
    * 在重现上述步骤时按照[获取调试日志](./capturing-a-debug-log)的说明操作。这将生成额外的日志信息，您可以将其分享至 `support@onesignal.com`，我们将帮助调查问题所在。
</Warning>

<Check>
  您已成功设置 OneSignal SDK 并学习了以下重要概念：

  * 收集[订阅](./subscriptions)，设置[测试订阅](./test-users)，以及创建[细分](./segmentation)。
  * 使用细分和我们的[创建消息](/reference/create-message) API 发送带图片的[推送通知](./push)。
  * 发送[应用内消息](./in-app-messages-setup)。

  继续阅读本指南以在您的应用中识别用户并设置其他功能。
</Check>

### 常见错误和修复

| 错误 / 症状                              | 原因                     | 修复方法                                                       |
| ------------------------------------ | ---------------------- | ---------------------------------------------------------- |
| `Cannot resolve symbol 'OneSignal'`  | 未添加 SDK 依赖或未同步 Gradle  | 将依赖添加到 build.gradle 并同步项目                                  |
| `Application class not found`        | Application 类未在清单中注册   | 在 `<application>` 标签中添加 `android:name=".ApplicationClass"` |
| `Google Play Services not available` | 模拟器/设备缺少 Play Services | 使用带有 Play Store 的设备或带有 Google APIs 的模拟器                    |
| 收到推送但显示默认 Android 图标                 | 自定义图标未配置或名称错误          | 创建名为 `onesignal_small_icon_default` 的通知图标资源                |
| 未收到推送通知                              | FCM 未在 OneSignal 中配置   | 完成步骤 0：在 OneSignal 控制面板中配置 FCM 凭据                          |
| 应用内消息不显示                             | 会话未启动或网络问题             | 关闭应用 30 秒以上，重新打开，检查网络连接                                    |
| `Manifest merger failed`             | 清单属性冲突                 | 检查是否有重复的应用名称或权限冲突                                          |
| 电池优化阻止通知                             | 设备电源管理                 | 引导用户为您的应用禁用电池优化                                            |
| 无法诊断问题                               | 日志信息不足                 | 添加详细日志并检查 logcat 输出中的错误                                    |

***

## 用户管理

之前，我们演示了如何创建移动[订阅](./subscriptions)。现在我们将扩展到使用 OneSignal SDK 通过所有订阅（包括推送、邮件和短信）来识别[用户](./users)。

### 分配 External ID（推荐）

使用 External ID 通过后端的用户标识符在设备、邮箱地址和电话号码之间一致地识别用户。这确保您的消息在渠道和第三方系统之间保持统一。有关更多详情和 Java 代码示例，请参阅我们的[移动 SDK 参考](./mobile-sdk-reference)。

```kotlin Kotlin theme={null}
// Call when user logs in or is identified, safe to call multiple times
// Typically used in a login completion handler, or on app launch if already authenticated
fun onUserAuthenticated(userId: String) {
    OneSignal.login(userId)
}

// If you want to remove the External ID from the Subscription, setting it to an anonymous user
fun onUserLoggedOut() {
    OneSignal.logout()
}
```

<Note>
  OneSignal 为订阅（Subscription ID）和用户（OneSignal ID）生成唯一的只读 ID。

  强烈建议通过我们的 SDK 设置 External ID，以便在所有订阅中识别用户，无论它们是如何创建的。

  在 SDK 参考指南中了解更多关于 [`login` 方法](./mobile-sdk-reference#login-external-id)的信息。
</Note>

### 添加标签和自定义事件

标签和自定义事件都是向用户添加数据的方式。标签是 `key-value` 字符串，通常与用户属性相关联（如 `username`、`role` 或 `status`），而自定义事件具有 JSON 格式，通常与操作相关联（如 `new_purchase`、`abandoned_cart` 及相关属性）。两者都可用于驱动高级[消息个性化](./message-personalization)和 Journeys。有关更多详情和 Java 代码示例，请参阅我们的[移动 SDK 参考](./mobile-sdk-reference)。

```kotlin Kotlin theme={null}
// Add a tag when the user's name is set
OneSignal.User.addTag("username", "john_doe")

// Create a custom event when user abandoned a cart
val properties = mapOf(
    "product_id" to "123456",
    "product_name" to "Product Name",
    "product_price" to 100,
    "product_quantity" to 1
)
OneSignal.User.trackEvent("abandoned_cart", properties)
```

<Note>
  有关如何使用标签和自定义事件的更多详情，请参阅[标签](./add-user-data-tags)和[自定义事件](./custom-events)指南。
</Note>

### 添加邮件和/或短信订阅

除了推送通知外，您还可以通过邮件和短信渠道联系用户。如果邮箱地址和/或电话号码已存在于 OneSignal 应用中，SDK 会将其添加到现有用户 — 不会创建重复项。有关更多详情和 Java 代码示例，请参阅我们的[移动 SDK 参考](./mobile-sdk-reference)。

```kotlin Kotlin theme={null}
// Add email subscription
// Call when user provides their email (e.g., account creation, settings update) after calling OneSignal.login("user_id")
OneSignal.User.addEmail("user@example.com")

// Add SMS subscription
// Use E.164 format: + country code + number
// Call when user provides their phone number (e.g., account creation, settings update) after calling OneSignal.login("user_id")
OneSignal.User.addSms("+15551234567")
```

<Frame caption="通过 External ID 统一推送、邮件和短信订阅的用户资料">
  <img src="https://mintcdn.com/onesignal/mJXnj6xKtiaVBd7y/images/dashboard/user-profile-with-push-email-and-sms-subscriptions-unified-by-external-id.png?fit=max&auto=format&n=mJXnj6xKtiaVBd7y&q=85&s=3e7d5ed8763acb24e0afa5c4ff8f0d81" alt="通过 External ID 统一推送、邮件和短信订阅的用户资料。" width="2440" height="1392" data-path="images/dashboard/user-profile-with-push-email-and-sms-subscriptions-unified-by-external-id.png" />
</Frame>

<Note>
  多渠道通信最佳实践

  * 在添加邮件或短信订阅之前获取明确同意。
  * 向用户说明每个通信渠道的好处。
  * 提供渠道偏好设置，让用户选择他们偏好的渠道。
</Note>

***

### 隐私和用户同意

要控制 OneSignal 何时收集用户数据，请使用 SDK 的同意管理方法。有关更多详情和 Java 代码示例，请参阅我们的[移动 SDK 参考](./mobile-sdk-reference)。

```kotlin Kotlin theme={null}
// In ApplicationClass onCreate(), BEFORE OneSignal.initWithContext()
// Use this if your app requires GDPR or other privacy consent before data collection
OneSignal.consentRequired = true

// Later, after user grants consent (e.g., taps "I Agree" on your consent screen)
OneSignal.consentGiven = true
```

<Note>
  有关更多信息，请参阅我们的隐私和安全文档：

  * [SDK 收集的数据](./data-collected-by-the-onesignal-sdk)
  * [处理个人数据](./handling-personal-data)
</Note>

***

## 推送权限提示

不要在应用打开时立即调用 `requestPermission()`，而是采取更具策略性的方法。使用应用内消息在请求权限之前向用户说明推送通知的价值。

有关最佳实践和实现详情，请参阅我们的[推送权限提示](./prompt-for-push-permissions)指南。

***

## 监听推送、用户和应用内事件

使用 SDK 监听器来响应用户操作和状态变化。在 `OneSignal.initWithContext()` 之后将这些添加到您的 Application 类中。

### 推送通知事件

```kotlin Kotlin theme={null}
// Add click listener to handle when users tap notifications
val clickListener = object : INotificationClickListener {
  override fun onClick(event: INotificationClickEvent) {
    Log.d("OneSignal", "Notification clicked: ${event.notification.title}")
  }
}
OneSignal.Notifications.addClickListener(clickListener)
```

### 用户状态变化

示例展示了如何使用推送订阅观察者。其他用户状态事件，如用户状态观察者和通知权限观察者，可在[移动 SDK 参考](./mobile-sdk-reference)中找到。

```kotlin Kotlin theme={null}
// Add subscription observer to track push subscription changes
class MyObserver : IPushSubscriptionObserver {
  init {
    OneSignal.User.pushSubscription.addObserver(this)
  }

  override fun onPushSubscriptionChange(state: PushSubscriptionChangedState) {
    if (state.current.optedIn) {
      println("User is now opted-in with push token: ${state.current.token}")
    }
  }
}
```

### 应用内消息事件

其他应用内消息方法可在[移动 SDK 参考](./mobile-sdk-reference)中找到。

```kotlin Kotlin theme={null}
// Add click listener for in-app message interactions
val clickListener = object : IInAppMessageClickListener {
  override fun onClick(event: IInAppMessageClickEvent) {
    print(event.result.actionId)
  }
}
OneSignal.InAppMessages.addClickListener(clickListener)
```

***

## 高级设置和功能

### Android 特定功能

* **[通知渠道](./mobile-sdk-reference#notification-channels)** — 将通知组织到不同类别（Android 8.0+）
* **[服务扩展](./service-extensions)** — 高级通知自定义
* **[华为/HMS 支持](./huawei-sdk-setup)** — Google Play Services 的替代方案

### 通用功能

* [深度链接](./deep-linking) — 从通知将用户导航到特定页面
* [操作按钮](./action-buttons) — 为通知添加交互按钮
* [身份验证](./identity-verification) — 安全的用户身份识别
* [位置追踪](./mobile-sdk-reference#location) — 基于位置的定向
* [集成](./integrations) — 与分析和数据平台连接
* [多语言消息](./multi-language-messaging) — 本地化通知

有关完整的 SDK 方法文档，请访问[移动 SDK 参考](./mobile-sdk-reference)。

***

<Info>
  需要帮助？

  与我们的支持团队聊天或发送邮件至 `support@onesignal.com`

  请包含以下信息：

  * 您遇到的问题详情以及复现步骤（如有）
  * 您的 OneSignal 应用 ID
  * 外部 ID 或订阅 ID（如适用）
  * 您在 OneSignal 控制台中测试的消息 URL（如适用）
  * 任何相关的[日志或错误信息](/docs/cn/capturing-a-debug-log)

  我们很乐意为您提供帮助！
</Info>

***
