我在上一篇文章 【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 RewardedVideoAdListener2)根據提示,在本類中實現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 29 buildToolsVersion '29.0.2' compileOptions { sourceCompatibility JavaVersion.VERSION_1_8 targetCompatibility JavaVersion.VERSION_1_8 } defaultConfig { minSdkVersion 16 targetSdkVersion 29 applicationId 'com.tan.admob' ndk { abiFilters 'armeabi-v7a', 'x86' } versionCode 1 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>






