Trong quá trình làm việc, đặc biệt khi các bạn làm out source cho khách hàng Nhật , chắc chắn một điều là các bạn sẽ được khách hàng yêu tích hợp các loại quảng cáo vào project hiện thời của bạn như quảng cáo AdMod và nhiều loại quảng cáo khác. Trong một lần làm project , khách hàng bên nhật đã yêu cầu tích hợp quảnh cáo của Adstir vào trong project bên mình đang phát triển cho họ. Trong Adstir có thể hiển thị rất nhiều các dạng quảng cáo khác nhau như hiển thị baner, hiển thị full screen, hiển thị video... Nhưng trong bài viết này mình sẽ hướng dẫn hiển thị loại quảng cáo video cụ thể ở đây là AdstirVideoReward Để tạo được một tài khoản của Adstir thì phải cần thoả mãn rất nhiều yêu cầu của bên Adstir vì cái này liên quan đến money khi xem quảng cáo. Nên tôi không tạo được một tài khoản free. Nhưng các bạn yên tâm, khi các bạn làm việc, thì Khách Hàng của các bạn sẽ cũng cấp tài khoản và những thông tin cần thiết cho các bạn. Chúng ta hãy bắt đầu nào Bước đầu tiên chúng ta cần phải làm là tích hợp SDK của adstir vào trong project của chúng ta.

Trong file build.gradle của project các bạn thêm những dòng bên dưới:

 maven { url 'http://cdnp.ad-stir.com/m2' }
    compile 'com.google.android.gms:play-services-ads-lite:11.0.4'

    def adstir_version = "2.11.3"
    compile "com.ad-stir.webviewsdk:adstir-webviewsdk:${adstir_version}"
    compile "com.ad-stir.mediationadapter:adstir-mediationadapter:${adstir_version}"

Tiếp theo chúng ta sẽ tạo một giao diện đơn giản gồm các button loadbutton play như bên dưới:

activity_main.xml

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:padding="@dimen/padding">


    <RelativeLayout
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_alignParentStart="true"
        android:layout_centerInParent="true"
        android:background="@color/colorLoaderArea">


        <RelativeLayout
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_centerHorizontal="true"
            android:layout_centerVertical="true">


            <TextView
                android:id="@+id/status"
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                android:layout_marginLeft="@dimen/padding"
                android:layout_marginRight="@dimen/padding"
                android:background="@color/colorLoaderStatusBackground"
                android:padding="@dimen/textPadding"
                android:text="Status"
                android:textColor="@color/colorLoaderStatusText" />

            <LinearLayout
                android:id="@+id/statuses"
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                android:layout_alignEnd="@+id/status"
                android:layout_alignLeft="@+id/status"
                android:layout_alignRight="@+id/status"
                android:layout_alignStart="@+id/status"
                android:layout_below="@+id/status"
                android:orientation="horizontal">

                <TextView
                    android:id="@+id/status_waiting"
                    android:layout_width="wrap_content"
                    android:layout_height="wrap_content"
                    android:layout_weight="1"
                    android:background="@color/colorActiveStatusBackground"
                    android:gravity="center"
                    android:padding="@dimen/textPadding"
                    android:text="Waiting"
                    android:textColor="@color/colorActiveStatusText" />

                <TextView
                    android:id="@+id/status_loading"
                    android:layout_width="wrap_content"
                    android:layout_height="wrap_content"
                    android:layout_weight="1"
                    android:background="@color/colorInactiveStatusBackground"
                    android:gravity="center"
                    android:padding="@dimen/textPadding"
                    android:text="Loading"
                    android:textColor="@color/colorInactiveStatusText" />

                <TextView
                    android:id="@+id/status_loaded"
                    android:layout_width="wrap_content"
                    android:layout_height="wrap_content"
                    android:layout_weight="1"
                    android:background="@color/colorInactiveStatusBackground"
                    android:gravity="center"
                    android:padding="@dimen/textPadding"
                    android:text="Loaded"
                    android:textColor="@color/colorInactiveStatusText" />

            </LinearLayout>

            <LinearLayout
                android:id="@+id/buttons"
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                android:layout_alignEnd="@+id/status"
                android:layout_alignLeft="@+id/status"
                android:layout_alignRight="@+id/status"
                android:layout_alignStart="@+id/status"
                android:layout_below="@+id/statuses"
                android:layout_marginTop="@dimen/middlePadding"
                android:orientation="horizontal">

                <Button
                    android:id="@+id/button_load"
                    style="@style/Widget.AppCompat.Button"
                    android:layout_width="wrap_content"
                    android:layout_height="wrap_content"
                    android:layout_alignLeft="@+id/status"
                    android:layout_alignStart="@+id/status"
                    android:layout_below="@+id/statuses"
                    android:layout_weight="1"
                    android:background="@drawable/shape_rounded_corners"
                    android:stateListAnimator="@null"
                    android:text="Load"
                    android:textColor="@color/colorButtonText" />

                    

                <Space
                    android:layout_width="@dimen/middlePadding"
                    android:layout_height="wrap_content" />

                <Button
                    android:id="@+id/button_play"
                    android:layout_width="wrap_content"
                    android:layout_height="wrap_content"
                    android:layout_alignLeft="@+id/status"
                    android:layout_alignStart="@+id/status"
                    android:layout_below="@+id/statuses"
                    android:layout_weight="1"
                    android:background="@drawable/shape_rounded_corners"
                    android:stateListAnimator="@null"
                    android:text="Play"
                    android:textColor="@color/colorButtonText" />

            </LinearLayout>

            <LinearLayout
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                android:layout_alignEnd="@+id/status"
                android:layout_alignLeft="@+id/status"
                android:layout_alignRight="@+id/status"
                android:layout_alignStart="@+id/status"
                android:layout_below="@+id/buttons"
                android:layout_marginTop="@dimen/middlePadding"
                android:gravity="center"
                android:orientation="horizontal">

                <ImageView

                    android:layout_width="@dimen/point"
                    android:layout_height="@dimen/point"
                    android:src="@mipmap/point" />

                    

                <Space
                    android:layout_width="@dimen/textPadding"
                    android:layout_height="wrap_content" />

                <TextView
                    android:id="@+id/reward"
                    android:layout_width="wrap_content"
                    android:layout_height="wrap_content"
                    android:text="0"
                    android:textSize="@dimen/pointText" />

            </LinearLayout>


        </RelativeLayout>

    </RelativeLayout>

</RelativeLayout>

AdstirVideoReward Trong tài liệu hướng dẫn của adsitr được viết bằng ngôn ngữ java nhưng ở đây tôi viết bằng kotlin Tôi đã tạo một custom class để dùng trong project được dễ dàng hơn, tôi viết class này theo mô hình singleton CustomAdstirVideoReward.kt

import android.app.Activity
import com.ad_stir.interstitial.AdstirVideoAds
import com.ad_stir.videoreward.AdstirVideoReward
import com.ad_stir.videoreward.AdstirVideoRewardListener
import com.digital.playadstirvideoreward.R

class CustomAdstirVideoReward private constructor(private val activity: Activity) {

    private var adstirVideoReward: AdstirVideoReward? = null
    private var callbackVideoRewardListener: CallbackVideoRewardListener? = null

    private val adstirVideoRewardListener = object : AdstirVideoRewardListener {

        override fun onLoad(p0: Int) {
            if (callbackVideoRewardListener != null) {
                callbackVideoRewardListener!!.onLoad()
            }
        }

        override fun onReward(p0: Int) {
            if (callbackVideoRewardListener != null) {
                callbackVideoRewardListener!!.onReward()
            }
        }

        override fun onFailed(p0: Int) {
            if (callbackVideoRewardListener != null) {
                callbackVideoRewardListener!!.onFailed()
            }
        }

        override fun onStartFailed(p0: Int) {
            if (callbackVideoRewardListener != null) {
                callbackVideoRewardListener!!.onStartFailed()
            }
        }

        override fun onClose(p0: Int) {
            if (callbackVideoRewardListener != null) {
                callbackVideoRewardListener!!.onClose()
            }
        }

        override fun onStart(p0: Int) {
        }

        override fun onRewardCanceled(p0: Int) {
        }

        override fun onFinished(p0: Int) {
        }

    }
    fun setCallbackVideoRewardListener(listener: CallbackVideoRewardListener) {
        callbackVideoRewardListener = listener
    }

    fun setMediaUserId(mediaUserId: String) {
        AdstirVideoAds.setMediaUserID(mediaUserId)
    }

    fun initAdstirVideo() {
        val spotIds = intArrayOf(activity.resources.getInteger(R.integer.spot_id))
        AdstirVideoAds.init(activity, activity.getString(R.string.mediaId), *spotIds)
        adstirVideoReward = AdstirVideoReward(activity, activity.getString(R.string.mediaId), activity.resources.getInteger(R.integer.spot_id))
        adstirVideoReward!!.adstirVideoRewardListener = adstirVideoRewardListener
        adstirVideoReward!!.load()
    }

    fun loadVideoReward() {
        if (adstirVideoReward != null) {
            adstirVideoReward!!.load()
        }
    }

    fun showVideoReward() {
        if (adstirVideoReward != null && adstirVideoReward!!.canShow()) {
            adstirVideoReward!!.showRewardVideo()
        }
    }

    fun isPlayVideoReward(): Boolean = adstirVideoReward!!.canShow()

    fun onResume() {
        if (adstirVideoReward != null) {
            adstirVideoReward!!.resume()
        }
    }

    fun onPause() {
        if (adstirVideoReward != null) {
            adstirVideoReward!!.pause()
        }
    }

    fun onDestroy() {
        if (adstirVideoReward != null) {
            adstirVideoReward!!.destroy()
        }
    }

    companion object {
        private var instance: CustomAdstirVideoReward? = null

        fun getInstance(activity: Activity): CustomAdstirVideoReward {
            if (instance == null) {
                instance = CustomAdstirVideoReward(activity)
            }
            return instance!!
        }
    }
}

Tôi sẽ giải thích cho các bạn một số method quan trọng: Constructor của AdstirVideoReward

public AdstirVideoReward(Activity activity, String mediaId, int spotNo) 

Parameters activity - activity mediaId - Media ID spot - Frame No Trong đó mediaId và spot các bạn sẽ được khách hàng cung cấp hoặc truy cập vào trang chủ của adstir với account của khách hàng cung cấp( email và password ) như hình bên dưới:

Load video quảng cáo

public void load()

phương thức trên sẽ load video quảng cáo của adstir sau khi chúng ta đã set up thông tin về mediaId và spot

Show video quảng cáo

public void showRewardVideo()

Phương thức này sẽ bắt đầu play video quảng cáo

Ngoài ra còn một số phương thức khác như :

public void pause()
public void resume()
public void destroy()

những phương thức này sẽ đi cùng với các trạng thái của Activity như onPause, onResume, onDestroy

Interface AdstirVideoRewardListener

AdstirVideoReward có một interface được gọi là AdstirVideoRewardListener những những method callback rất cụ thể, giúp chúng ta có thể xử lý mọi logic chúng ta cần:

  • onLoad
  • onFailed
  • onStart
  • onStartFailed
  • onFinished
  • onReward
  • onRewardCanceled
  • onClose onLoad được gọi khi video quảng cáo đã được load về
public void onLoad(int spot_no)

onFailed được gọi khi load video quảng cáo về bị failed

public void onFailed(int spot_no)

onStart được gọi khi bắt đầu play video quảng cáo

public void onStart(int spot_no)

onStartFailed được gọi khi play video quảng cáo bị failed

public void onStartFailed(int spot_no)

onFinished được gọi khi video quảng cáo chạy xong

public void onFinished(int spot_no)

onReward được gọi khi quá trình reward được hoàn tất, khi nhận được callback từ adstir server

public void onReward(int spot_no)

onRewardCanceled nó được gọi khi quá trình reward chưa được xử lý xong

public void onRewardCanceled(int spot_no)

onClose được gọi khi người dùng click vào button close của adstir view

public void onClose(int spot_no)

Nhưng ở đây tôi đã tạo một interface của riêng mình CallbackVideoRewardListener.kt

interface CallbackVideoRewardListener {

    fun onLoad()

    fun onFailed()

    fun onStartFailed()

    fun onReward()

    fun onClose()

}

Việc cuối cùng của chúng ta là ghép những gì chúng ta đã làm với nhau. MainActivity.kt

package com.digital.playadstirvideoreward

import android.content.pm.PackageManager
import android.support.v7.app.AppCompatActivity
import android.os.Bundle
import android.widget.Button
import android.widget.TextView
import android.widget.Toast

class MainActivity : AppCompatActivity() {

    private lateinit var load: Button
    private lateinit var play: Button
    private lateinit var statusWaiting: TextView
    private lateinit var statusLoading: TextView
    private lateinit var statusLoaded: TextView
    private lateinit var reward: TextView
    private var point: Int = 0
    private var isRewarded = false
    private lateinit var videoReward: CustomAdstirVideoReward

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main)
        setUpView()
        setUpAdstir()

    }

    override fun onResume() {
        videoReward.onResume()
        if (isRewarded) {
            isRewarded = false
            Toast.makeText(this, R.string.reward_success, Toast.LENGTH_SHORT).show()
        }
        super.onResume()
    }

    override fun onPause() {
        videoReward.onPause()
        super.onPause()
    }

    override fun onDestroy() {
        videoReward.onDestroy()
        super.onDestroy()
    }

    private fun setUpAdstir() {
        val email: String = "[email protected]"
        val versionApp: Int = getAppVersion()
        val mediaUserId: String = "$email&$versionApp"

        videoReward = CustomAdstirVideoReward.getInstance(this)
        videoReward.setMediaUserId(mediaUserId)
        videoReward.initAdstirVideo()
        videoReward.setCallbackVideoRewardListener(object : CallbackVideoRewardListener {
            override fun onLoad() {
                play.isEnabled = true
                setStatus(LoadStatus.LOADED)
            }

            override fun onFailed() {
                load.isEnabled = true
                setStatus(LoadStatus.LOADING)
            }

            override fun onStartFailed() {
                load.isEnabled = true
                setStatus(LoadStatus.WAITING)
            }

            override fun onReward() {
                isRewarded = true
                reward.text = (++point).toString()
            }

            override fun onClose() {
                load.isEnabled = true
                setStatus(LoadStatus.WAITING)
            }
        })
    }

    private fun setUpView() {
        statusWaiting = findViewById<TextView>(R.id.status_waiting)
        statusLoading = findViewById<TextView>(R.id.status_loading)
        statusLoaded = findViewById<TextView>(R.id.status_loaded)

        reward = findViewById<TextView>(R.id.reward)

        play = findViewById<Button>(R.id.button_play)
        play.isEnabled = false
        play.setOnClickListener {
            if (videoReward.isPlayVideoReward()) {
                play.isEnabled = false
                setStatus(LoadStatus.WAITING)
                videoReward.showVideoReward()
            }
        }

        load = findViewById<Button>(R.id.button_load)
        load.setEnabled(true)
        load.setOnClickListener {
            load.isEnabled = false
            setStatus(LoadStatus.LOADING)
            videoReward.loadVideoReward()
        }

    }

    private fun setStatus(status: LoadStatus) {

        setTextViewEnabled(statusWaiting, false)
        setTextViewEnabled(statusLoading, false)
        setTextViewEnabled(statusLoaded, false)

        when (status) {
            LoadStatus.WAITING -> setTextViewEnabled(statusWaiting, true)
            LoadStatus.LOADING -> setTextViewEnabled(statusLoading, true)
            LoadStatus.LOADED -> setTextViewEnabled(statusLoaded, true)
        }
    }

    private fun setTextViewEnabled(t: TextView, enable: Boolean) {
        if (enable) {
            t.setTextColor(resources.getColor(R.color.colorActiveStatusText))
            t.setBackgroundResource(R.color.colorActiveStatusBackground)
        } else {
            t.setTextColor(resources.getColor(R.color.colorInactiveStatusText))
            t.setBackgroundResource(R.color.colorInactiveStatusBackground)
        }
    }


    private fun getAppVersion(): Int {
        val packageManager = this.packageManager
        var versionCode: Int = try {
            val packageInfo = packageManager.getPackageInfo(this.packageName, 0)
            packageInfo.versionCode
        } catch (e: PackageManager.NameNotFoundException) {
            0
        }
        return versionCode
    }
}

Để chạy được video quảng cáo các bạn phải kết nó VPN Các bạn có thể download toàn bộ source code tại đây

Tiệu tam khảo https://github.com/united-adstir/AdStir-Integration-Guide-Android/wiki/AdstirVideoRewardListener-Interface-Reference https://github.com/united-adstir/AdStir-Integration-Guide-Android/wiki/AdstirVideoAds-Class-Reference#parameters https://github.com/united-adstir/AdStir-Integration-Guide-Android/wiki/AdstirVideoReward-Class-Reference