Hướng Dẫn Chạy Quảng Cáo AdstirVideoReward Của Adstir Viết Bằng Kotlin
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 ...
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 load và button 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_awidth="match_parent" android:layout_height="match_parent" android:padding="@dimen/padding"> <RelativeLayout android:layout_awidth="match_parent" android:layout_height="wrap_content" android:layout_alignParentStart="true" android:layout_centerInParent="true" android:background="@color/colorLoaderArea"> <RelativeLayout android:layout_awidth="wrap_content" android:layout_height="wrap_content" android:layout_centerHorizontal="true" android:layout_centerVertical="true"> <TextView android:id="@+id/status" android:layout_awidth="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_awidth="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_awidth="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_awidth="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_awidth="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_awidth="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_awidth="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_awidth="@dimen/middlePadding" android:layout_height="wrap_content" /> <Button android:id="@+id/button_play" android:layout_awidth="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_awidth="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_awidth="@dimen/point" android:layout_height="@dimen/point" android:src="@mipmap/point" /> <Space android:layout_awidth="@dimen/textPadding" android:layout_height="wrap_content" /> <TextView android:id="@+id/reward" android:layout_awidth="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 = "le.quang.hoa@framgia.com" 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