【Unity与Android】02-在Unity导出的Android工程中接入Google Admob广告

  • 2019 年 10 月 6 日
  • 筆記

我在上一篇文章 【Unity与Android】01-Unity与Android交互通信的简易实现) 中介绍了Unity与Android通讯的基本方法。

这一篇开始进入应用阶段,这次要介绍的是如何在Android工程中接入Google的AdMob。

 

关于AdMob

AdMob是Google的一个广告平台,现在市面上(国外)的大部分免费游戏都是靠接入AdMob广告赚钱。

AdMob提供了iOS,Android,Unity以及Cocos四大平台的SDK。

如果想在Unity游戏中接入AdMob,最快的方法是使用Google提供的GoogleMobileAdsPlugin.unitypackage。这个插件可以在Unity Assets Store中找到,也可以去github上下载,地址

https://github.com/googleads/googleads-mobile-unity

鉴于Unity制作的移动端游戏最终还是会被转换为Android应用和iOS应用,所以为Unity游戏接入广告也可以在Android端和iOS端进行。

本文要介绍的就是如何在Android端为Unity游戏接入AdMob广告。

 

广告类型

AdMob提供的广告有四种类型:横幅广告(Banner Ads)、插页式广告(Interstitial Ads)、激励广告(Rewarded Video Ads)和原生广告(Native Ads)。

横幅广告:

横幅广告是在应用布局中占据一处位置的矩形图片或文字广告。用户与应用互动时,这类广告会停留在屏幕上,并且可在一段时间后自动刷新。

插页式广告:

插页式广告是全屏广告,它会覆盖其托管应用的整个界面。这些广告通常会在应用流程的自然过渡点(例如活动之间或游戏关卡之间的暂停时段)展示。当应用展示插页式广告时,用户可以选择点按广告,访问其目标网址,也可以将其关闭,返回应用。

激励广告:

激励广告是全屏视频广告,用户选择观看视频,以换取应用内奖励。

原生广告:

原生广告是通过平台原生的UI组件呈现给用户的广告,比如微博、JD等软件启动时显示的广告。

 

这几种类型的广告,横幅、插页、激励广告在游戏中都比较常用。

下面将一一介绍这几种广告的接法(原生广告通常用的较少,且制作有点复杂,这里就不细述了,有需要的可以去AdMob的网站查看相关教程)。

 

一、准备工作

 1、创建一个Unity项目。

  该项目上只设一个场景,场景中放三个按钮,用于发起对广告的调用。如下图

 

 

2、将上述项目导出为Android的Gradle工程。(暂时不写任何代码,以后文章里会补充)

3、在Android Studio中打开上述工程。我这里这个工程的名称为AdMobProject,后文的操作都在这个工程中进行。

 

二、导入AdMob SDK并初始化

  1、导入SDK

  将工程切换到Project视图,在工程目录下找到build.gradle文件并打开,在 buildscript { repositories { 后添加google(),如果已经存在, 则不用重复添加。添加完成的代码块如下:

// GENERATED BY UNITY. REMOVE THIS COMMENT TO PREVENT OVERWRITING WHEN EXPORTING AGAIN    buildscript {      repositories {          google()          jcenter()      }        dependencies {          classpath 'com.android.tools.build:gradle:3.2.0'  }  }

  在与buildscript平级的dependencies里添加 implementation ‘com.google.android.gms:play-services-ads:18.2.0’

  添加完成的代码块如下:  

  

 

   修改完成后,IDE会提示Gradle files have changed…,点击 Sync Now进行同步。

  这个同步操作,会将AdMob SDK以及其依赖库下载下来。同步结束后,打开External Libraries能看到相应的库文件。

 

  2、SDK初始化

  在src目录下找到UnityPlayerActivity.java文件,在UnityPlayerActivity类中有一个onCreate方法,这个就是游戏app的入口。

  初始化的方法1:

  在onCreate方法的 mUnityPlayer.requestFocus(); 语句之后,用 MobileAds.initialize进行初始化。代码如下:  

        // MobileAds初始化的方法1,有监听,无法设置appId ;appId可以在AndroidManifest.xml中设置          // AdMob Init          MobileAds.initialize(this, new OnInitializationCompleteListener() {              @Override              public void onInitializationComplete(InitializationStatus initializationStatus) {                  Log.i("AdMob", "-----Admob初始化完成");              }          });

  这是一个带监听的初始化方法,但是不包含广告对应的appId,如果使用这种方法,需要在AndroidManifest.xml文件中指明appid。

  初始化的方法2:

  还是在同样的位置添加MobileAds.initialize调用,区别在于参数不一样。这个方法的第二个参数为appid,代码如下:

        //MobileAds初始化的方法2,可以指定appId;当AndroidManifest中也设置了appId时,以AndroidManifest为准          // Sample AdMob App ID: ca-app-pub-3940256099942544~3347511713          MobileAds.initialize(this, "ca-app-pub-3940256099942544~3347511713");//测试用的AppId

  如果使用此种方法初始化,而在AndroidManifest.xml也指明了appid,推测可能是以xml文件中的为准(根据使用其它插件的经验推测的,未验证。不放心就只使用一种方式即可)

  这里的”ca-app-pub-3940256099942544~3347511713″是Google提供的用于测试一个样例appId。

  以上两种初始化的方法,选择一个即可。

  我这里选择方法2,以下是添加完成后的图:

    

 

 

三、接入横幅广告(Banner Ads)

  上一步的初始化完成之后,就能进行banner广告的接入了。

  1、 在UnityPlayerActivity类中添加一个初始化banner广告的方法bannerAdInit。代码如下:  

    /**       * banner广告初始化       * @param adUnitId  广告id       * @param size 广告尺寸       */      private  void bannerAdInit (String adUnitId, AdSize size) {          //创建广告视图          AdView bannerAdView = new AdView(this);          //设置广告尺寸          bannerAdView.setAdSize(size);          //设置广告ID          bannerAdView.setAdUnitId(adUnitId);          //请求广告          AdRequest adRequest = new AdRequest.Builder().build();          bannerAdView.loadAd(adRequest);          //添加监听          bannerAdView.setAdListener(new AdListener() {              @Override              public void onAdLoaded() {                  Log.i("BannerAd", "banner广告加载完成");              }                @Override              public void onAdFailedToLoad(int errCode) {                  Log.i("BannerAd", "banner广告加载失败, err_code:" + errCode);              }                @Override              public void onAdOpened() {                  Log.i("BannerAd", "banner广告被打开");              }          });            //声明一个布局参数(MATCH_PARENT为填充父级,WRAP_CONTENT为包裹内容)          FrameLayout.LayoutParams fllp = new FrameLayout.LayoutParams(                  LinearLayout.LayoutParams.MATCH_PARENT,                  LinearLayout.LayoutParams.WRAP_CONTENT);            //设置布局对齐方式为:垂直对齐到底,水平居中          fllp.gravity = Gravity.BOTTOM|Gravity.CENTER_HORIZONTAL;            //添加到View          addContentView(bannerAdView, fllp);      }

    关于代码的说明,直接看注释即可。

2、在onCreate方法中添加对bannerAdInit的调用,代码如下:

        //横幅(banner)广告初始化          // Sample AdMob banner ad id: ca-app-pub-3940256099942544/6300978111          bannerAdInit("ca-app-pub-3940256099942544/6300978111", AdSize.BANNER);

 这条语句位于初始化语句之后即可。“ca-app-pub-3940256099942544/6300978111″是Google提供的banner广告单元id样例,可以直接使用,直到你申请了正式的广告id。

3、测试

  bannerAdInit添加完成之后,配置一下Android Studio的SDK以及模拟器。

  然后运行app,app安装到模拟器之后,能看到,在屏幕下方出现了测试用的Banner广告。见下图:

    

 

 

 Banner广告的接入就算实现了,接下来看插页广告的接法。

 

四、接入插页广告(Interstitial Ads)

  1、 在UnityPlayerActivity类中添加一个初始化插页广告的方法interstitialAdInit。代码如下: 

    /**       * 插页广告初始化       * @param adUnitId 广告id       */      private void interstitialAdInit (String adUnitId) {          InterstitialAd interstitialAd = new InterstitialAd(this);            interstitialAd.setAdUnitId(adUnitId);            interstitialAd.loadAd(new AdRequest.Builder().build());            Log.i("interstitalAd", "is Loaded:" + interstitialAd.isLoaded());            interstitialAd.setAdListener(new AdListener() {              @Override              public void onAdClosed() {                  super.onAdClosed();                  Log.i("interstitalAd", "插页广告被关闭");                    // Load the next interstitial.插页广告被关闭时预加载下一次的广告                  //interstitialAd.loadAd(new AdRequest.Builder().build());             }  
@Override
public void onAdLoaded() { super.onAdLoaded(); Log.i("interstitalAd", "插页广告加载完成");           //广告加载完成之后直接显示 interstitialAd.show(); } }); }

  2、依照banner广告,在onCreate方法中添加对interstitialAdInit的调用,代码如下:

        //插页(interstitial)广告初始化          // Sample AdMob interstitial ad id: ca-app-pub-3940256099942544/1033173712          interstitialAdInit("ca-app-pub-3940256099942544/1033173712");

  代码位置在AdMob初始化之后即可。参数同样为一个测试用的插页广告id。

 3、重新运行app,等待app启动后,能看到一个插页广告被显示出来。如下图:

  

 

   要注意的是,我这是为了测试,直接让app启动后就进行广告初始化,并在广告加载完成后立即显示出来。这是不太符合正常的使用场景的。在游戏中,广告初始化和加载可以提前进行,但显示应该是可控的。

  所以,插页广告的显示方法,应该提出来,由外部(游戏逻辑)调用。

  插页广告接入完成。

 

五、接入激励广告(Rewarded Video Ads)

  1、在UnityPlayerActivity类中声明两个成员变量rewardedVideoAd(RewardedVideoAd类型)和rewardVidewAdUnitId(String类型),如下:

    //激励视频广告      private RewardedVideoAd rewardedVideoAd;      //激励视频广告Id      private  String rewardVidewAdUnitId;

 

  2、在UnityPlayerActivity类中添加一个初始化插页广告的方法interstitialAdInit。代码如下:

    /**       * 激励视频(Rewarded Video)广告初始化       */      private void rewardedVideoAdInit (String adUnitId) {          // Use an activity context to get the rewarded video instance.          rewardedVideoAd = MobileAds.getRewardedVideoAdInstance(this);            rewardedVideoAd.setRewardedVideoAdListener(this);            rewardVidewAdUnitId = adUnitId;      }

  3、在UnityPlayerActivity类中添加一个加载激励视频的方法loadRewardedVideoAd。代码如下:

    //加载激励视频      private void loadRewardedVideoAd() {          rewardedVideoAd.loadAd(rewardVidewAdUnitId, new AdRequest.Builder().build());      }

  4、在UnityPlayerActivity类中添加一个显示激励视频的方法showRewardedVideoAd。代码如下:  

    //显示激励视频      public void showRewardedVideoAd() {          if (rewardedVideoAd.isLoaded()) {              rewardedVideoAd.show();          } else {              Toast.makeText(this, "video is not ready.", Toast.LENGTH_SHORT);          }      }

  5、在第1步的interstitialAdInit方法写法之后,应该出报红,提未本类无法成为激励视频广告的监听。

   解决办法是让UnityPlayerActivity 类实现RewardedVideoAdListener接口。

   a.在extends Activity后添加 implements RewardedVideoAdListener,如下:  

public class UnityPlayerActivity extends Activity implements RewardedVideoAdListener

   b.根据提示,在本类中实现RewardedVideoAdListener对应的方法,代码如下:  

    /**---------------激励视频监听实现 begin-------------------*/      @Override      public void onRewardedVideoAdLoaded() {          Toast.makeText(this, "onRewardedVideoAdLoaded", Toast.LENGTH_SHORT).show();          showRewardedVideoAd();      }        @Override      public void onRewardedVideoAdOpened() {          Toast.makeText(this, "onRewardedVideoAdOpened", Toast.LENGTH_SHORT).show();      }        @Override      public void onRewardedVideoStarted() {          Toast.makeText(this, "onRewardedVideoStarted", Toast.LENGTH_SHORT).show();      }        @Override      public void onRewardedVideoAdClosed() {          Toast.makeText(this, "onRewardedVideoAdClosed", Toast.LENGTH_SHORT).show();            // Load the next rewarded video ad.          loadRewardedVideoAd();      }        @Override      public void onRewarded(RewardItem reward) {          Toast.makeText(this, "onRewarded! currency: " + reward.getType() + "  amount: " +                  reward.getAmount(), Toast.LENGTH_SHORT).show();      }        @Override      public void onRewardedVideoAdLeftApplication() {          Toast.makeText(this, "onRewardedVideoAdLeftApplication",                  Toast.LENGTH_SHORT).show();      }        @Override      public void onRewardedVideoAdFailedToLoad(int i) {          Toast.makeText(this, "onRewardedVideoAdFailedToLoad", Toast.LENGTH_SHORT).show();      }        @Override      public void onRewardedVideoCompleted() {          Toast.makeText(this, "onRewardedVideoCompleted", Toast.LENGTH_SHORT).show();      }      /**---------------激励视频监听实现 end-------------------*/

激励视频监听实现的代码

  其中,我在广告加载完成后进行了对showRewardedVideoAd的调用以显示广告。并在视频广告关闭后进行了重新加载。

  5、依照banner和插页广告的做法,在onCreate方法中添加对rewardedVideoAdInit的调用,代码如下:
        //激励视频(Rewarded Video)广告初始化          // Sample AdMob interstitial ad id: ca-app-pub-3940256099942544/5224354917          rewardedVideoAdInit("ca-app-pub-3940256099942544/5224354917");          //预加载视频          loadRewardedVideoAd();

  在rewardedVideoAdInit之后还需要调用loadRewardedVideoAd以便让广告视频可以提前加载。

  6、测试。

  重新运行项目,等待模拟器上app启动后,能看到一个7秒的视频广告显示。

 

 关闭视频广告后,等几秒又会重新加载一个视频出来(前边的代码有说明,在关闭后重新加载了)。

和插页广告一样,视频广告的显示应该是由外部(游戏逻辑)调用的。这里为了测试,是直接在加载后就是显示。

激励广告的接入也完成。

 

总结

AdMob的接入,总的来看,还是比较简单的,且官方也提供了详细的文档和案例,基本照着做就能会。唯一的问题是,看这些文档需要会翻墙。

 

后续

由于UnityPlayerActivity是Unity自动生成的,我们在此类中实现SDK的接入,对于项目的更新及其不方便。总不能每次打包,都要倒腾一回UnityPlayerActivity.java吧。

后续计划就是用前一篇文章提到的方法,将接入AdMob SDK相关的逻辑都放放到一个jar包里,直接在Unity里调用。

 

下篇再见。