我在上一篇文章 【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工程。(Unity中暂时不写任何代码,以后的文章里会补充)

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类中添加一个初始化激励广告的方法rewardedVideoAdInit 。代码如下:

    /**
* 激励视频(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方法写完之后,IDE会报红,提未本类无法成为激励视频广告的监听。

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

  1)在extends Activity后添加 implements RewardedVideoAdListener,如下:  

public class UnityPlayerActivity extends Activity implements RewardedVideoAdListener

  2)根据提示,在本类中实现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的调用以显示广告。并在视频广告关闭后进行了重新加载。

6、依照banner和插页广告的做法,在onCreate方法中添加对rewardedVideoAdInit的调用,代码如下:

        //激励视频(Rewarded Video)广告初始化
// Sample AdMob interstitial ad id: ca-app-pub-3940256099942544/5224354917
rewardedVideoAdInit("ca-app-pub-3940256099942544/5224354917");
//预加载视频
loadRewardedVideoAd();

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

7、测试。

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

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

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

激励广告的接入也完成。

总结

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

后续

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

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

下篇再见。

UnityPlayerActivity.java的完整代码

package com.tan.admob;

import com.google.android.gms.ads.AdListener;
import com.google.android.gms.ads.AdRequest;
import com.google.android.gms.ads.AdSize;
import com.google.android.gms.ads.AdView;
import com.google.android.gms.ads.InterstitialAd;
import com.google.android.gms.ads.MobileAds;
import com.google.android.gms.ads.initialization.InitializationStatus;
import com.google.android.gms.ads.initialization.OnInitializationCompleteListener;
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.unity3d.player.*;
import android.app.Activity;
import android.content.Intent;
import android.content.res.Configuration;
import android.graphics.Color;
import android.graphics.PixelFormat;
import android.os.Bundle;
import android.print.PrintAttributes;
import android.util.Log;
import android.view.Gravity;
import android.view.KeyEvent;
import android.view.MotionEvent;
import android.view.View;
import android.view.ViewGroup;
import android.view.Window;
import android.view.WindowManager;
import android.widget.FrameLayout;
import android.widget.LinearLayout;
import android.widget.RelativeLayout;
import android.widget.TextView;
import android.widget.Toast; public class UnityPlayerActivity extends Activity implements RewardedVideoAdListener {
protected UnityPlayer mUnityPlayer; // don't change the name of this variable; referenced from native code //激励视频广告
private RewardedVideoAd rewardedVideoAd;
//激励视频广告Id
private String rewardVidewAdUnitId; // Setup activity layout
@Override protected void onCreate(Bundle savedInstanceState)
{
requestWindowFeature(Window.FEATURE_NO_TITLE);
super.onCreate(savedInstanceState); mUnityPlayer = new UnityPlayer(this);
setContentView(mUnityPlayer);
mUnityPlayer.requestFocus(); /*
// MobileAds初始化的方法1,有监听,无法设置appId ;appId可以在AndroidManifest.xml中设置
// AdMob Init
MobileAds.initialize(this, new OnInitializationCompleteListener() {
@Override
public void onInitializationComplete(InitializationStatus initializationStatus) {
Log.i("AdMob", "-----Admob初始化完成");
}
});
*/ //MobileAds初始化的方法2,可以指定appId;当AndroidManifest中也设置了appId时,以AndroidManifest为准
// Sample AdMob App ID: ca-app-pub-3940256099942544~3347511713
MobileAds.initialize(this, "ca-app-pub-3940256099942544~3347511713");//测试用的AppId //横幅(banner)广告初始化
// Sample AdMob banner ad id: ca-app-pub-3940256099942544/6300978111
bannerAdInit("ca-app-pub-3940256099942544/6300978111", AdSize.BANNER); //插页(interstitial)广告初始化
// Sample AdMob interstitial ad id: ca-app-pub-3940256099942544/1033173712
interstitialAdInit("ca-app-pub-3940256099942544/1033173712"); //激励视频(Rewarded Video)广告初始化
// Sample AdMob interstitial ad id: ca-app-pub-3940256099942544/5224354917
rewardedVideoAdInit("ca-app-pub-3940256099942544/5224354917");
//预加载视频
loadRewardedVideoAd();
} /**
* 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);
} /**
* 插页广告初始化
* @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();
}
});
} /**
* 激励视频(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;
} //加载激励视频
private void loadRewardedVideoAd() {
rewardedVideoAd.loadAd(rewardVidewAdUnitId, new AdRequest.Builder().build());
} //显示激励视频
public void showRewardedVideoAd() {
if (rewardedVideoAd.isLoaded()) {
rewardedVideoAd.show();
} else {
Toast.makeText(this, "video is not ready.", Toast.LENGTH_SHORT);
}
} @Override protected void onNewIntent(Intent intent)
{
// To support deep linking, we need to make sure that the client can get access to
// the last sent intent. The clients access this through a JNI api that allows them
// to get the intent set on launch. To update that after launch we have to manually
// replace the intent with the one caught here.
setIntent(intent);
} // Quit Unity
@Override protected void onDestroy ()
{
mUnityPlayer.destroy();
super.onDestroy();
} // Pause Unity
@Override protected void onPause()
{
super.onPause();
mUnityPlayer.pause();
} // Resume Unity
@Override protected void onResume()
{
super.onResume();
mUnityPlayer.resume();
} @Override protected void onStart()
{
super.onStart();
mUnityPlayer.start();
} @Override protected void onStop()
{
super.onStop();
mUnityPlayer.stop();
} // Low Memory Unity
@Override public void onLowMemory()
{
super.onLowMemory();
mUnityPlayer.lowMemory();
} // Trim Memory Unity
@Override public void onTrimMemory(int level)
{
super.onTrimMemory(level);
if (level == TRIM_MEMORY_RUNNING_CRITICAL)
{
mUnityPlayer.lowMemory();
}
} // This ensures the layout will be correct.
@Override public void onConfigurationChanged(Configuration newConfig)
{
super.onConfigurationChanged(newConfig);
mUnityPlayer.configurationChanged(newConfig);
} // Notify Unity of the focus change.
@Override public void onWindowFocusChanged(boolean hasFocus)
{
super.onWindowFocusChanged(hasFocus);
mUnityPlayer.windowFocusChanged(hasFocus);
} // For some reason the multiple keyevent type is not supported by the ndk.
// Force event injection by overriding dispatchKeyEvent().
@Override public boolean dispatchKeyEvent(KeyEvent event)
{
if (event.getAction() == KeyEvent.ACTION_MULTIPLE)
return mUnityPlayer.injectEvent(event);
return super.dispatchKeyEvent(event);
} // Pass any events not handled by (unfocused) views straight to UnityPlayer
@Override public boolean onKeyUp(int keyCode, KeyEvent event) { return mUnityPlayer.injectEvent(event); }
@Override public boolean onKeyDown(int keyCode, KeyEvent event) { return mUnityPlayer.injectEvent(event); }
@Override public boolean onTouchEvent(MotionEvent event) { return mUnityPlayer.injectEvent(event); }
/*API12*/ public boolean onGenericMotionEvent(MotionEvent event) { return mUnityPlayer.injectEvent(event); } /**---------------激励视频监听实现 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-------------------*/ }

build.gradle

// 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'
}
} allprojects {
repositories {
google()
jcenter()
flatDir {
dirs 'libs'
}
}
} apply plugin: 'com.android.application' dependencies {
implementation fileTree(dir: 'libs', include: ['*.jar'])
implementation 'com.google.android.gms:play-services-ads:18.2.0'
} android {
compileSdkVersion
buildToolsVersion '29.0.2' compileOptions {
sourceCompatibility JavaVersion.VERSION_1_8
targetCompatibility JavaVersion.VERSION_1_8
} defaultConfig {
minSdkVersion
targetSdkVersion
applicationId 'com.tan.admob'
ndk {
abiFilters 'armeabi-v7a', 'x86'
}
versionCode
versionName '0.1'
} lintOptions {
abortOnError false
} aaptOptions {
noCompress = ['.unity3d', '.ress', '.resource', '.obb']
} buildTypes {
debug {
minifyEnabled false
useProguard false
proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-unity.txt'
jniDebuggable true
}
release {
minifyEnabled false
useProguard false
proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-unity.txt'
signingConfig signingConfigs.debug
}
} packagingOptions {
doNotStrip '*/armeabi-v7a/*.so'
doNotStrip '*/x86/*.so'
} bundle {
language {
enableSplit = false
}
density {
enableSplit = false
}
abi {
enableSplit = true
}
}
}

AndroidManifest.xml

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android" package="com.tan.admob" xmlns:tools="http://schemas.android.com/tools" android:installLocation="preferExternal">
<supports-screens android:smallScreens="true" android:normalScreens="true" android:largeScreens="true" android:xlargeScreens="true" android:anyDensity="true" />
<application android:theme="@style/UnityThemeSelector" android:icon="@mipmap/app_icon" android:label="@string/app_name" android:isGame="true" android:banner="@drawable/app_banner">
<activity android:label="@string/app_name" android:screenOrientation="fullSensor" android:launchMode="singleTask" android:configChanges="mcc|mnc|locale|touchscreen|keyboard|keyboardHidden|navigation|orientation|screenLayout|uiMode|screenSize|smallestScreenSize|fontScale|layoutDirection|density" android:hardwareAccelerated="false" android:name="com.tan.admob.UnityPlayerActivity">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
<category android:name="android.intent.category.LEANBACK_LAUNCHER" />
</intent-filter>
<meta-data android:name="unityplayer.UnityActivity" android:value="true" />
</activity>
<meta-data android:name="unity.build-id" android:value="fea8e2f2-427d-4c46-a8ec-f06bef433231" />
<meta-data android:name="unity.splash-mode" android:value="0" />
<meta-data android:name="unity.splash-enable" android:value="True" /> <!-- Sample AdMob App ID: ca-app-pub-3940256099942544~3347511713 -->
<meta-data
android:name="com.google.android.gms.ads.APPLICATION_ID"
android:value="ca-app-pub-3940256099942544~3347511713"/> </application>
<uses-feature android:glEsVersion="0x00020000" />
<uses-permission android:name="android.permission.INTERNET" />
<uses-feature android:name="android.hardware.touchscreen" android:required="false" />
<uses-feature android:name="android.hardware.touchscreen.multitouch" android:required="false" />
<uses-feature android:name="android.hardware.touchscreen.multitouch.distinct" android:required="false" />
</manifest>

【Unity与Android】02-在Unity导出的Android工程中接入Google Admob广告的更多相关文章

  1. Android Google AdMob 广告接入示例

    Android Google AdMob 广告接入示例 [TOC] 首先请大家放心,虽然 Google搜索等服务被qiang了,但是 广告服务国内还是可以用的,真是普天同庆啊~~~噗! 其实这篇文章也 ...

  2. [Android]彻底去除Google AdMob广告

    应用中包含广告是能够理解的,但经常造成用户误点,或者广告切换时造成下载流量,就有点让人不舒服了. 以下就以Google AdMob广告为例,看怎样彻底去除他. 先分析一下Google AdMob的工作 ...

  3. Google Admob广告Android全攻略1

    一.登录Google AdMob中文官网:http://www.google.cn/ads/admob/   ,注册帐号. 1.点击注册AdMob帐号 2.进入Google帐号注册页面,因为要创建一个 ...

  4. unity 代码有调整,重新导出 iOS 最烦的就是 覆盖导出后项目不能打开

    unity  代码有调整,重新导出 iOS 最烦的就是 覆盖导出后项目不能打开,原因是 editor 里面的脚本,破坏了 Unity-iPhone.xcodeproj 里面的结构,具体是什么原因,也不 ...

  5. Unity3D 解决用Unity导出的Android工程在6.0及以上设备会弹出一串权限对话框的问题

    解决用Unity导出的Android工程在6.0及以上设备会弹出一串权限对话框的问题 <meta-data android:name="unityplayer.SkipPermissi ...

  6. 将Unity导出的Eclipse工程转换为AndroidStudio工程

    步骤:1)将unity项目导出到文件夹: 转换到安卓平台,这里只勾选google android project.然后导出到自己新建的文件夹. 2)打开导出的文件夹,看到如下内容.这是unity5.x ...

  7. unity导出工程导入到iOS原生工程中详细步骤

    一直想抽空整理一下unity原生工程导入iOS原生工程中的详细步骤.做iOS+vuforia+unity开发这么长时间了.从最初的小小白到现在的小白.中间趟过了好多的坑.也有一些的小小收货.做一个喜欢 ...

  8. Android设备连接Unity Profiler性能分析器

    Unity提供两种方式让Developer的Android设备连接Profiler进行性能分析: 1.通过wifi,Android设备和计算机处于同一个Wlan中. 2.通过USB ADB 普通情况我 ...

  9. unity A*寻路 (一)导出NavMesh数据

    使用unity的API   NavMesh.CalculateTriangulation 可以获取NavMesh数据 首先 我们创建一个新的工程 保存一个test场景 然后在场景中添加一个Plane作 ...

随机推荐

  1. Asp.net MVC 集成AD域认证

    1.首先WebApi 应用下Web.config要配置域认证服务器节点,如下 <!--LDAP地址 用于项目AD系统账号密码验证--> <!--0:关闭域认证:1:开启域认证--&g ...

  2. 通过代码审计找出网站中的XSS漏洞实战(三)

    一.背景 笔者此前录制了一套XSS的视频教程,在漏洞案例一节中讲解手工挖掘.工具挖掘.代码审计三部分内容,准备将内容用文章的形式再次写一此,前两篇已经写完,内容有一些关联性,其中手工XSS挖掘篇地址为 ...

  3. sql查询技巧指南

    传送门(牛客网我做过的每到题目答案以及解析) sql定义: 结构化查询语言(Structured Query Language)简称SQL,是一种特殊目的的编程语言,是一种数据库查询和程序设计语言,用 ...

  4. P3317 [SDOI2014]重建 变元矩阵树定理 高斯消元

    传送门:https://www.luogu.org/problemnew/show/P3317 这道题的推导公式还是比较好理解的,但是由于这个矩阵是小数的,要注意高斯消元方法的使用: #include ...

  5. 牛客多校第七场 C Bit Compression 思维

    链接:https://www.nowcoder.com/acm/contest/145/C来源:牛客网 A binary string s of length N = 2n is given. You ...

  6. Codeforces 735D Taxes(简单数论)

    题目链接 http://codeforces.com/problemset/problem/735/D 题意:一个人的收入为n他要交的税是n的最大除数,他为了少缴税将n分成k个数n1,n2,n2... ...

  7. 《Hive编程指南》读书笔记 | 一文看懂Hive的数据类型和文件格式

    Hive支持关系型数据库中的大多数基本数据类型,同时也支持关系型数据库中很少出现的3种集合数据类型. 和大多数数据库相比,Hive具有一个独特的功能,那就是其对于数据在文件中的编码方式具有非常大的灵活 ...

  8. JSP标签介绍

    JSP标签也称之为Jsp Action(JSP动作)元素,它用于在Jsp页面中提供业务逻辑功能,避免在JSP页面中直接编写java代码,造成jsp页面难以维护. jsp的常用标签有以下三个 <j ...

  9. Markdown 直接转换公众号文章,不再为排版花时间

    上一篇「又一家数据公司被查,爬虫到底做错了什么?」反响强烈,虽然我这是新号,但还是获得了不少公众号的转发,借机也结识了很多业内大佬,在此感谢大家的抬爱! 同时也有不少号主问我的文章排版是用的哪个网站, ...

  10. 5.cookie每个参数的意义和作用以及工作原理?

    cookie主要参数有: (1)expires 过期时间 (2)path cookie存放路径 (3)domain 域名 同域名下可访问 (4)Set-Cookie: name cookie名称