В один момент понадобилось мне интегрировать рекламу в мобильное приложение на Qt и я был сильно удивлен, обнаружив, что решений, в общем-то, и нет. Нет, есть конечно, V-Play AdMob плагин, но вы меня извините, 160 баксов за то, что можно сделать за выходные — это чересчур. Последующие поиски привели меня к этой статье на хабре, которая послужила материалом для Android реализации, а в итоге получился небольшой фреймворк, для работы с AdMob рекламой на IOS и Android.
Сам фреймворк можно найти на GitHub. Здесь, в QtAdMob находится библиотека, а QtAdMobApp — тестовое приложение, демонстрирующее возможности библиотеки. В настоящий момент реализована поддержка баннеров и Interstitial рекламы (полноэкранной рекламы). Интерфейс баннеров представлен IQtAdMobBanner, содержащим набор методов для управления баннером (установка позиции, размера, показа/скрытия и проч.). Конкретные реализации сделаны в классах QtAdMobBannerIos/Android/Dummy, соответственно для IOS, Android и последний является классом-заглушкой для неподдерживаемых платформ. Создание платформ-специфик баннера легло на плечи функции CreateQtAdMobBanner().
Подобная структура относится и к «интерстишал» рекламе, здесь есть свой базовый интерфейс IQtAdMobInterstitial, платформо-зависимая реализация в классах QtAdMobInterstitialIos/Android/Dummy, а также ф-ция создания CreateQtAdMobInterstitial().
пример использования:
Initialize — метод выполняет базовую инициализацию баннера, конкретно в IOS этот метод делает поиск главной вьюшки и «приаттачивает» вьюшку баннера к ней. Собственно, в андроиде этот метод делает практически тоже самое.
SetUnitId — устанавливает идентификатор рекламы, который можно получить в настройках компании вашего приложения на странице AdMob.
SetSize — как говорит из названия, устанавливает размер баннера. Возможные размеры заданы в перечислении в интерфейсе баннеров.
AddTestDevice — добавляет идентификаторы тестовых девайсов, реклама на таких девайсах будет представленна тестовым баннером, с указанием размера баннера и проч. «дебажных» вещей. Идентификатор девайса можно вытянуть из консоли, при запуске приложения на устройстве
Show — ну и метод который выполняет загрузку и показ рекламы. Для скрытия рекламы существует метод Hide
В примере выше, в методе resizeEvent делается позиционировние баннера по центру
Для полноэкранной рекламы все еще проще, т.к. тут нет возможности задавать позицию и размеры, то интерфейс сократился до пары методов. Как правило, реклама такого типа отображается при переходах между уровнями в играх, и поэтому она должна быть уже загружена на момент показа. Поэтому здесь разделены методы загрузки и показа. LoadWithUnitId — метод выполняет загрузку рекламы с определенным идентификатором и должен быть вызван как можно раньше. После загрузки рекламы она не будет отображена, до вызова метода Show
#include "MainWindow.h"
#include "ui_MainWindow.h"
#include "QtAdMob/QtAdMobBanner.h"
#include "QtAdMob/QtAdMobInterstitial.h"
MainWindow::MainWindow(QWidget *parent)
: QMainWindow(parent)
, ui(new Ui::MainWindow)
, m_Switch(false)
{
ui->setupUi(this);
m_Banner = CreateQtAdMobBanner();
m_Banner->Initialize();
m_Banner->SetUnitId("ca-app-pub-7485900711629006/8288667458");
m_Banner->SetSize(IQtAdMobBanner::Banner);
m_Banner->AddTestDevice("514ED2E95AD8EECE454CC5565326160A");
m_Banner->Show();
m_Interstitial = CreateQtAdMobInterstitial();
m_Interstitial->LoadWithUnitId("ca-app-pub-7485900711629006/9462519453");
m_Interstitial->AddTestDevice("514ED2E95AD8EECE454CC5565326160A");
m_Interstitial->Show();
connect(ui->okButton, SIGNAL(clicked()), this, SLOT(OnButtonOkClicked()));
}
MainWindow::~MainWindow()
{
m_Banner->Shutdown();
delete m_Banner;
delete m_Interstitial;
delete ui;
}
void MainWindow::resizeEvent(QResizeEvent *event)
{
UNUSED(event);
QPoint position((width() - m_Banner->GetSizeInPixels().width()) * 0.5f, 50.0f);
m_Banner->SetPosition(position);
}
void MainWindow::OnButtonOkClicked()
{
bool isShowed = m_Banner->IsShow();
if (!isShowed)
{
m_Banner->Show();
ui->okButton->setText("Hide Banner");
}
else
{
m_Banner->Hide();
ui->okButton->setText("Show Banner");
}
}
Initialize — метод выполняет базовую инициализацию баннера, конкретно в IOS этот метод делает поиск главной вьюшки и «приаттачивает» вьюшку баннера к ней. Собственно, в андроиде этот метод делает практически тоже самое.
SetUnitId — устанавливает идентификатор рекламы, который можно получить в настройках компании вашего приложения на странице AdMob.
SetSize — как говорит из названия, устанавливает размер баннера. Возможные размеры заданы в перечислении в интерфейсе баннеров.
AddTestDevice — добавляет идентификаторы тестовых девайсов, реклама на таких девайсах будет представленна тестовым баннером, с указанием размера баннера и проч. «дебажных» вещей. Идентификатор девайса можно вытянуть из консоли, при запуске приложения на устройстве
Show — ну и метод который выполняет загрузку и показ рекламы. Для скрытия рекламы существует метод Hide
В примере выше, в методе resizeEvent делается позиционировние баннера по центру
Для полноэкранной рекламы все еще проще, т.к. тут нет возможности задавать позицию и размеры, то интерфейс сократился до пары методов. Как правило, реклама такого типа отображается при переходах между уровнями в играх, и поэтому она должна быть уже загружена на момент показа. Поэтому здесь разделены методы загрузки и показа. LoadWithUnitId — метод выполняет загрузку рекламы с определенным идентификатором и должен быть вызван как можно раньше. После загрузки рекламы она не будет отображена, до вызова метода Show
Интеграция в IOS:
Интеграция для IOS оказалась достаточно простая и сводится к копированию фреймворка в нужный каталог проекта и добавление необходимых библиотек к проекту. Для начала инклюдим фреймворк в .pro файле проекта
include(QtAdMob/QtAdMob.pri)
А также добавляем все необходимые флаги компиляции и библиотеки
ios:QMAKE_CXXFLAGS += -fobjc-arc
ios:QMAKE_LFLAGS += -ObjC
ios:QT += gui_private
ios:LIBS += -F $$PWD/QtAdMob/platform/ios/GoogleMobileAds -framework GoogleMobileAds \
-framework AVFoundation \
-framework AudioToolbox \
-framework CoreTelephony \
-framework MessageUI \
-framework SystemConfiguration \
-framework CoreGraphics \
-framework AdSupport \
-framework StoreKit \
-framework EventKit \
-framework EventKitUI \
-framework CoreMedia
Интеграция в Android:
Т.к. опыта работы с java и андроидом у меня практически нет, то реализация получилась для меня несколько «монструозной». Главной проблемой то, что поток в котором работает UI QT и поток UI java — это два разных потока, и все вызовы из C++ в Java пришлось переводить на UI поток джавы, потому реализация QtAdMobActivity награмождена однотипными вызовами runOnUiThread.
Для подключения фреймворка понадобится следующее:
— Скопировать каталог с фреймворком в каталог проекта и заинклюдить его в .pro файле проекта, как и в случае с IOS версией
include(QtAdMob/QtAdMob.pri)
— Скопировать директории src/ и google-play-services_lib/ из каталога QtAdMob/platform/android в каталог, где находится манифест AndroidManifest.xml
— Сделать все изменения в вашем манифесте как на скриншоте ниже
— Прилинковать следующие Qt библиотеки в файле проекта:
android:QT += androidextras gui-private
— Если не существует, то создать файл project.properties в каталоге с манифест-файлом и добавить в него путь к библиотеке Google Play Services
android.library.reference.1=./google-play-services_lib/
— И добавить путь к активити
android:DISTFILES += <Path_to_manifest_location>/src/org/dreamdev/QtAdMob/QtAdMobActivity.java
Пример работы тестового приложения
На этом все, надеюсь кому-то пригодится данная реализация. Ну а если вы заметили неточности, опечатки или есть пожелания — пишите мне в коменатриях или личку