# 适用于 Android 的奖励广告服务集成

> 通过实现 LevelPlayRewardedAdListener、初始化和检查广告可用性、显示包含广告位的广告服务、在完成时奖励用户以及使用 LevelPlay Integration Helper 验证设置来集成 LevelPlay SDK 的奖励广告单元。

Unity LevelPlay Rewarded 是一个全屏广告单元，通常在 app 生命周期中的自然过渡点投放。 

> **Note:**
>
> 本文档与 SDK 8.5.0+ 相关。

## 先决条件##prerequisites

* 确保已将 LevelPlay SDK 正确集成到应用程序中。[此处](/grow/levelplay/sdk/android/sdk-integration.md)概述了集成。
* 确保使用 LevelPlay Initialization API 初始化 SDK。
* 在 LevelPlay 后台中找到 AdUnitID。

## 创建奖励广告对象##create-rewarded-ad-object

必须在收到 **onInitSuccess** 回调后执行奖励广告对象的创建。

该对象是可重用的实例，可以处理多个加载并在整个会话中显示。创建后，应将其用于加载和展示同一广告单元的广告服务。

对于更高级的实现，如有必要，可以创建多个奖励广告对象。

1. **Java**

   ```java
   LevelPlayRewardedAd mRewardedAd = new LevelPlayRewardedAd("adUnitId");
   ```

2. **Kotlin**

   ```kotlin
   val mRewardedAd = LevelPlayRewardedAd("adUnitId")
   ```

## 设置奖励监听器##set-rewarded-listener

在代码中实现 **LevelPlayRewardedAdListener** 以获取广告投放信息。 

* 建议在加载奖励广告之前设置监听器。
* 每个奖励广告都应有自己的监听器实现。
* 回调在主线程上运行。

1. **Java**

   ```java
   // 创建奖励广告对象
   LevelPlayRewardedAd mRewardedAd = new LevelPlayRewardedAd("adUnitId");
   mRewardedAd.setListener(new LevelPlayRewardedAdListener() { }
   @Override
   public void onAdLoaded(LevelPlayAdInfo levelPlayAdInfo) {
      // 广告已成功加载
   }
   @Override
   public void onAdLoadFailed(LevelPlayAdError levelPlayAdError) { }
      // 广告加载失败 
   }
   @Override
   public void onAdDisplayed(LevelPlayAdInfo levelPlayAdInfo) { }
      // 广告已显示并在屏幕上可见
   }

   @Override
   public void onAdRewarded(@NonNull LevelPlayReward reward, @NonNull LevelPlayAdInfo adInfo) {
      // Ad reward received 
   }
   @Override
   public void onAdDisplayFailed(LevelPlayAdError levelPlayAdError, LevelPlayAdInfo levelPlayAdInfo) {
      // Ad fails to be displayed
      // Optional
   }
   @Override
   public void onAdClicked(LevelPlayAdInfo levelPlayAdInfo) {
      // Ad was clicked
      // Optional
   }
   @Override
   public void onAdClosed(LevelPlayAdInfo levelPlayAdInfo) {
      // Ad was closed
      // Optional
   }
   @Override
   public void onAdInfoChanged(LevelPlayAdInfo levelPlayAdInfo) {
      // Called after the ad info is updated.加载另一个奖励广告后可用，并包含更高的 CPM/速率
      // Optional
   }
   });
   ```

2. **Kotlin**

   ```kotlin
   // 创建奖励广告对象 
   val mRewardedAd = LevelPlayRewardedAd("adUnitId")
   mRewardedAd.setListener(object :LevelPlayRewardedAdListener { }
   覆盖 fun onAdLoaded(levelPlayAdInfo:LevelPlayAdInfo) {
      // 广告已成功加载
   }
   覆盖 fun onAdLoadFailed(levelPlayAdError:LevelPlayAdError) {
      // 广告加载失败
   }
   覆盖 fun onAdDisplayed(levelPlayAdInfo:LevelPlayAdInfo) {
      // 广告已显示并在屏幕上可见
   }

   覆盖 fun onAdRewarded(奖励：LevelPlayReward、adInfo：LevelPlayAdInfo) {
      // Ad reward received 
   }
   覆盖 fun onAdDisplayFailed(levelPlayAdError:LevelPlayAdError、levelPlayAdInfo：LevelPlayAdInfo) {
      // Ad fails to be displayed
      // Optional
   }
   覆盖 fun onAdClicked(levelPlayAdInfo:LevelPlayAdInfo) {
      // Ad was clicked
      // Optional
   }
   覆盖 fun onAdClosed(levelPlayAdInfo:LevelPlayAdInfo) {
      // Ad was closed
      // Optional
   }
   覆盖 fun onAdInfoChanged(levelPlayAdInfo:LevelPlayAdInfo) {
      // Called after the ad info is updated.加载另一个奖励广告后可用，并包含更高的 CPM/速率
      // Optional
   }
   })	 
   ```

### LevelPlay 广告信息##levelplay-ad-info

**LevelPlayAdInfo** 参数包含有关加载的广告的信息。

## 获取奖励广告详细信息##get-rewarded-ad-details

使用 getReward API 可以访问您在 LevelPlay 后台中设置的奖励数据。与其他聚合 API 不同，这是一个独立调用，在初始化后返回存储在 SDK 本地的数据。这使您能够构建动态、数据驱动的 UI，在用户参与广告之前告知他们潜在的奖励，从而无需在app中硬编码奖励值。

### 先决条件##prerequisites

在实现 getReward API 之前，请确保项目满足以下技术要求：

* **SDK 初始化**：调用 initSDK 并等待 onInitializationSuccess 回调以确保奖励数据已缓存。
* **广告对象实例**：在调用 API 之前，使用有效的 Ad Unit ID 实例化奖励广告对象。
* **最低 SDK 版本**：使用 LevelPlay SDK 8.1.0 或更高版本（原生或 Unity 软件包）。

### 最佳实践##best-practices

遵循这些建议可确保稳定且可预测的集成。

* **初始化成功时调用**：调用 getReward 的最佳时间是初始化成功监听器器内部。这样可以确保 UI 在用户进入屏幕时就绪。
* **检查空状态**：在更新 UI 之前，请始终验证该数量> 0。如果在初始化期间发生网络报错，这将确保平滑的用户体验。
* **放置/位置精度**：确保在 getReward("placementName") 中使用的字符串与 LevelPlay 后台中定义的名称完全匹配。

### API 结构##api-structure

getReward 方法允许您从 LevelPlay 后台访问同步的奖励数据。使用此方法可以查询本地 SDK 缓存中指定的广告放置/位置或全局广告单元默认值。

#### getReward##getreward

```java
public LevelPlayReward getReward(String placementName)
```

获取指定的广告放置/位置或默认广告单元的奖励名称和金额。没有其他参数可以使用。

| 参数            | 描述                                                    |
| ------------- | ----------------------------------------------------- |
| placementName | 在 LevelPlay 后台中定义的放置/位置的唯一标识符。通道`null`，用于获取广告单元的默认奖励。 |

返回一个 LevelPlayReward 对象，其中包含名称（字符串）和金额（int）。

### 初始设置##initial-setup

getReward API 充当 LevelPlay SDK 的核心组件，在如下逻辑下运行以确保数据无延迟可用：

* **集成功能**：由于奖励数据是在初始 SDK 设置期间获取的，因此 API 调用是即时的，不需要网络请求。
* **编辑器配置**：将 app 与 LevelPlay SDK 集成后，API 可以立即使用。测试此功能不需要额外的资源或插件。

### 了解奖励选择逻辑##understand-reward-selection-logic

API 根据指定的层级视图返回 LevelPlayReward 对象。了解此逻辑有助于排除出现指定的奖励的原因。

* **放置/位置级别**：如果在调用中提供了有效的广告放置/位置称，SDK 将返回控制面板中为该广告位放置/位置的指定的奖励。
* **广告单元级别**：如果广告放置/位置名称为 null 或未找到，SDK 将回退到为广告单元定义的默认奖励。
* **回退状态**：如果在初始化完成之前调用 API，则返回一个字符串名称为空且值为 0 的奖励对象。

### 动态更新 UI##update-your-ui-dynamically

使用 getReward API 可将静态按钮变换为高意图的行动调用。例如：您可以显示“Watch to earn 50 Gold”，而不是通用的“Watch Video”按钮。

* **有效金额**：在更新 UI 组件之前，请务必验证 reward.amount > 0。
* **事件驱动更新**：在初始化成功监听器器中调用 API 以确保 UI 在用户进入屏幕时准确无误。
* **区分大小写**：确保代码中的放置/位置名称字符串与 LevelPlay 后台完全匹配；不匹配的字符串将触发器广告单元回退。

### 获取奖励数据示例##retrieve-reward-data-examples

以下示例展示了如何调用 Android 奖励 API：

1. **Kotlin**

   ```kotlin
   /** 
    * 获取与广告关联的奖励。
    * 使用此方法可获得为广告单元或放置/位置配置的奖励。的 
    * 当有效的放置/位置名称时，指定的放置/位置奖励优先于广告单元奖励 
    * 提供。
    * @param放置/位置 要获取奖励的放置/位置名称，或使用广告单元奖励的`null`。
    * @return [LevelPlayReward] 对象。失败时返回空奖励（`name: ""` 和 `amount: 0`）。
    */ 
   @JvmOverloads 
   fun getReward(放置/位置：字符串？ = null）：LevelPlayReward { 
       val reward = mRewardedAd.getReward(放置/位置)
       Log.d("LevelPlay", "Amount: ${reward.amount}, Name: ${reward.name}")
       返回奖励
   }
   ```

2. **Java**

   ```java
   LevelPlayReward reward = mRewardedAd.getReward("bonus_level");
   if (reward.getAmount() > 0) {
       // 授予奖励逻辑
   }
   ```

### getReward API 实现故障排除##troubleshooting-getreward-api-implementation

* **奖励金额返回 0**：如果在 onInitializationSuccess 回调之前调用 API，通常会发生这种情况。在查询奖励之前，请确保 SDK 完全准备就绪。
* **显示错误奖励类型**：检查是否有多个广告位。如果放置/位置名称拼写错误，SDK 默认认为主广告单元奖励，而不是指定的广告放置/位置奖励。

## 加载奖励广告##load-rewarded-ad

要加载奖励广告，请使用 **loadAd**。

1. **Java**

   ```java
   mRewardedAd.loadAd();
   ```

2. **Kotlin**

   ```kotlin
   mRewardedAd.loadAd()	 
   ```

## 显示奖励广告##show-rewarded-ad

使用 **LevelPlayRewardedAdListener** API 在收到 **onAdLoaded** 回调后显示奖励广告。

* 共享 **Activity** 是必需的。 
* 如果使用放置，请在 **showAd** API 中通道放置/位置名称，如下文 Placements 部分所示。
* 广告成功展示给用户后，可以通过重复加载步骤加载另一个广告。 

1. **Java**

   ```java
   public void showRewardedAd() {
   // 检查广告是否已准备就绪
   if (mRewardedAd.isAdReady()) {
      // 显示广告 
      mRewardedAd.showAd(this);
   }
   }	
   ```

2. **Kotlin**

   ```kotlin
   fun showRewardedAd() {
   // 检查广告是否已准备就绪
   if (mRewardedAd.isAdReady()) {
      // 显示广告
      mRewardedAd.showAd(this)
   }
   }	 
   ```

### 检查 Ad is Ready##check-ad-is-ready

为了避免展示失败，并确保广告可以正确展示，建议在调用 **showAd** API 之前使用以下 API。

**isAdReady** – 如果广告已成功加载且广告单元未设置上限，则返回 true，否则返回 false。

**isPlacementCapped** – 有效放置/位置被限制时返回 true。如果放置/位置无效或未设置上限，此 API 将返回 false。

1. **Java**

   ```java
   // 检查广告是否已准备就绪并且放置/位置未设置上限 
   if (mRewardedAd.isAdReady() &amp;&amp; !LevelPlayRewardedAd.isPlacementCapped(placementName)) {
   mRewardedAd.showAd(this, placementName);
   }	
   ```

2. **Kotlin**

   ```kotlin
   // 检查广告是否已准备就绪并且放置/位置未设置上限
   if (mRewardedAd.isAdReady() &amp;&amp; !LevelPlayRewardedAd.isPlacementCapped(placementName)) {
   mRewardedAd.showAd(this, placementName)
   }
   ```

### 广告位##placements

我们支持 LevelPlay 后台上的 Rewarded [广告位](/grow/levelplay/platform/settings/placements.md)节奏和上限。 

如果为奖励广告服务设置了放置位置，请调用 **showAd** 方法为指定的放置/位置提供广告。

1. **Java**

   ```java
   public void showRewardedAdWithPlacement() {
      // 检查广告是否已准备就绪并且放置/位置未设置上限 
      if (mRewardedAd.isAdReady() &amp;&amp; !LevelPlayRewardedAd.isPlacementCapped(placementName)) {
      // 显示带有放置/位置的广告 
      mRewardedAd.showAd(this, placementName);
   }
   }
   ```

2. **Kotlin**

   ```kotlin
   fun showRewardedAdWithPlacement(placementName：字符串) {
      // 检查广告是否已准备就绪并且放置/位置未设置上限
      if (mRewardedAd.isAdReady() &amp;&amp; !LevelPlayRewardedAd.isPlacementCapped(placementName)) {
      // 显示带有放置/位置的广告
      mRewardedAd.showAd(this, placementName)
   }
   }
   ```

### 动态 UserId##dynamic-userid

动态 UserID 是一个参数，用于验证可在整个会话中更改的 AdRewarded 交易。您将通过[服务器到服务器](/grow/levelplay/platform/settings/server-to-server-callback.md)的广告奖励回调收到此参数，必须在调用 showAd 之前设置此参数。

* 字字符串必须包含 1-64 个字母数字角色。
* 您将在回调网址中收到一个 `dynamicUserId` 参数以及奖励详细信息。

1. **Java**

   ```java
   LevelPlay.setDynamicUserId("userId");
   ```

2. **Kotlin**

   ```kotlin
   LevelPlay.setDynamicUserId("userId")
   ```

1) **Java**

   ```java
   public 类 RewardedAdActivity extends 活动实现 LevelPlayRewardedAdListener {
   私有变量 LevelPlayRewardedAd mRewardedAd;
   void createRewardedAd() {
      mRewardedAd = new LevelPlayRewardedAd("adUnitId");
      mRewardedAd.setListener(this);
   }
   void loadRewardedAd() {
      // 加载或重新加载广告
      mRewardedAd.loadAd();
   }
   void showRewardedAd() {
      if(mRewardedAd.isAdReady()) {
            mRewardedAd.showAd(this);
      }
   }
   void showRewardedAd(@NonNull 字符串 placementName) {
      // 检查广告是否已准备就绪并且放置/位置未设置上限 
      if(mRewardedAd.isAdReady() &amp;&amp; !LevelPlayRewardedAd.isPlacementCapped(placementName)) {
            mRewardedAd.showAd(this, placementName);
      }
   }
   // LevelPlayRewardedAdListener 方法
   @Override
   public void onAdLoaded(@NonNull LevelPlayAdInfo adInfo) {}
   @Override
   public void onAdLoadFailed(@NonNull LevelPlayAdError 报错) {
   @Override
   public void onAdDisplayed(@NonNull LevelPlayAdInfo adInfo) {}
   @Override
   public void onAdClosed(@NonNull LevelPlayAdInfo adInfo) {
   @Override
   public void onAdClicked(@NonNull LevelPlayAdInfo adInfo) {
   @Override
   public void onAdDisplayFailed(@NonNull LevelPlayAdError 报错, @NonNull LevelPlayAdInfo adInfo) {
   @Override
   public void onAdInfoChanged(@NonNull LevelPlayAdInfo adInfo) {
   @Override
   public void onAdRewarded(@NonNull LevelPlayReward reward, @NonNull LevelPlayAdInfo adInfo) {
   }
   ```

2) **Kotlin**

   ```kotlin
   类 RewardedAdActivity：Activity(), LevelPlayRewardedAdListener {
   私有变量 lateinit var mRewardedAd：LevelPlayRewardedAd
   fun createRewardedAd() {
      mRewardedAd = LevelPlayRewardedAd("adUnitId")
      mRewardedAd.setListener(this)
   }
   fun loadRewardedAd() {
      mRewardedAd.loadAd()
   }
   fun showRewardedAd() {
      if (mRewardedAd.isAdReady()) {
          mRewardedAd.showAd(this)
      }
   }
   fun showRewardedAd(placementName:字符串) {
      // 检查广告是否已准备就绪并且放置/位置未设置上限 
      if (mRewardedAd.isAdReady() &amp;&amp; !LevelPlayRewardedAd.isPlacementCapped(placementName)) {
          mRewardedAd.showAd(this, placementName)
      }
   }
   // LevelPlayRewardedAdListener 方法
   覆盖 fun onAdLoaded(adInfo:LevelPlayAdInfo) {}
   覆盖 fun onAdLoadFailed（报错：LevelPlayAdError) {}
   覆盖 fun onAdInfoChanged(adInfo:LevelPlayAdInfo) {}
   覆盖 fun onAdDisplayed(adInfo:LevelPlayAdInfo) {}
   覆盖 fun onAdDisplayFailed（报错：LevelPlayAdError、adInfo：LevelPlayAdInfo) {}
   覆盖 fun onAdClicked(adInfo:LevelPlayAdInfo) {}
   覆盖 fun onAdClosed(adInfo:LevelPlayAdInfo) {}
   覆盖 fun onAdRewarded(奖励：LevelPlayReward、adInfo：LevelPlayAdInfo) {}
   }
   ```

## LevelPlay Mediation 演示应用程序##levelplay-mediation-demo-app

Integration Demo 应用程序演示如何在 app 中集成奖励广告单元 API。

[下载 Android Demo 应用程序](https://github.com/ironsource-mobile/Mediation-Demo-Apps)

验证您与我们的[集成测试套件](/grow/levelplay/sdk/unity/integration-test-suite.md)的集成。

## 后续步骤##next-steps

请遵循我们的集成指南来集成其他奖励广告网络或配置其他广告格式：

* [添加聚合网络](/grow/levelplay/sdk/android/mediation-networks.md)
* [插页式广告服务](/grow/levelplay/sdk/android/interstitial-integration.md)
* [横幅广告服务](/grow/levelplay/sdk/android/banner-integration.md)
* [原生广告服务](/grow/levelplay/sdk/android/native-ads-integration.md)
