BearZPY Blog

Hi, nice to meet you

BearZPY's avatar BearZPY

Android Firebase AdMob 横幅广告

Firebase

Firebase 是一个用于开发移动应用和 Web 应用的开发平台,自从被 Google 收购后融合了 Google 的云服务。Firebase 的初始产品是一个实时数据库,它提供了一个 API,允许开发人员在多个客户端之间存储和同步数据。随着时间的推移,它已经扩大了产品线,成为一个完整的应用程序开发套件。

AdMob

AdMob 覆盖 200 多个国家,是美国最大的移动广告平台。开发者可以直接使用 AdMob SDK 展示广告来获得收益,而无需与广告投放者沟通。

接入 AdMob SDK

这里主要介绍如何使用横幅式广告。横幅广告:基本广告格式,在设备屏幕的顶部和底部展示。

使用 AdMob SDK 主要有 4 个步骤:

  • 在 build.gradle 中添加依赖。
  • 在 manifest 中声明权限。
  • 在 layout 文件中添加布局。
  • 在 activity 代码中添加加载代码。

横幅式广告效果:
横幅式广告

在 build.gradle 中添加依赖

修改 Project 目录下的 build.gradle,在 buildscript 闭包里的 dependencies 闭包中增加 com.google.gms:google-services 的插件。

// Top-level build file where you can add configuration options common to all sub-projects/modules.

buildscript {
    repositories {
        jcenter()
    }
    dependencies {
        classpath 'com.android.tools.build:gradle:2.3.2'
        classpath 'com.google.gms:google-services:3.0.0'

        // NOTE: Do not place your application dependencies here; they belong
        // in the individual module build.gradle files
    }
}

allprojects {
    repositories {
        jcenter()
    }
}

task clean(type: Delete) {
    delete rootProject.buildDir
}

修改 Module 目录下的 build.gradle,声明 google-services 插件,并在 dependencies 闭包中增加 firebase-core 和 firebase-ads。

apply plugin: 'com.android.application'
apply plugin: 'com.google.gms.google-services'

android {
    compileSdkVersion 25
    buildToolsVersion "25.0.2"
    defaultConfig {
        minSdkVersion 15
        targetSdkVersion 25
    }
    buildTypes {
        release {
            minifyEnabled false
            proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
        }
    }
}

dependencies {
    compile 'com.android.support:appcompat-v7:25.3.1'
    compile 'com.google.firebase:firebase-core:10.2.1'
    compile 'com.google.firebase:firebase-ads:10.2.1'
}

在 manifest 中声明权限

使用 AdMob 的应用本身需要有访问网络的权限,所以需要在 manifest 中声明如下权限。

    <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE"/>
    <uses-permission android:name="android.permission.INTERNET"/>

在 layout 文件中添加布局

横幅式广告只需要在布局文件中添加一个 AdView 就可以了,其中使用了 ads,需要声明命名空间,在根布局中添加 xmlns:ads="http://schemas.android.com/apk/res-auto"。在 AdView 中,系统要求提供 layout_width 和 layout_height,可以将这两项都设置为 wrap_content。

ads 参数意义:

  • adSize=”BANNER” 设置为横幅式广告。
  • adUnitId 该参数是在请求广告时 AdView 使用的广告单元 ID,是用来和你的账户绑定的,下文会讲述如何获得该 ID。

AdView 布局:

    <com.google.android.gms.ads.AdView
        android:id="@+id/adView"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_centerHorizontal="true"
        android:layout_alignParentBottom="true"
        ads:adSize="BANNER"
        ads:adUnitId="@string/banner_ad_unit_id">
    </com.google.android.gms.ads.AdView>

在 activity 代码中添加加载代码

  • 定义全局变量 private AdView mAdView;
  • 在 OnCreate 中添加如下代码就能完成广告的加载。
    mAdView = (AdView) findViewById(R.id.adView);
    AdRequest adRequest = new AdRequest.Builder().build();
    mAdView.loadAd(adRequest);

广告单元 ID

广告单元 ID 是在应用中占有位置的唯一标识符,用于显示广告。如果应用具有两个 Activity(例如,分别显示一个横幅),则需要提供两个广告单元,每个广告单元均具有自己的 ID。AdMob 广告单元 ID 的格式为 ca-app-pub-XXXXXXXXXXXXXXXX/NNNNNNNNNN

若要使新应用显示广告,则需包括一个广告单元 ID。使用应用字符串资源文件(在 app/src/main/res/values/strings.xml 中)。

测试广告单元 ID

<string name="banner_ad_unit_id">ca-app-pub-3940256099942544/6300978111</string>

注意,以上提供的广告单元 ID 仅供测试使用。它允许应用检索示例横幅广告并确保实现正确无误。在开发和测试应用时,应始终使用测试广告。 点击自己的实时广告违反 AdMob 政策。在开发和测试期间,请使用测试广告。如果确实需要在发布前呈现直播广告,请避免点击它们。如果点击直播广告,AdMob 帐户可能被禁用。

创建自己的广告单元 ID

当前基于 AdMob 和 AdMob Beta 的版本,有两种不同的方法,具体参见
创建横幅广告单元

添加广告监听器

你可能会发现有时候你的广告不能正常显示出来,然而根据前文的信息你无法得知具体的原因,这时候我们可为 AdView 添加 AdListener,由此来确定 AdView 的状态。例如,当广告加载失败的时候 onAdFailedToLoad(int returnCode) 函数会被调用,我们可以根据 returnCode 来确定无法显示的原因。

AdListener 一共有 5 个函数可以由我们去实现:

  • onAdClosed() 用户在点击广告后即将返回应用程序时调用。
  • onAdFailedToLoad(int returnCode) 广告请求失败时调用。
  • onAdLeftApplication() 当广告离开应用程序时调用(例如,去浏览器)。
  • onAdLoaded() 从服务器获得广告后调用。
  • onAdOpened() 当广告打开,覆盖屏幕时调用。

广告加载失败的 4 种常见原因:

  • ERROR_CODE_INTERNAL_ERROR,值为0,内部错误(从广告服务器收到无效的响应)。
  • ERROR_CODE_INVALID_REQUEST,值为1,广告单元ID不正确。
  • ERROR_CODE_NETWORK_ERROR,值为2,网络连接失败。
  • ERROR_CODE_NO_FILL,值为3,广告请求已成功,但由于缺少广告资源,没有返回任何广告。

使用示例:

   mAdView = (AdView) findViewById(R.id.adView);
   AdRequest adRequest = new AdRequest.Builder().build();
   mAdView.setAdListener(new AdListener() {
       @Override
       public void onAdClosed() {
           super.onAdClosed();
           Log.d(TAG, "onAdClosed: ");
       }

       @Override
       public void onAdFailedToLoad(int i) {
           super.onAdFailedToLoad(i);
           String msg;
           switch (i) {
               case AdRequest.ERROR_CODE_INTERNAL_ERROR:
                   msg = "服务器错误";
                   break;
               case AdRequest.ERROR_CODE_INVALID_REQUEST:
                   msg = "广告单元ID不正确";
                   break;
               case AdRequest.ERROR_CODE_NETWORK_ERROR:
                   msg = "网络连接失败";
                   break;
               case AdRequest.ERROR_CODE_NO_FILL:
                   msg = "暂无广告显示";
                   break;
               default:
                   msg = "未知错误";
           }
           Toast.makeText(getApplicationContext(),msg,Toast.LENGTH_LONG).show();
           Log.e(TAG, "onAdFailedToLoad: msg = " + msg);
       }

       @Override
       public void onAdLeftApplication() {
           super.onAdLeftApplication();
           Log.d(TAG, "onAdLeftApplication: ");
       }

       @Override
       public void onAdOpened() {
           super.onAdOpened();
           Log.d(TAG, "onAdOpened: ");
       }

       @Override
       public void onAdLoaded() {
           super.onAdLoaded();
           Log.d(TAG, "onAdLoaded: ");
       }
   });
   mAdView.loadAd(adRequest);

有些时候广告可能显示不出来,可能是因为 GFW 导致的网络问题。