这里先附上谷歌AdMob API官方说明文档的地址,如果有不明白或者想详细了解的可以点击进入 查看学习:https://developers.google.com/admob/android/rewarded-video
顺便附上广告请求错误码对应原因查看的网址: https://developers.google.com/android/reference/com/google/android/gms/ads/AdRequest
话不多说,在项目里面需要用到的加载谷歌广告的地方比较多,重复代码多次写没有必要,所以封装了一个工具类,直接调用方法就行,你在使用时可以更加细节封装优化一下~
LoadGoogleAd.kt代码:
import android.app.Activity
import android.util.Log
import android.widget.Toast
import com.google.android.gms.ads.AdListener
import com.google.android.gms.ads.AdRequest
import com.google.android.gms.ads.InterstitialAd
import com.google.android.gms.ads.MobileAds
import com.google.android.gms.ads.reward.RewardItem
import com.google.android.gms.ads.reward.RewardedVideoAd
import com.google.android.gms.ads.reward.RewardedVideoAdListener
import com.wj.R
/**
* @time 2018/6/11
* @author JunJieW
* @since 1376881525@qq.com
* @description 谷歌广告加载封装工具类
*/
class LoadGoogleAd {
private val TAG = "LoadGoogleAd"
private var activity: Activity? = null
internal var mInterstitialAd: InterstitialAd? = null
lateinit var mRewardedVideoAd: RewardedVideoAd
constructor(activity: Activity, adType: String) {
this.activity = activity
//google ad 初始化
MobileAds.initialize(activity,activity.resources.getString(R.string.google_app_id))
if (adType == "inster") {
// 插屏ad
mInterstitialAd = InterstitialAd(activity)
initInterstitialAdListener()
mInterstitialAd!!.adUnitId = activity.resources.getString(R.string.google_ad_interstitial_unit_id)
mInterstitialAd!!.loadAd( AdRequest.Builder().build())
Log.d(TAG, "The InterstitialAd")
} else if (adType == "video") {
// 视频ad
mRewardedVideoAd = MobileAds.getRewardedVideoAdInstance(activity)
initVideoAdListener()
mRewardedVideoAd.loadAd(activity.resources.getString(R.string.google_ad_video_unit_id), AdRequest.Builder().build())
Log.d(TAG, "The VideoAd")
}
}
private fun initVideoAdListener() {
mRewardedVideoAd.rewardedVideoAdListener = object :RewardedVideoAdListener{
override fun onRewarded(reward: RewardItem) {
Toast.makeText(activity, "onRewarded! currency: ${reward.type} amount: ${reward.amount}",
Toast.LENGTH_SHORT).show()
// Reward the user.做奖励用户的操作
}
override fun onRewardedVideoAdLeftApplication() {
Log.d(TAG, "onRewardedVideoAdLeftApplication")
}
override fun onRewardedVideoAdClosed() {
Log.d(TAG, "onRewardedVideoAdClosed")
mRewardedVideoAd.loadAd(activity!!.resources.getString(R.string.google_ad_video_unit_id), AdRequest.Builder().build())
}
override fun onRewardedVideoAdFailedToLoad(errorCode: Int) {
Log.d(TAG, "onRewardedVideoAdFailedToLoad")
}
override fun onRewardedVideoAdLoaded() {
Log.d(TAG, "onRewardedVideoAdLoaded")
}
override fun onRewardedVideoAdOpened() {
Log.d(TAG, "onRewardedVideoAdOpened")
}
override fun onRewardedVideoStarted() {
Log.d(TAG, "onRewardedVideoStarted")
}
override fun onRewardedVideoCompleted() {
Log.d(TAG, "onRewardedVideoCompleted")
}
}
}
private fun initInterstitialAdListener() {
//记录插屏广告展示的次数,每间隔三次才进行展示
var showInterstitialAdNum = SharedPreferencesUnitls.getParam2(activity,"showInterstitialAdNum")
if (StringUtils.StringIsNull(showInterstitialAdNum)){
}else{
SharedPreferencesUnitls.setParam(activity,"showInterstitialAdNum","1")
}
mInterstitialAd!!.adListener = object: AdListener() {
override fun onAdLoaded() {
Log.d(TAG, "The interstitial onAdLoaded")
}
override fun onAdFailedToLoad(errorCode: Int) {
Log.d(TAG, "The interstitial onAdFailedToLoad;errorCode==$errorCode")
}
override fun onAdOpened() {
Log.d(TAG, "The interstitial onAdOpened")
}
override fun onAdLeftApplication() {
Log.d(TAG, "The interstitial onAdLeftApplication")
}
override fun onAdClosed() {
Log.d(TAG, "The interstitial onAdClosed")
mInterstitialAd!!.loadAd(AdRequest.Builder().build())
}
}
}
//Show the ad 插屏广告
fun showInterstitialAd() {
//记录插屏广告展示的次数,每间隔三次才进行展示
var showInterstitialAdNum = SharedPreferencesUnitls.getParam2(activity,"showInterstitialAdNum")
if (StringUtils.StringIsNull(showInterstitialAdNum)){
if (showInterstitialAdNum.toInt()%4==0){
if (mInterstitialAd!!.isLoaded){
mInterstitialAd!!.show()
}
}
SharedPreferencesUnitls.setParam(activity,"showInterstitialAdNum",(showInterstitialAdNum.toInt()+1).toString())
}else{
SharedPreferencesUnitls.setParam(activity,"showInterstitialAdNum","1")
}
}
//Show the ad video广告
fun showRewardedVideoAd(){
//记录插屏广告展示的次数,每间隔三次才进行展示
var showInterstitialAdNum = SharedPreferencesUnitls.getParam2(activity,"showVideoAdNum")
if (StringUtils.StringIsNull(showInterstitialAdNum)){
if (showInterstitialAdNum.toInt()%4==0){
if (mRewardedVideoAd.isLoaded) {
mRewardedVideoAd.show()
}
}
SharedPreferencesUnitls.setParam(activity,"showVideoAdNum",(showInterstitialAdNum.toInt()+1).toString())
}else{
SharedPreferencesUnitls.setParam(activity,"showVideoAdNum","1")
}
}
}
调用关键代码:
//第一步 声明工具类变量
private LoadGoogleAd googleAdUti_intes = null;
private LoadGoogleAd googleAdUti_video = null;
//第二步 在onCreate方法中初始化,传递广告类型的标识
googleAdUti_intes = new LoadGoogleAd(getActivity(), "inster");
googleAdUti_video = new LoadGoogleAd(getActivity(), "video");
//第三步 在你想展示广告的地方调用展示广告的方法
//加载打开文章的google插屏广告
googleAdUti_intes.showInterstitialAd();
//加载的google视频广告
googleAdUti_video.showRewardedVideoAd();
至此加载谷歌广告就已经不是问题了!
插屏广告加载效果图:
视频广告加载效果图:
最后值得一提的是,谷歌广告官方建议为了客户体验好,加载广告的时候不用太长时间,避免用户不愉快体验,应该在需要调用展示广告的activity或者fragment中,提前将广告请求建立,只不过不show出来,然后当你需要展示的时候只需要判断当前广告对象是否是加载完成状态,如果是则show出来,这样速度很快,我做时就被这里坑过,当用户点击列表的一个item时才初始化一个广告请求,然后加载一个插屏广告,竟然耗时能超过3秒多有时候,体验巨差,自己都不能忍,后来优化为现在的activity或者fragment创建时就初始化广告请求只是不show出来,当需要展示的时候直接show方法调用就行,还要记得在广告关闭的时候重新发起下一个广告请求的创建,只是不show展示出来就行~
过了一段时间,再做别的项目的时候又遇到了一些新的问题,也挺坑的,在这里补充一下作为爬坑记录,以防长时间不用了再遇到忘记。
异常1:W/Ads: Failed to load ad: errorcode == 3
完整的异常日志输出:
09-12 11:02:43.932 7914-7914/com.mobile I/Ads: Starting ad request.
09-12 11:02:43.932 7914-7914/com.mobile I/Ads: This request is sent from a test device.
09-12 11:02:44.067 7914-8007/com.mobile W/Ads: Invoke Firebase method getInstance error.
09-12 11:02:44.067 7914-8007/com.mobile W/Ads: The Google Mobile Ads SDK will not integrate with Firebase. Admob/Firebase integration requires the latest Firebase SDK jar, but Firebase SDK is either missing or out of date
09-12 11:02:45.596 7914-8016/com.mobile I/Ads: No fill from ad server.
09-12 11:02:49.336 7914-7914/com.mobile W/Ads: Failed to load ad: 3
造成原因:这个错误的描述是:ERROR_CODE_NO_FILL,广告没有填充。而造成的原因可能是:
1.正式版的没有发布,在app没有上线之前,都是测试的广告位id,没有正式的广告位id,所以可以直接使用官方给的测试广告位id,这里附上官方链接:https://developers.google.com/admob/android/test-ads
解决方案:使用官方给的测试广告位id,这里附上各种广告类型的官方给的测试id的截图,可以各自对号入座找自己适合的,我这里是Rewarded Video的
// 修改前
mRewardedVideoAd!!.loadAd(resources.getString(R.string.google_ad_video_unit_id), AdRequest.Builder()
// 修改后 把这里的正式id换位官方给的测试广告位id
mRewardedVideoAd!!.loadAd("ca-app-pub-3940256099942544/5224354917", AdRequest.Builder().build())
2.你不是测试设备
解决方案:添加自己的测试设备号,需要从log日志里面寻找,如下图
代码贴出来:
mRewardedVideoAd!!.loadAd("ca-app-pub-3940256099942544/5224354917", AdRequest.Builder()
.addTestDevice("176998C7DFA2CC4F0FDC2C42DD42ACF8") // An example device ID ,this code you should get from your log info and replace it ,after soon you can run and for a test。
.build())
哈哈,注释写成英文了,不过相信你一定能看懂我这傻瓜式的英文注释,哈哈