Pull to refresh

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

C++ *Development of mobile applications *Qt *
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_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


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


На этом все, надеюсь кому-то пригодится данная реализация. Ну а если вы заметили неточности, опечатки или есть пожелания — пишите мне в коменатриях или личку
Tags: qtadmobc++iosandroid
Hubs: C++ Development of mobile applications Qt
Total votes 16: ↑13 and ↓3 +10
Comments 2
Comments Comments 2

Popular right now