AndroidStudio集成Admob

前段时间公司的游戏开发的差不多了,集成了一些SDK,本次要说的就是其中之一的Admob,这个变现sdk就不用介绍了吧,看到这个文章的肯定都知道是什么,实在不清楚就去玩玩度娘。其实Android应用接入Admob没什么复杂的地方,只不过手上这个应用是CocosCreator开发的游戏,就是在一个Activity上面加了个GLView,然后渲染,要接入SDK需要稍微绕一点点弯路,然后国内的网络环境也堪忧,有可能会在测试的时候带来麻烦。

Android GL线程与UI线程通信

熟悉Cocos的同学都知道,我们的游戏都是在一个GLview上进行的,游戏开发的语言是js,要想与UI线程通信,就需要引擎提供的api

1
jsb.reflection.callStaticMethod('类路径', '方法名', '参数签名', '参数列表');

只有静态方法可以通过这个方式进行调用,关于这个方法的详细说明就不过多赘述,官方文档有很详细的讲解 [ 传送门 ]

接入Admob依赖库

首先在工程级的build.gradle中添加依赖(最外层的那个build.gralde文件)

1
2
3
4
5
6
7
8
allprojects {
repositories {
jcenter()
maven {
url "https://maven.google.com"
}
}
}

再在app级的build.gradle中添加相关库的依赖(定义了applicationid等应用信息的那个build.gradle)

1
2
3
4
dependencies {
//new dependence
implementation 'com.google.android.gms:play-services-ads:15.0.0'
}

到这里库的配置就弄完了,可以开始撸代码了

注意,Admob要求的Target Android API level 最低是14,不然编译阶段会提示你修改

接入Banner广告

Banner广告就是一个显示在屏幕某个位置的横幅广告,难以避免地会占用游戏节目,是个很不友好的广告,在Android原生应用中,可以直接在要植入广告的界面的xml布局里面直接把banner广告布局填进去,适配也非常的简单,但是我这游戏就不行,cocos的长度单位与Android的不一样,需要经过一些换算才能得到正确的大小,Banner广告展示的大小,SDK有提供了很多尺寸的选择,其中Smart Banner是SDK自己进行适配,如果广告内容把游戏内容遮挡了,这肯定是非常不好的,所以我非常咸鱼的选择了最小的尺寸(快速迭代嘛,以后再优化 >_< ),下面直接贴代码

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
//首先初始化Admob mActivity就是游戏的主Activity,admob相关的id找让你接sdk的人要,嘻嘻
MobileAds.initialize(mActivity,mActivity.getResources().getString(R.string.admob_appid));

mActivity.runOnUiThread(new Runnable() {
@Override
public void run() {
bannerAd = new AdView(mActivity);
bannerAd.setAdUnitId(mActivity.getResources().getString(R.string.admob_banner_id));
bannerAd.setAdSize(AdSize.BANNER);
bannerAd.setAdListener(bannerAdListener);

AdRequest adRequest = new AdRequest.Builder()
.addTestDevice("test_device_id")
.build();
bannerAd.loadAd(adRequest);
}
});
public static AdListener bannerAdListener = new AdListener(){
@Override
public void onAdLoaded() {
mActivity.runOnUiThread(new Runnable() {
@Override
public void run() {
if(bannerAd.getParent() == null){
FrameLayout.LayoutParams params = new FrameLayout.LayoutParams(FrameLayout.LayoutParams.MATCH_PARENT, FrameLayout.LayoutParams.WRAP_CONTENT);
params.gravity = Gravity.BOTTOM;
mActivity.addContentView(bannerAd, params);
}else{ }
}
});
}

@Override
public void onAdFailedToLoad(final int errorCode) { }

@Override
public void onAdOpened() { }

@Override
public void onAdLeftApplication() { }

@Override
public void onAdClosed() { });
}

};

由于我们不能直接在GL thread去修改UI thread,所以我们这里用了个runOnUIthread包装了一下,也可以用其他方式去实现
bannerAd.setAdListener(bannerAdListener) 是广告的生命周期的监听函数,广告的状态发生变化都会再这里得到通知,我这里在广告Load成功后对banner广告的UI进行了操作,如果Banner没有添加到Activity中就把它添加进去,并且把它放到了屏幕最底部,之所以加判断是因为Banner是会自己进行一定频率的刷新,如果每次Load成功都去添加一个到场景,老板知道了就要开除我了

接入插屏广告

插屏广告·是一种完全覆盖游戏的广告,需要用户手动点击关闭按钮才会消失,这个的接入相比Banner就简单点了,由于产品要求要确保广告在某个时间点弹出来,所以插屏这里我预先进行了Load操作,然后在要展示的时候才show它,因为加载插屏是有一定的延迟的,如果广告内容是视频的话,延迟就更明显了,还是贴上代码

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
//加载插屏广告
mActivity.runOnUiThread(new Runnable() {
@Override
public void run() {
Log.e(DEBUG_TAG,"loadInterstitial");
AdRequest request = new AdRequest.Builder()
.addTestDevice("test_device_id")
.build();
interstitialAd.setAdListener(interstitialAdListener);
interstitialAd.loadAd(request);
}
});
//展示插屏广告
//一定要确保在UI线程操作
mActivity.runOnUiThread(new Runnable() {
@Override
public void run() {
if(interstitialAd.isLoaded()){
interstitialAd.show();
}else if(interstitialAd.isLoading()){
}else{
//如果没有loading,或者load失败了就进行load
loadInterstitial(curInterstitialAdPos);
}
}
});
public static AdListener interstitialAdListener = new AdListener(){}

接入视频广告

视频广告的接入和插屏几乎一样,非常简单,这次需要用到广告的回掉,因为这涉及到观看广告的奖励的发放,
talk is cheap, show me the code~

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
//load
mActivity.runOnUiThread(new Runnable() {
@Override
public void run() {
AdRequest adRequest = new AdRequest.Builder().build();
rewardedVideoAd.loadAd(mActivity.getResources().getString(R.string.admob_rewardedvideo_id),adRequest);
}
});
//show
mActivity.runOnUiThread(new Runnable() {
@Override
public void run() {
if(rewardedVideoAd.isLoaded()){
rewardedVideoAd.show();
}else{
loadRewardedVideo();
}
}
});
//广告回掉
//收到这个回掉表示用户完整观看了视频广告,需要发放奖励
@Override
public void onRewarded(RewardItem rewardItem) {
Log.e(DEBUG_TAG,"onRewarded");
}

Always test with test ads !

进行测试的时候尽量使用文档提供的测试id,一来可以排除掉市场人员app广告信息配置错误,二来这也是官方要求的(不要刷广告),其实刷也没用,刷着刷着就不给你展示广告了


我为什么突然没广告看了!

先别急,这一般不是我们程序员的问题(先甩锅),广告没有按预期播放一般有4个原因:
1.INTERNAL_ERROR(内部错误) 2.INVALID_REQUEST(非法请求) 3.NETWORK_ERROR(网络错误) 4.NOT_FILL(未填充)
所以测试的时候最好能把这些信息实时的输出出来,以便在没能成功展示广告时看到是什么原因(=_=)

有了AndroidStudio,接入广告真的简单了好多,其实还有原生广告和中介还么有说到,原生广告真的是非常的坑爹,这里简单说下中介,通过中介我们可以去接入一些其他的广告来源,目前文章中就能得到来自Admob的广告,通过一些配置就可以得到来自其他广告联盟的广告了,这两个就下次再写一篇讲讲