Объединяем Qt и AdMob

от автора

image
В один момент понадобилось мне интегрировать рекламу в мобильное приложение на 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().

пример использования:

#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_Banner(0)     , 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 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 

Пример работы тестового приложения

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

ссылка на оригинал статьи http://habrahabr.ru/post/261425/


Комментарии

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *