🦾

UE5.5で使用するAdmobをアップデートする方法

2025/01/25に公開

Unreal EngineでAdmobを使用する際、インストールしたばかりのUE5.5やUE5.4ではGameActivity.javaがエラーを起こして使えないといった問題が起こると思います。
今回は、この問題を修正します。また、デフォルトで使用しているGoogle Mobile Ads SDKが古いのでそのアップデート方法についても解説します。修正後のファイルに関しては、ページの最後にgithubリンクを載せています。

前提

記事の対象

この記事はAndroidデバイスでUnreal Engineプロジェクトを開発するための要件を満たしている方を対象にしています。
Admobを使用していない状態で、クイック起動できれば大丈夫です。
まだの方はUEのドキュメントを参考に要件を満たしてください。
(英語版と日本語版ではAndroid Studioのバージョンが違うので見比べながら設置すると良いと思います。)

https://dev.epicgames.com/documentation/en-us/unreal-engine/android-development-requirements-for-unreal-engine

Android上でUE製のゲームが動く仕組みについての概略

通常AndroidアプリはJavaやKotolinなどで記述します。一方、UEではC++を記述してゲームを作成します。こういった環境では、Andoridでアプリ起動時に、Javaにより仮想マシンが生成されその中でゲームが実行されます。また、Javaとネイティブコード(C++コンパイルにより作成されたコード)を結びつける仕組みであるJNI(Java Native Interface)によって端末で発生したイベントをゲームに通知したり、ゲームで発生したしたイベントをJava側に通知することができます。
 Unreal Engineでは各モジュール内に記述されているJavaコードを集めて、ppGameActivity.javaを生成する仕組みが実装されており、Android上でゲームを動かすことができます。このGameActivity.javaはAndroidプラットフォームを対象とするプロジェクトごとに生成されます。以下のパスで実装が確認できます。
プロジェクトフォルダ/Intermediate/Android/arm64/src/com/epicgames/unreal/GameActivity.java

Admobの実装に関して

以下のフォルダ内で実装されていることが確認できます。
(UE_〇.〇の箇所はエンジンのバージョンを入れてください。 UE_5.5など)
UE_○.○/Engine/Source/Runtime/Advertising/Android/AndroidAdvertising

UEでは、Javaコードはxmlファイルに直書きされているため、このフォルダ内にあるファイルAndroidAdvertising_APL.xmlを修正していくことでAdmobのアップデートが可能になります。

GameActivity.javaのエラーについての対処

エラー内容

エンジンをインストールしてデフォルトの状態で、Admobの使用を開始するとパッケージ時に以下のようなエラーが発生します。
一部抜粋

> Task :app:compileDebugJavaWithJavac
Z:\app\src\main\java\com\epicgames\unreal\GameActivity.java:867: �G���[: �V���{�������‚����܂���
   		activityContext.runOnUiThread(new Runnable()
   		               ^
 �V���{��:   ���\�b�h runOnUiThread(<anonymous Runnable>)
 �ꏊ: �^�C�vContextWrapper�̕ϐ� activityContext

対処

以下のパスにあるAndroidAdvertising_APL.xmlを修正することで直すことができます。
(UE_〇.〇の箇所はエンジンのバージョンを入れてください。UE_5.5など)
パス UE_○.○/Engine/Source/Runtime/Advertising/Android/AndroidAdvertising/AndroidAdvertising_APL.xml

おそらく全部で6箇所あるので全て以下のように修正してください。

AndroidAdvertising_APL.xml
- activityContext.runOnUiThread(new Runnable()
+ _activity.runOnUiThread(new Runnable()

xmlファイル修正後、Admobの設定をした上で、クイック起動を試してみるとエラーが出ずに実行できると思います。

解説

GameActivity.javaよりactivityContextはContextWrapperクラスだとわかります。

GameActivity.java
 protected ContextWrapper activityContext = null;

runOnUiThreadはActivityクラスのメソッドなので、_activityに修正することで直せます。

Admobのアップデート

Google Mobile Ads SDKについてデフォルトでは18.1.0を使用していますが、最新では23.6.0なのでそちらに更新します。
また、20.0.0で従来のInterstitial APIが削除されたことや、AdListenerでのonAdFailedToLoadに変更があったようなので、そちらも更新します。
https://developers.google.com/admob/android/rel-notes?hl=ja#23.6.0
https://developers.google.com/admob/android/migration?hl=ja

Google Mobile Ads SDKの更新

AndroidAdvertising_APL.xml
dependencies {
- implementation('com.google.android.gms:play-services-ads:18.1.0')
- implementation('com.google.android.gms:play-services-ads-identifier:18.0.1')

+ implementation('com.google.android.gms:play-services-ads:23.6.0')
}

onAdFailedToLoadの更新

AndroidAdvertising_APL.xml の AndroidThunkJava_ShowAdBanner関数内
- public void onAdFailedToLoad(int errorCode)
+ public void onAdFailedToLoad(LoadAdError adError)

インタースティシャル広告の更新

AndroidAdvertising_APL.xml の import部分
- import com.google.android.gms.ads.InterstitialAd;
+ import androidx.annotation.NonNull;
+ import com.google.android.gms.ads.LoadAdError;
+ import com.google.android.gms.ads.interstitial.InterstitialAd;
+ import com.google.android.gms.ads.interstitial.InterstitialAdLoadCallback;
AndroidAdvertising_APL.xml の AndroidThunkJava_LoadInterstitialAd関数内
// インタースティシャル広告インスタンスの生成部分と、UnitId設定部分の削除
- interstitialAd = new InterstitialAd(this);
- interstitialAd.setAdUnitId(AdMobAdUnitID);

// Runnableのrun関数内
- interstitialAd.loadAd(interstitialAdRequest);
+ InterstitialAd.load(
+    _activity,
+    AdMobAdUnitID,
+    interstitialAdRequest,
+    new InterstitialAdLoadCallback() {
+        @Override
+        public void onAdLoaded(@NonNull InterstitialAd ad) {
+            interstitialAd = ad;
+            isInterstitialAdLoaded = true;
+            isInterstitialAdRequested = false;
+        }
+
+        @Override
+        public void onAdFailedToLoad(@NonNull LoadAdError loadAdError) {
+            Log.debug("Interstitial Ad failed to load, errorCode: " + loadAdError.getCode());
+            isInterstitialAdLoaded = false;
+            isInterstitialAdRequested = false;
+        }
+    });

// interstitialAdインスタンスにAdLisnerをセットしている部分 全部削除
- interstitialAd.setAdListener(new AdListener() {
-    @Override
-    public void onAdFailedToLoad(int errorCode) {
-        Log.debug("Interstitial Ad failed to load, errocode: " + errorCode);
-        isInterstitialAdLoaded = false;
-        isInterstitialAdRequested = false;
-    }
-
-    @Override
-    public void onAdLoaded() {
-        //track if the ad is loaded since we can only called interstitialAd.isLoaded() from the uiThread				
-        isInterstitialAdLoaded = true;
-        isInterstitialAdRequested = false;
-    }    
-});

参考

エラーの対処については以下のフォーラムが参考になりました。
https://forums.unrealengine.com/t/android-packaging-fails-with-errors-in-gameactivity-java/1883300/4

コードの修正については、AdmobSDKのリファレンスやGitHubページが参考になりました。
https://developers.google.com/admob/android/quick-start?hl=ja
https://github.com/googleads/googleads-mobile-android-examples/tree/main/java/admob
https://developers.google.com/android/reference/com/google/android/gms/ads/package-summary

修正後のAndroidAdvertising_APL.xml

https://github.com/koki-ymd/AndroidAdvertisingInUE5/tree/master

Discussion