1 В избранное 0 Ответвления 0

OSCHINA-MIRROR/MMAChinaSDK-MMAViewabilitySDK_Android

Присоединиться к Gitlife
Откройте для себя и примите участие в публичных проектах с открытым исходным кодом с участием более 10 миллионов разработчиков. Приватные репозитории также полностью бесплатны :)
Присоединиться бесплатно
Клонировать/Скачать
Внести вклад в разработку кода
Синхронизировать код
Отмена
Подсказка: Поскольку Git не поддерживает пустые директории, создание директории приведёт к созданию пустого файла .keep.
Loading...
README.md

Руководство по развёртыванию унифицированного SDK для мониторинга и верификации цифровой рекламы (Android)

Область применения

Android SDK подходит для устройств с Android 2.3.3 (API Level 10) и выше.

Интеграция SDK

Шаг 1: Импорт SDK

Выберите способ импорта в зависимости от используемой IDE:

Eclipse ADT

Скопируйте файлы jar из SDK в папку libs проекта: правой кнопкой мыши выберите jar-пакет --> Build Path --> Add to Build Path.

Android Studio

  1. Создайте папку libs в папке app проекта Android Studio.
  2. Скопируйте файлы jar SDK в новую папку libs.
  3. Измените файл build.gradle папки app, добавив зависимость dependencies:
dependencies {

      implementation files('libs/mmachina_sdk.jar') 

  }

Импорт сигнатурной библиотеки

Скопируйте файл libMMASignature.so из SDK в каталог libs/armeabi проекта. Файлы библиотек для других архитектур CPU находятся в каталоге lib_abi SDK. Рекомендуется скопировать все файлы из этого каталога в папку app/libs проекта, но если вы учитываете размер APK, то как минимум включите основные архитектуры: armeabi, armeabi-v7a, arm64-v8a.

Импорт конфигурации в автономном режиме

Скопируйте конфигурационный файл sdkconfig.xml в папку assets проекта. Это позволит читать настройки по умолчанию при отсутствии сети или в автономном режиме. Также рекомендуется загрузить этот файл на веб-сервер, чтобы его можно было получить через Интернет и легко изменять настройки удалённо.

Настройка разрешений

Обычные разрешения

Для базовых функций мониторинга требуются следующие разрешения:

Разрешение Назначение
INTERNET Разрешает приложению подключаться к Интернету и отправлять данные мониторинга.
ACCESS_NETWORK_STATE Позволяет проверять подключение к сети, чтобы избежать отправки данных при проблемах с сетью и сэкономить трафик и заряд батареи.
READ_PHONE_STATE Позволяет получить информацию о телефоне, которая используется для уникальной идентификации пользователя.
ACCESS_WIFI_STATE Позволяет считывать информацию о Wi-Fi, что полезно для обновления конфигурации при подходящем сетевом окружении.
Расширенные разрешения

В дополнение к базовым разрешениям, если требуется передавать информацию о местоположении, необходимо установить параметр <isTrackLocation> в разделе Company файла sdkconfig равным true, а также запросить следующие разрешения:

Разрешение Назначение
ACCESS_FINE_LOCATION Получение местоположения через GPS.
ACCESS_COARSE_LOCATION Получение местоположения через WiFi или сотовые вышки.

Пример кода

<!--?xml version="1.0" encoding="utf-8"?-->
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="cn.com.mma.mobile.tracking.demo">
    <!-- SDK 所需常规权限 -->
    <uses-permission android:name="android.permission.INTERNET" />
    <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
    <uses-permission android:name="android.permission.READ_PHONE_STATE" />
    <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE"/>
    <!-- 如果获取位置信息,需要声明以下权限 -->
    <uses-permission android:name="android.permission.ACCESS_FINE_LOCATION"/>
    <uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION"/>
<application ......>
  <activity ......>
  ......
  </activity>
    </application>
</manifest>

Шаг 2: Использование

Включение классов

Импортируйте соответствующие классы в классе, где требуется использовать функции SDK:

import cn.com.mma.mobile.tracking.api.Countly;

Инициализация SDK

Определение интерфейса:

public void init(Context context, String configURL) 

Описание параметров:

Параметр Тип Описание
context Context Контекст приложения или активности
configURL String Удаленный адрес для обновления sdkconfig

Пример кода: добавьте следующий код в метод onCreate вашего класса Application или Activity:

Countly.sharedInstance().init(this, "удаленный адрес sdkconfig");

Отображение экспозиции

Экспозиция определяется как момент, когда рекламный контент полностью загружен на клиентское устройство и начинает рендериться (Begin to render, BtR). Только после начала рендеринга событие считается экспозицией. Рендеринг означает процесс рисования контента или добавление контента в документную модель объекта.

Если экспозиция вызвана, SDK проверяет, начал ли рекламный контент рендериться. Если да, SDK отправляет уведомление об экспозиции в систему мониторинга.

Примечание: Для мониторинга видимости рекламы, реклама должна соответствовать условиям начала рендеринга (BtR), иначе SDK не будет выполнять мониторинг видимости. При вызове метода мониторинга видимости, SDK проверит, начался ли рендеринг рекламного контента. Если да, то SDK отправит уведомление об экспозиции и продолжит мониторинг видимости до тех пор, пока условия видимости/невидимости не будут выполнены, после чего мониторинг завершится. Если нет, то мониторинг не начнется. Видеомониторинг экспозиции в Countly

Видеомониторинг засветки

Интерфейс определения:

public void videoImp(String adUrl, View adView, int impType, int palyType, CallBack callBack)

Параметры:

Параметр Тип Описание Обязательно
adURL String Код мониторинга засветки рекламы Да
adview View Объект представления рекламы Да
impType int 0 — мониторинг засветки; 1 — визуализация засветки Да
palyType int Тип воспроизведения видео: 1 — автоматическое воспроизведение, 2 — ручное воспроизведение, 0 — невозможно определить Да
callBack CallBack Объект обратного вызова для мониторинга Да

Пример кода:

     private String VIDEO_IMP_URL = "https://g.cn.miaozhen.com/x/k=1234567&p=778kb&dx=__IPDX__&rt=2&ns=__IP__&ni=__IESID__&v=__LOC__&xa=__ADPLATF";
     Countly.sharedInstance().videoImp(VIDEO_IMP_URL, adView, 0 ,1,new CallBack() {
             /**
              * Мониторинг события
              * @param eventType
              */
             @Override
             public void onSuccess(String eventType) {
                 //Код мониторинга отправлен успешно
             }
             @Override
             public void onFailed(String errorMessage) {
                 //Ошибка отправки кода мониторинга

             }
         });
         

Мониторинг элементов веб-страницы с помощью WebView

Использование: При мониторинге экспозиции рекламы в местах, где используется WebView, Android SDK динамически внедряет код JavaScript, который активно отслеживает состояние рекламных элементов на странице и их видимость (BTR). Чтобы точно отслеживать определённый рекламный контент, необходимо добавить класс «umid-element» к соответствующему тегу элемента.

Пример кода:

<!-- Видеореклама -->
<video width="300" class="umid-element"  controls playsinline muted>
    <source src="./ad.mp4" type="video/mp4">
    <source src="./ad.webm" type="video/webm">
</video>
<!-- Графическая реклама -->
  <div style="margin-bottom: 0px;">
      <img alt="HTML Display Reference Ad" class="umid-element" src="./ads.png">
  </div>

Мониторинг экспозиции с помощью WebView

Определение интерфейса:

Использование: В веб-странице, которую нужно отслеживать, добавьте прослушиватель мониторинга. Обратите внимание, что прослушиватель должен быть добавлен до завершения загрузки страницы (onPageFinished), иначе SDK не сможет выполнить мониторинг экспозиции через WebView.

Примечание: Если вы решите не внедрять JavaScript для запуска мониторинга, то его следует добавить до загрузки страницы. Подробности см. в приложении.

public void SetAddJavascriptMonitor(Context context, WebView webView)

Параметры:

Параметр Тип Описание Обязателен
context Context Контекст среды Да
webView WebView Объект WebView с загружаемой рекламой Да

Пример кода:

Countly.sharedInstance().SetAddJavascriptMonitor(getApplicationContext(),webView);

Запустите мониторинг после завершения загрузки страницы onPageFinished. Если вы решили не внедрять JavaScript, мониторинг следует запустить до загрузки страницы, подробности см. в приложении.

public void webViewImp( String adUrl, View adView,  int impType, boolean isInjectJs,CallBack callBack)

Параметры:

Параметр Тип Описание Обязателен
adURL String Код отслеживания экспозиции Да
adview View Объект отображения рекламы Да
impType int 0 — отслеживание экспозиции; 1 — визуальное отслеживание Да
isInjectJs boolean true — динамическое внедрение JavaScript; false — не внедряется, но требуется добавить соответствующий код JavaScript в HTML самостоятельно, см. приложение Да
callBack CallBack Обработчик мониторинга Да

Пример кода:

      private String WebView_DISPLAY_IMP_URL = "https://g.cn.miaozhen.com/x/k=1234567&p=778kb&dx=__IPDX__&rt=2&ns=__IP__&ni=__IESID__&v=__LOC__&xa=__ADPLATF";

      Countly.sharedInstance().webViewImp(WebView_DISPLAY_IMP_URL, adView, 0 ,new CallBack() {
             /**
              * Мониторинг событий
              * @param eventType
              */
             @Override
             public void onSuccess(String eventType) {
                 //Успешная отправка кода мониторинга
             }
             @Override
             public void onFailed(String errorMessage) {
                 //Сбой отправки кода мониторинга

             }
         });

Отслеживание видео в WebView

Определение интерфейса:

Использование: Добавьте прослушиватель в веб-страницу, которая должна отслеживаться. Обратите внимание, что слушатель должен быть добавлен перед завершением загрузки страницы (onPageFinished), в противном случае SDK может не выполнить отслеживание видео через WebView.

Примечание: Если вы выберете не внедрять JavaScript для отслеживания, его следует добавить перед загрузкой страницы. Подробнее см. в приложении.

public void SetAddJavascriptMonitor(Context context,WebView webView)

Параметры:

Параметр Тип Описание Обязателен
context Context Среда контекста Да
webView WebView Веб-просмотр с загруженным рекламным контентом Да

Пример кода:

Countly.sharedInstance().SetAddJavascriptMonitor(getApplicationContext(),webView);

Включите мониторинг после завершения загрузки страницы onPageFinished. Если вы выбрали не внедрять JavaScript, мониторинг должен быть запущен до загрузки страницы, подробнее см. в приложении.

public void webViewVideoImp( String adUrl, View adView,  int impType, int palyType,boolean isInjectJs,CallBack callBack)

Параметры:

Параметр Тип Описание Обязателен
adURL String Код отслеживания видео Да
adview View Отображение рекламного контента Да
impType int 0 — отслеживание; 1 — визуальное отслеживание Да
palyType int Тип воспроизведения видео: 1 — автоматический, 2 — ручной, 0 — не определяется Да
isInjectJs boolean true — динамическое внедрение JavaScript; false — без внедрения, но необходимо добавить соответствующий JavaScript-код в HTML вручную, см. приложение Да
callBack CallBack Обработчик мониторинга Да
--- --- --- ---
Автоматическое воспроизведение 1 Автоматическое воспроизведение видео
Ручное воспроизведение 2 Ручное воспроизведение видео
Не удалось определить 0 Не удалось определить режим воспроизведения
isInjectJs boolean Динамическое внедрение JavaScript; false — динамическое внедрение не производится, необходимо добавить соответствующий код в HTML-документ вручную Да
callBack CallBack Объект обратного вызова для мониторинга Да

Пример кода:

private String WebView_VIDEO_IMP_URL = "https://g.cn.miaozhen.com/x/k=1234567&p=778kb&dx=__IPDX__&rt=2&ns=__IP__&ni=__IESID__&v=__LOC__&xa=__ADPLATFORM";

Countly.sharedInstance().webViewVideoImp(WebView_VIDEO_IMP_URL, adView, 0 ,2,new CallBack() {
    /**
     * Мониторинг событий
     * @param eventType
     */
    @Override
    public void onSuccess(String eventType) {
        // Мониторинг кода успешно отправлен
    }

    @Override
    public void onFailed(String errorMessage) {
        // Ошибка отправки кода мониторинга
    }
});

Мониторинг кликов:

Интерфейс определения:

public  void onClick(String adURL,CallBack callBack)

Параметры:

Параметр Тип Описание Обязателен
adURL String Код мониторинга клика по рекламному объявлению Да
callBack CallBack Объект обратного вызова для мониторинга Да
Пример кода:
Countly.sharedInstance().onClick("http://example.com/axxx,bxxxx,c3,i0,h", new CallBack() {
    /**
     * Мониторинг событий
     * @param eventType
     */
    @Override
    public void onSuccess(String eventType) {
            // Мониторинг кода успешно отправлен
    }

    @Override
    public void onFailed(String errorMessage) {
            // Ошибка отправки кода мониторинга
    }
});

Остановка мониторинга видимости:

Интерфейс определения:

public void stop(String adURL)

Параметры:

Параметр Тип Описание Обязателен
adURL String Код мониторинга видимости рекламного объявления Да
SDK предоставляет функцию активного закрытия мониторинга видимости, которая требует передачи уже активированного кода мониторинга видимости для рекламного объявления. Если передать неправильный код мониторинга, это может привести к тому, что остановка не будет работать.

Пример кода:

String adURL = "http://vxyz.admaster.com.cn/w/a86218,b1778712,c2343,i0,m202,8a2,8b2,2j,h";
Countly.sharedInstance().onExpose(adURL, adView);
new Handler().postDelayed(new Runnable(){
    public void run() {
        // Через 5 секунд остановить мониторинг
        Countly.sharedInstance().stop(adURL);
    }}, 5000);

Режим отладки:

В режиме отладки SDK будет выводить данные журнала. Рекомендуется не включать этот режим при публикации приложения (пожалуйста, установите переключатель Log перед инициализацией, по умолчанию он выключен).

Интерфейс определения:

public void setLogState(boolean debugmode)

Параметры:

Параметр Тип Описание Обязателен
debugmode boolean true — включить журнал SDK, false — выключить журнал SDK Да
Пример кода:
Countly.sharedInstance().setLogState(true);

Освобождение памяти:

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

Интерфейс определения:

public  void terminateSDK()

Пример кода:

Countly.sharedInstance().terminateSDK();

Конфигурация запутывания:

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

# SDK использует API в пакете v4, убедитесь, что пакет поддержки v4 не запутан
-keep class android.support.v4.** { *; }
-dontwarn android.support.v4.**
``` ```
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <meta http-equiv="X-UA-Compatible" content="ie=edge">
    <title>Document</title>
    <!-- js sdk 代码放入 head 元素内 -->
    <script>
        !function() {
            "use strict";
            var e = function(e) {
                return JSON.stringify(e);
            },
                t = function(e) {
                    var t = e.getBoundingClientRect();
                    return 0 == t.width || 0 == t.height;
                };

            var n, i, s = function() {
                return (s = Object.assign || function(e) {
                    for (var t, n = 1, i = arguments.length; n < i; n++)
                        for (var s in t = arguments[n])
                            Object.prototype.hasOwnProperty.call(t, s) && (e[s] = t[s]);
                    return e;
                }).apply(this, arguments);
            };

            var o = [],
                r = new window.Map,
                a = function(e) {
                    var t;
                    navigator.userAgent.match(/\(i[^;]+;( U;)? CPU.+Mac OS X/) ? window.webkit.messageHandlers.__mz_Monitor.postMessage(e) : ((t = navigator.userAgent).indexOf("Android") > -1 || t.indexOf("Adr") > -1) && window.__mz_Monitor.mz_push(e),
                },
                d = function(t) {
                    var n = e(t);
                    r.has(n) || (r.set(n), o.push(e(s(s({}, t), {time: (new Date).toISOString()})))), function() {
                        for (; o.length;) {
                            var e = o.shift();
                            e && a(e);
                        }
                    }();
                };

            !function(e) {
                e.JavaScript = "javaScript",
                    e.Image = "image",
                    e.Video = "video",
                    e.AUDIO = "audio",
                    e.HTML = "html";
            }(n || (n = {})),
                function(e) {
                    e.Impression = "impression",
                        e.ImpressionError = "impressionError",
                        e.WindowUnload = "unload",
                        e.Click = "click",
                        e.DisplayChange = "displayChange",
                        e.Start = "start",
                        e.FirstQuartile = "firstQuartile",
                        e.Midpoint = "midpoint",
                        e.ThirdQuartile = "thirdQuartile",
                        e.Complete = "complete",
                        e.Pause = "pause",
                        e.Resume = "resume",
                        e.BufferStart = "bufferStart",
                        e.BufferFinish = "bufferFinish";
                }(i || (i = {}));

            var h = function() {
                function e(e) {
                    this.advertisementType = n.Image,
                        this.el = e,
                        this.onError = this.onError.bind(this),
                        this.onLoad = this.onLoad.bind(this);

                    this.bindEvent(),
                        this.checkVisible();
                }

                return e.prototype.checkVisible = function() {
                    this.el.complete && (t(this.el) ? this.onError() : this.imageComplete());
                },
                    e.prototype.imageComplete = function() {
                        var e = new Image;
                        e.src = this.el.src,
                            e.onload = this.onLoad,
                            e.onerror = this.onError;
                    },
                    e.prototype.bindEvent = function() {
                        this.el.addEventListener("error", this.onError),
                            this.el.addEventListener("load", this.onLoad);
                    },
                    e.prototype.send = function(e) {
                        d(s(s({}, e), {advertisementType: this.advertisementType}));
                    },
                    e.prototype.onImpression = function() {
                        this.send({eventType: i.Impression, ImpressionType: "beginToRender", isRender: "1"});
                    },
                    e.prototype.onError = function() {
                        this.send({
                            eventType: i.ImpressionError,
                            ImpressionType: "beginToRender",
                            isRender: "0"
                        });
                    },
                    e.prototype.onLoad = function() {
                        this.onImpression();
                    },
                    e.prototype.onClick = function() {},
                    e.prototype.destroyed = function() {
                        this.el.removeEventListener("error", this.onError),
                            this.el.removeEventListener("load", this.onLoad),
                            this.el = null;
                    },
                    e;
            }(),
                u = function() {
                    function e(e) {
                        this.advertisementType = n.AUDIO,
                            this.quartileEvents = {
                                "1q": !1,
                                "2q": !1,
                                "3q": !1,
                                "4q": !1
                            },
                            this.isFirst = !1,
                            this.isFullscreen = !1,
                            this.el = e,
                            this.isFirst = !0,
                            this.onPlay = this.onPlay.bind(this),
                            this.onPause = this.onPause.bind(this),
                            this.onWaiting = this.onWaiting.bind(this),
                            this.onTimeupdate = this.onTimeupdate.bind(this),
                            this.onWebkitendfullscreen = this.onWebkitendfullscreen.bind(this),
                            this.onWebkitbeginfullscreen = this.onWebkitbeginfullscreen.bind(this);

                        this.bindEvent(),
                            this.checkElement();
                    }

                    return {
                        ...
                    };
                }();
``` Вот перевод текста на русский язык:

e.prototype.checkElement = function() { t(this.el)? this.beforeImpression(!1): this.beforeImpression(!0) }, e.prototype.bindEvent = function() { this.el.addEventListener("play", this.onPlay), this.el.addEventListener("pause", this.onPause), this.el.addEventListener("waiting", this.onWaiting), this.el.addEventListener("timeupdate", this.onTimeupdate), this.el.addEventListener("webkitendfullscreen", this.onWebkitendfullscreen), this.el.addEventListener("webkitbeginfullscreen", this.onWebkitbeginfullscreen) }, e.prototype.onPlay = function() { this.isFirst? this.isFirst=!1: this.send({EventType: i.Resume}) }, e.prototype.onPause = function() { this.send({eventType: i.Pause}) }, e.prototype.onWaiting = function() {}, e.prototype.onTimeupdate = function() {}, e.prototype.onVolumechange = function() {}, e.prototype.onWebkitendfullscreen = function() { this.isFullscreen=!1 }, e.prototype.onWebkitbeginfullscreen = function() { this.isFullscreen=!0 }, e.prototype.send = function(e) { d(s(s({}, e), {advertisementType: this.advertisementType, quartileEvents: this.quartileEvents})) }, e.prototype.beforeImpression = function(e) { this.send({EventType: i.Impression, ImpressionType:"beginToRender", isRender: e?"1":"0"}) }, e.prototype.destroyed = function() { this.el.removeEventListener("play", this.onPlay), this.el.removeEventListener("pause", this.onPause), this.el.removeEventListener("waiting", this.onWaiting), this.el.removeEventListener("timeupdate", this.onTimeupdate), this.el.removeEventListener("webkitendfullscreen", this.onWebkitendfullscreen), this.el.removeEventListener("webkitbeginfullscreen", this.onWebkitbeginfullscreen), this.el=null }, e}(), l=function() { function e() { this.advertisementType=n.HTML, document.body.innerText.length>0? this.send({isRender:"1"}): this.send({isRender:"0"}) } return e.prototype.send=function(e){ d(s(s({},e),{advertisementType:this.advertisementType,ImpressionType:"beginToRender"})) }, e }(); var p, c, f=function(){ var e, t=document.body.querySelector(".umid-element"); if (t) return (e=t).tagName&&"video"===e.tagName.toLowerCase()? new u(t): function(e){return e.tagName&&"img"===e.tagName.toLowerCase()(t)? new h(t): new l; var n=document.body.querySelector("video"); if(n)return new u(n); var i=document.body.querySelectorAll("img"); if(i.length){ var s=function(e){for(var t=0, n=null, i=0; i<e.length; i++){var s=e[i], o=s.offsetWidth*s.offsetHeight; o>=t&&(t=o, n=s)}return n}(i); return new h(s) }return new l }; function m(){f()} if(document.body)m(); else { var v=(p=function(){m()}, c=!1, function(){c||(c=!0, p.apply(this, arguments))}); window.addEventListener("load", v), document.addEventListener("DOMContentLoaded", v) }}


Комментарии ( 0 )

Вы можете оставить комментарий после Вход в систему

Введение

MMAChina публикует открытый проект для мониторинга видимости рекламы на мобильных устройствах с операционной системой Android. Развернуть Свернуть
MPL-2.0
Отмена

Обновления

Пока нет обновлений

Участники

все

Недавние действия

Загрузить больше
Больше нет результатов для загрузки
1
https://api.gitlife.ru/oschina-mirror/MMAChinaSDK-MMAViewabilitySDK_Android.git
git@api.gitlife.ru:oschina-mirror/MMAChinaSDK-MMAViewabilitySDK_Android.git
oschina-mirror
MMAChinaSDK-MMAViewabilitySDK_Android
MMAChinaSDK-MMAViewabilitySDK_Android
master