Нативная реклама

Нативная реклама — реклама, внешний вид которой может определяться на стороне приложения. Данная особенность позволяет изменять визуальный стиль объявлений и места их размещения с учетом особенностей дизайна приложения.

Нативные объявления улучшают впечатления от рекламы, поэтому вы можете показывать больше объявлений, не теряя интерес пользователей. Это позволяет обеспечить максимальный доход от рекламы в долгосрочной перспективе.

Отрисовка рекламы производится нативными средствами платформы, что увеличивает её производительность и качество.

Это руководство покажет, как интегрировать нативную рекламу в Android‐приложение. В дополнение к примерам кода и инструкции оно содержит рекомендации по использованию данного формата рекламы, а также ссылки на дополнительные ресурсы.

Дополнительно об интеграции нативной рекламы смотрите в видео:

Пререквизит

  1. Выполните шаги по интеграции sdk, описанные в Быстром старте.
  2. Заранее проинициализируйте рекламный SDK.
  3. Убедитесь, что используете самую актуальную версию Yandex Mobile Ads SDK, а в случае использовании медиации — наиболее свежую версию единой сборки.

Имплементация

Основные шаги по интеграции нативной рекламы:

  • Создать и настроить загрузчик рекламы NativeAdLoader.
  • Зарегистрировать слушатель событий загрузчика объявлений.
  • Загрузить рекламу.
  • Отобразить загруженное объявление.

Особенности подключения нативной рекламы

  1. Все вызовы методов Yandex Mobile Ads SDK необходимо выполнять из главного потока.

  2. Если вы получили ошибку в коллбэке onAdFailedToLoad(), не пытайтесь загрузить новое объявление снова. Если всё же необходимо это сделать, ограничьте число повторных попыток загрузки рекламы. Это поможет избежать постоянных неудачных запросов и проблем с подключением в случае ограничений.

  3. Рекомендуется держать сильную ссылку на рекламу и ее загрузчик на всем протяжении жизни экрана, в рамках которого происходит взаимодействие с рекламой.

  4. Размер рекламного контейнера рекомендуется рассчитывать исходя из содержимого объявления. После окончания загрузки рекламы, все ее компоненты необходимо отобразить. Список доступных в объявлении компонентов можно получить из объекта рекламы NativeAd.

  5. Объявления с видео, как правило, показывают лучший результат. Для отображения рекламы с видео необходимо чтобы размер рекламного контейнера и компонента MediaView были не меньше 300x160 dp (density-independent pixels).

  6. Рекомендуется использовать макет, который включает весь набор возможных компонентов. Как показывает практика, макеты, включающие весь набор компонентов, приводит к лучшим конверсиям.

Загрузка рекламы

Для загрузки нативной рекламы необходимо создать объект NativeAdLoader.

Параметры запроса за рекламой настраиваются через объект класса NativeAdRequestConfiguration.Builder. В качестве параметров запроса можно передать идентификатор рекламного блока, способ загрузки изображений, возраст, гендерные признаки и другие данные, способные улучшить качество подбора рекламы. Подробнее читайте в разделе Таргетирование рекламы.

Для получения уведомлений о результате загрузки объявлений, создайте экземпляр NativeAdLoadListener и установите его в качестве слушателя событий загрузчика рекламных объявлений.

Для загрузки рекламы вызовите метод loadAd().

В примере ниже показано как загрузить нативную рекламу из Activity:

class CustomNativeAdActivity : AppCompatActivity(R.layout.activity_custom_native_ad) {

  private val nativeAdView get() = binding.nativeAd.root

  private var nativeAdLoader: NativeAdLoader? = null

  private lateinit var binding: ActivityCustomNativeAdBinding

  override fun onCreate(savedInstanceState: Bundle?) {
      super.onCreate(savedInstanceState)
      binding = ActivityCustomNativeAdBinding.inflate(layoutInflater)
      setContentView(binding.root)

      nativeAdLoader = createNativeAdLoader()
      nativeAdLoader?.loadAd(
          // Methods in the NativeAdRequestConfiguration.Builder class can be used here to specify individual options settings.
          NativeAdRequestConfiguration.Builder("your-ad-unit-id").build())
  }

  private fun createNativeAdLoader(): NativeAdLoader {
      return nativeAdLoader ?: NativeAdLoader(this).apply {
          setNativeAdLoadListener(object : NativeAdLoadListener {
              override fun onAdLoaded(p0: NativeAd) {
                  // The ad was loaded successfully. Now you can show loaded ad.
              }

              override fun onAdFailedToLoad(p0: AdRequestError) {
                  // Ad failed to load with AdRequestError.
                  // Attempting to load a new ad from the onAdFailedToLoad() method is strongly discouraged.
              }
          })
      }
  }
}
class CustomNativeAdActivity extends AppCompatActivity {
  private NativeAdView mNativeAdView = mBinding.nativeAd.getRoot();

  @Nullable private NativeAdLoader mNativeAdLoader = null;

  private ActivityCustomNativeAdBinding mBinding;

  @Override
  public void onCreate(@Nullable Bundle savedInstanceState) {
      super.onCreate(savedInstanceState);
      mBinding = ActivityCustomNativeAdBinding.inflate(getLayoutInflater());
      setContentView(mBinding.getRoot());

      mNativeAdLoader = createNativeAdLoader();
      if (mNativeAdLoader != null) {
          // Methods in the NativeAdRequestConfiguration.Builder class can be used here to specify individual options settings.
          mNativeAdLoader.loadAd(
                  new NativeAdRequestConfiguration.Builder("your-ad-unit-id").build()
          );
      }
  }

  private NativeAdLoader createNativeAdLoader() {
      if (mNativeAdLoader != null) {
          return mNativeAdLoader;
      }

      final NativeAdLoader newNativeAdLoader = new NativeAdLoader(this);
      newNativeAdLoader.setNativeAdLoadListener(new NativeAdLoadListener() {
          @Override
          public void onAdLoaded(@NonNull final NativeAd nativeAd) {
              // The ad was loaded successfully. Now you can show loaded ad.
          }

          @Override
          public void onAdFailedToLoad(@NonNull final AdRequestError error) {
              // Ad failed to load with AdRequestError.
              // Attempting to load a new ad from the onAdFailedToLoad() method is strongly discouraged.
          }
      });
      return newNativeAdLoader;
  }
}

Показ рекламных объявлений

После окончания загрузки рекламы, все ее компоненты необходимо отобразить. Список доступных в объявлении компонентов можно получить из объекта рекламы NativeAd.

Существует два способа настройки внешнего оформления рекламы:

  • Оформление с помощью шаблона.
  • Ручная настройка внешнего оформления нативной рекламы.

Оформление с помощью шаблона

Использование стандартного шаблона оформления — самый простой способ работы с нативной рекламой, который требует всего нескольких строк кода в базовом варианте.

В шаблоне уже добавлен весь набор необходимых рекламных компонентов и настроено их расположение относительно друг друга. Шаблон работает с любым поддерживаемым типом нативной рекламы.

Пример кода
private fun showAd(nativeAd: NativeAd) {
   nativeAd.setNativeAdEventListener(NativeAdEventLogger())
   binding.nativeBanner.setAd(nativeAd)
}

private inner class NativeAdEventLogger : NativeAdEventListener {
    override fun onAdClicked() {
       // Called when a click is recorded for an ad.
    }

    override fun onLeftApplication() {
        // Called when user is about to leave application (e.g., to go to the browser), as a result of clicking on the ad.
    }

    override fun onReturnedToApplication() {
        // Called when user returned to application after click.
    }

    override fun onImpression(data: ImpressionData?) {
        // Called when an impression is recorded for an ad.
    }
}
private void showAd(@NonNull final NativeAd nativeAd) {
    nativeAd.setNativeAdEventListener(new NativeAdEventLogger());
    mBinding.nativeBanner.setAd(nativeAd);
}

private static class NativeAdEventLogger implements NativeAdEventListener {
    @Override
    public void onAdClicked() {
        // Called when a click is recorded for an ad.
    }

    @Override
    public void onLeftApplication() {
        // Called when user is about to leave application (e.g., to go to the browser), as a result of clicking on the ad.
    }

    @Override
    public void onReturnedToApplication() {
        // Called when user returned to application after click.
    }

    @Override
    public void onImpression(@Nullable ImpressionData impressionData) {
        // Called when an impression is recorded for an ad.
    }
}

Шаблон нативной рекламы можно кастомизировать. Подробнее об этом в статье Настройка внешнего оформления с помощью шаблона.

Ручная настройка внешнего оформления нативной рекламы

Ручная настройка внешнего оформления нативной рекламы используется в тех случаях, когда возможностей настройки шаблона недостаточно для получения желаемого результата.

Данный способ позволяет самостоятельно сверстать макет нативной рекламы, определить расположение компонентов рекламы относительно друг друга. В объявлении могут присутствовать как обязательные, так и опциональные для показа компоненты. Полный их перечень можно найти в разделе Компоненты нативной рекламы.

Совет

Рекомендуется использовать макет, который включает весь набор возможных компонентов. Как показывает практика, макет, включающий весь набор компонентов, приводит к лучшим конверсиям.

Для каждого компонента рекламного объявления предоставьте View через экземпляр класса NativeAdViewBinder.Builder. Класс принимает в качестве аргумента контейнер NativeAdView. Все компоненты рекламы должны быть определены как subview данного контейнера.

Сформированный макет рекламного объявления необходимо связать с объектом нативной рекламы NativeAd.

Пример кода
private fun showAd(nativeAd: NativeAd) {
    val nativeAdViewBinder = binding.nativeAd.run {
        NativeAdViewBinder.Builder(nativeAdView)
            .setAgeView(age)
            .setBodyView(body)
            .setCallToActionView(callToAction)
            .setDomainView(domain)
            .setFaviconView(favicon)
            .setFeedbackView(feedback)
            .setIconView(icon)
            .setMediaView(media)
            .setPriceView(price)
            .setRatingView(rating)
            .setReviewCountView(reviewCount)
            .setSponsoredView(sponsored)
            .setTitleView(title)
            .setWarningView(warning)
            .build()
    }

    try {
        nativeAd.bindNativeAd(nativeAdViewBinder)
        nativeAd.setNativeAdEventListener(NativeAdEventLogger())
    } catch (exception: NativeAdException) {
        Logger.error(exception.message.orEmpty())
    }
}

private inner class NativeAdEventLogger : NativeAdEventListener {

    override fun onAdClicked() {
        // Called when a click is recorded for an ad.
    }

    override fun onLeftApplication() {
        // Called when user is about to leave application (e.g., to go to the browser), as a result of clicking on the ad.
    }

    override fun onReturnedToApplication() {
        // Called when user returned to application after click.
    }

    override fun onImpression(data: ImpressionData?) {
        // Called when an impression is recorded for an ad.
    }
}
private void showAd(@NonNull final NativeAd nativeAd) {
    final NativeAdViewBinder nativeAdViewBinder = new NativeAdViewBinder.Builder(mNativeAdView)
            .setAgeView(age)
            .setBodyView(body)
            .setCallToActionView(callToAction)
            .setDomainView(domain)
            .setFaviconView(favicon)
            .setFeedbackView(feedback)
            .setIconView(icon)
            .setMediaView(media)
            .setPriceView(price)
            .setRatingView(rating)
            .setReviewCountView(reviewCount)
            .setSponsoredView(sponsored)
            .setTitleView(title)
            .setWarningView(warning)
            .build();
    try {
        nativeAd.bindNativeAd(nativeAdViewBinder);
        nativeAd.setNativeAdEventListener(new CustomNativeAdActivity.NativeAdEventLogger());
    } catch (final NativeAdException exception) {
        Log.e("TAG", exception.getMessage());
    }
}

private class NativeAdEventLogger implements NativeAdEventListener {
    @Override
    public void onAdClicked() {
        // Called when a click is recorded for an ad.
    }

    @Override
    public void onLeftApplication() {
        // Called when user is about to leave application (e.g., to go to the browser), as a result of clicking on the ad.
    }

    @Override
    public void onReturnedToApplication() {
        // Called when user returned to application after click.
    }

    @Override
    public void onImpression(@Nullable ImpressionData data) {
        // Called when an impression is recorded for an ad.
    }
}

Загрузка нескольких рекламных объявлений

Yandex Mobile Ads SDK предоставляет возможность загрузки нескольких рекламных объявлений одним запросом (до девяти объявлений).

Для балкового запроса за рекламой воспользуйтесь экземпляром класса NativeBulkAdLoader. Экземпляр класса принимает в методе loadAds аргумент count, определяющий желаемое количество объявлений за один запрос.

Пример кода
class NativeBulkAdLoaderActivity : AppCompatActivity(R.layout.activity_custom_native_ad) {

    private val nativeAdView get() = binding.nativeAd.root

    private var nativeAdsLoader: NativeBulkAdLoader? = null

    private lateinit var binding: ActivityCustomNativeAdBinding

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        binding = ActivityCustomNativeAdBinding.inflate(layoutInflater)
        setContentView(binding.root)

        nativeAdsLoader = createNativeBulkAdLoader()
        // Methods in the NativeAdRequestConfiguration.Builder class can be used here to specify individual options settings.
        val adRequestConfiguration = NativeAdRequestConfiguration.Builder("your-ad-unit-id").build()
        nativeAdsLoader?.loadAds(adRequestConfiguration, 3)
    }

    private fun createNativeBulkAdLoader(): NativeBulkAdLoader {
        return nativeAdsLoader ?: NativeBulkAdLoader(this).apply {
            setNativeBulkAdLoadListener(object : NativeBulkAdLoadListener {
                override fun onAdsLoaded(p0: MutableList<NativeAd>) {
                    // The ads was loaded successfully. Now you can show loaded ads.
                    for (nativeAd in p0) {
                        showAd(nativeAd)
                    }
                }

                override fun onAdsFailedToLoad(p0: AdRequestError) {
                    // Ad failed to load with AdRequestError.
                    // Attempting to load a new ads from the onAdFailedToLoad() method is strongly discouraged.
                }
            })
        }
    }
}
class CustomBulkNativeAdActivity extends AppCompatActivity {
    private NativeAdView mNativeAdView = mBinding.nativeAd.getRoot();

    @Nullable private NativeBulkAdLoader mNativeAdsLoader = null;

    private ActivityCustomNativeAdBinding mBinding;

    @Override
    public void onCreate(@Nullable Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        mBinding = ActivityCustomNativeAdBinding.inflate(getLayoutInflater());
        setContentView(mBinding.getRoot());

        mNativeAdsLoader = createNativeBulkAdLoader();
        if (mNativeAdsLoader != null) {
            // Methods in the NativeAdRequestConfiguration.Builder class can be used here to specify individual options settings.
            mNativeAdsLoader.loadAds(
                    new NativeAdRequestConfiguration.Builder("your-ad-unit-id").build();
            );
        }
    }

    private NativeBulkAdLoader createNativeBulkAdLoader() {
        if (mNativeAdsLoader != null) {
            return mNativeAdsLoader;
        }

        final NativeBulkAdLoader newNativeBulkAdLoader = new NativeBulkAdLoader(this);

        newNativeBulkAdLoader.setNativeBulkAdLoadListener(new NativeBulkAdLoadListener() {
            @Override
            public void onAdsLoaded(@NonNull final List<NativeAd> list) {
                // The ad was loaded successfully. Now you can show loaded ad.
            }

            @Override
            public void onAdsFailedToLoad(@NonNull final AdRequestError error) {
                // Ad failed to load with AdRequestError.
                // Attempting to load a new ad from the onAdFailedToLoad() method is strongly discouraged.
            }
        });
        return newNativeBulkAdLoader;
    }
}

Примечание

Балковый запрос за рекламой позволяет подобрать несколько отличающихся друг от друга объявлений.

Массив рекламных объявлений, полученный в результате балкового запроса, может содержать от 0 до count объектов NativeAd. Все полученные объекты рекламы можно показывать независимо друг от друга, используя описанные выше способы внешнего оформления нативных объявлений.

Тестирование интеграции нативной рекламы

Использование демоблоков для тестирования рекламы

Для проверки корректной интеграции нативной рекламы, а также для тестирования вашего приложения, рекомендуется использовать тестовую рекламу.

Для гарантированного возврата тестовых объявлений на каждый запрос за рекламой, мы создали специальный демонстрационный идентификатор рекламного места. Используйте его для проверки корректной интеграции рекламы.

Демонстрационный adUnitId для текстово-графической рекламы: demo-native-content-yandex.

Демонстрационный adUnitId для рекламы мобильных приложений: demo-native-app-yandex.

Важно

Убедитесь, что перед выкладыванием приложения в store, вы заменили демонстрационный идентификатор рекламного места на настоящий, полученный в ПИ.

Проверка корректной интеграции рекламы

Проверить корректность интеграции нативной рекламы можно через встроенный в sdk анализатор.

Данный инструмент проверяет корректность подключения нативной рекламы и выводит в лог подробный отчет. Для просмотра отчета, выполните поиск по ключевому слову "YandexAds" в инструменте отладки Android-приложений Logcat.

adb logcat -v brief '*:S YandexAds'

В случае успешной интеграции, вы увидите следующее сообщение:

adb logcat -v brief '*:S YandexAds'
mobileads$ adb logcat -v brief '*:S YandexAds'
I/YandexAds(13719): [Integration] Ad type native was integrated successfully

В случае обнаружения проблем при интеграции нативной рекламы — подробный отчет о проблемах и рекомендации по их устранению.

Индикатор корректной интеграции нативной рекламы

С помощью индикатора можно определить, успешно ли прошла интеграция нативной рекламы или получить отладочную информацию, чтобы понять причину ошибки.

Примечание

Теперь индикатор корректной интеграции можно включить/отключить в Debug Panel.

Чтобы включить отображение индикатора в отладочном режиме, вызовите метод enableDebugErrorIndicator со значением true:

MobileAds.enableDebugErrorIndicator(true)

Если интеграция прошла успешно, то в отладочном режиме, поверх рекламного объявления появится рамка светлого зеленого цвета.

Если при интеграции нативной рекламы допущена ошибка, то в отладочном режиме, поверх рекламного объявления, появится индикатор. По нажатию на индикатор вы увидите сообщение с отладочной информацией, по которой можно понять причину ошибки. Повторное нажатие на индикатор скрывает сообщение.

Чтобы выключить отображение индикатора в отладочном режиме, вызовите метод enableDebugErrorIndicator со значением false:

MobileAds.enableDebugErrorIndicator(false)

Аппаратное ускорение для видеорекламы

Чтобы видеореклама успешно проигрывалась на экране вашего приложении, необходимо чтобы было включено аппаратное ускорение (подробнее в документации).

По умолчанию аппаратное ускорение включено. Если вы выключали аппаратное ускорение в вашем приложении, убедитесь, что на экранах приложения с рекламой, аппаратное ускорение включено.

Код включения аппаратного ускорения
<application android:hardwareAccelerated="true">
    <!-- For activities that use ads, hardwareAcceleration should be true. -->
    <activity android:hardwareAccelerated="true" />
</application>