WebViewとJavaScriptの相互通信、及びAdMob広告の実装方法

ガワネイティブアプリ(Android+WebView(HTML+CSS+JavaScript))におけるAdMob広告を表示する方法を備忘録として記す。サンプルプロジェクトは「ファイル」→「新規」→「新規プロジェクト」から「Empty Views Activity」で作成した。

順番にコードを追加していき、最終的にバナー広告、インタースティシャル広告、リワード広告を実装したガワネイティブアプリを作成する。

開発環境

  • ndroid Studio Hedgehog | 2023.1.1 Patch 2
  • Android Gradle Plugin 8.2.2
  • Gradle 8.2
  • kotlin 1.9.22

JavaScriptからAndroidのメソッドの呼び出し

まず、Android側でWebサイトを表示するWebViewを作る。

[app/manifests/AndroidManifest.xml]

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools">
    
    <!-- インターネッと接続を許可 -->
    <uses-permission android:name="android.permission.INTERNET" />
    
    <application
        android:allowBackup="true"
        android:dataExtractionRules="@xml/data_extraction_rules"
        android:fullBackupContent="@xml/backup_rules"
        android:icon="@mipmap/ic_launcher"
        android:label="@string/app_name"
        android:roundIcon="@mipmap/ic_launcher_round"
        android:supportsRtl="true"
        android:theme="@style/Theme.AdSample"
        tools:targetApi="34">
        <activity
            android:name=".MainActivity"
            android:exported="true">
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />
    
                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
        </activity>
    </application>

</manifest>

マニフェストファイルにインターネットアクセスの許可を追加。

[res/layout/activity_main.xml]

<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context=".MainActivity">

	<!-- WebViewコンポーネントを追加 -->
	<WebView
	    android:id="@+id/webView"
	    android:layout_width="match_parent"
	    android:layout_height="match_parent" />

</androidx.constraintlayout.widget.ConstraintLayout>

レイアウトファイルにWebViewコンポーネントを追加。元々あったTextViewは不要のため削除。

[MainActibity.kt]

package com.example

import androidx.appcompat.app.AppCompatActivity
import android.os.Bundle
import android.webkit.WebView

class MainActivity : AppCompatActivity() {
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main)

        // WebViewの設定
        val webView:WebView = findViewById(R.id.webView)
        webView.settings.javaScriptEnabled = true;  // JavaScriptを有効にする
        webView.loadUrl("https://example.com/sample.html")
    }
}

MainActibtyにWebViewを設定。これで指定したWebサイトが表示される。

[MainActibity.kt]

package com.example

import androidx.appcompat.app.AppCompatActivity
import android.os.Bundle

class MainActivity : AppCompatActivity() {
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main)

        val webView:WebView = findViewById(R.id.webView)
        webView.settings.javaScriptEnabled = true;  // JavaScriptを有効にする
        webView.loadUrl("https://example.com/sample.html")
        // WebViewに橋渡し役のインターフェイスを追加
        webView.addJavascriptInterface(WebAppInterface(this), "Android")
    }

	// JavaScriptとAndroidを橋渡しするインターフェイスを実装
	class WebAppInterface(private val context: Context) {
	    @JavascriptInterface
	    fun showToast(toast: String): String {
	        Toast.makeText(context, toast, Toast.LENGTH_LONG).show()
	        return toast
	    }
	}
}

WebViewに橋渡し役のインターフェイスを設定。2番目の引数がJavaScriptから呼び出す際の名前。JavaScript側からメソッドを呼び出す場合、この名前を頭につける。例、Android.showToast()など。

JavaScript側からは、このインターフェイス内にあるメソッドを呼び出す。

[sample.html]

<!DOCTYPE html>
<html lang="ja">
    <head>
        <meta charset="UTF-8">
    </head>
    <body>
	    <p>サンプルWebページ</p>
        <script type="text/javascript">
        window.onload = function(){
        	// Android側のメソッドを呼び出す
        	Android.showToast("JavaScriptからの呼び出し");
        }
        </script>
    </body>
</html>

上のシンプルなHTMLファイルは、開いた瞬間にAndroid側に対しshowToast()の呼び出しを行う。エミュレータ下部に「JavaScriptからの呼び出し」というトーストが表示される。

バナー広告の実装

バナー広告はアプリの下部に最初から最後まで表示されている広告。Android側だけの設定で済むため簡単。AdMobでの設定は割愛。

[build.gradle(Module)]

...

dependencies {

    implementation("androidx.core:core-ktx:1.12.0")
    implementation("androidx.appcompat:appcompat:1.6.1")
    implementation("com.google.android.material:material:1.11.0")
    implementation("androidx.constraintlayout:constraintlayout:2.1.4")
    testImplementation("junit:junit:4.13.2")
    androidTestImplementation("androidx.test.ext:junit:1.1.5")
    androidTestImplementation("androidx.test.espresso:espresso-core:3.5.1")
    // Mobile Ads SDKを追加
    implementation("com.google.android.gms:play-services-ads:22.6.0")
}

「build.gradle(Module)」に「Mobile Ads SDK」を追加し、上部に現れた「Sync Now」をクリック。記事作成時の最新版は22.6.0。

[app/manifests/AndroidManifest.xml]

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools">

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

    <application
        android:allowBackup="true"
        android:dataExtractionRules="@xml/data_extraction_rules"
        android:fullBackupContent="@xml/backup_rules"
        android:icon="@mipmap/ic_launcher"
        android:label="@string/app_name"
        android:roundIcon="@mipmap/ic_launcher_round"
        android:supportsRtl="true"
        android:theme="@style/Theme.AdSample"
        tools:targetApi="34">
        <activity
            android:name=".MainActivity"
            android:exported="true">
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />

                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
        </activity>
        <!-- AdMobのアプリIDを追加 -->
        <meta-data android:name="com.google.android.gms.ads.APPLICATION_ID"
            android:value="ca-app-pub-3940256099942544~3347511713"/>
    </application>

</manifest>

AdMobにはアプリIDと広告ユニットIDがある。アプリIDは自分のアプリをAdMobに登録すると割り当てられるユニークID。広告ユニットIDはAdMobで作成した個々の広告ユニットに割り当てられるユニークID。AdMobはテスト用アプリID、種類別テスト用広告ユニットIDを公開している。テスト段階ではこちらを使う。

テスト用アプリID

Androidca-app-pub-3940256099942544~3347511713
iPhoneca-app-pub-3940256099942544~1458002511

テスト用広告ユニットID

広告フォーマットテスト用広告ユニットID
アプリ起動ca-app-pub-3940256099942544/3419835294
バナーca-app-pub-3940256099942544/6300978111
インタースティシャルca-app-pub-3940256099942544/1033173712
インタースティシャル動画ca-app-pub-3940256099942544/8691691433
リワードca-app-pub-3940256099942544/5224354917
リワード インタースティシャルca-app-pub-3940256099942544/5354046379
ネイティブ アドバンスca-app-pub-3940256099942544/2247696110
ネイティブ アドバンス動画ca-app-pub-3940256099942544/1044960115

まず、AndroidManifest.xmlにAdMobのアプリIDを追加。ここではAdMobがテスト用に公開しているアプリIDを使用。本番では自分のアプリIDを使う。

[res/layout/activity_main.xml]

<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context=".MainActivity">

    <WebView
        android:id="@+id/webView"
        android:layout_width="match_parent"
        android:layout_height="match_parent" />

    <!-- レイアウトファイルに広告ユニットを追加 -->
    <com.google.android.gms.ads.AdView
        android:id="@+id/adView"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_alignParentBottom="true"
        android:layout_centerHorizontal="true"
        app:adSize="BANNER"
        app:adUnitId="ca-app-pub-3940256099942544/6300978111"
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintStart_toStartOf="parent"/>

</androidx.constraintlayout.widget.ConstraintLayout>

レイアウトファイルに広告ユニットを追加。広告ユニットIDはテスト用IDを使用。

[MainActibity.kt]

package com.example

import android.content.Context
import androidx.appcompat.app.AppCompatActivity
import android.os.Bundle
import android.webkit.JavascriptInterface
import android.webkit.WebView
import android.widget.Toast
import com.google.android.gms.ads.AdRequest
import com.google.android.gms.ads.AdView
import com.google.android.gms.ads.MobileAds

class MainActivity : AppCompatActivity() {
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main)

        // 広告の初期化
        MobileAds.initialize(this)
        // バナー広告の読み込み
        var adView:AdView = findViewById(R.id.adView)
        adView.loadAd(AdRequest.Builder().build())

        val webView:WebView = findViewById(R.id.webView)
        webView.settings.javaScriptEnabled = true;  // JavaScriptを有効にする
        webView.loadUrl("https://example.com/sample.html")
        webView.addJavascriptInterface(WebAppInterface(this), "Android")
    }

    class WebAppInterface(private val context:Context) {
        @JavascriptInterface
        fun showToast(toast: String): String {
            Toast.makeText(context, toast, Toast.LENGTH_LONG).show()
            return toast
        }
    }
}

MainActibityでSDKの初期化、バナー広告の読み込みを実装。これでエミュレータを実行すると、下部にテスト用バナー広告が表示される。

バナー広告はアプリの起動から終了まで表示しっぱなしが多いだろう。しかし、読み込み中、表示された、クリックされたといったライフサイクル毎の処理も実装可能。下の一番目のサイトで解説されている。

参考サイト

[Android] Android Studio でのAdMob広告の実装

【Kotlin/Android Studio】AdMobの導入方法!バナー広告の実装

AndroidアプリのAdMobを使ったバナー広告の実装

インタースティシャル広告の実装

インタースティシャル広告はいつ表示するか、表示してはいけないかAdMobがガイドラインを出している。一般には画面遷移、ゲームのクリアまたはオーバー時が多いだろう。つまりこちらの任意のタイミングで表示させたい。

インタースティシャル広告の導入における推奨事項

インタースティシャル広告の導入における禁止事項

[sample.html]

<!DOCTYPE html>
<html lang="ja">
    <head>
        <meta charset="UTF-8">
        <script type="text/javascript">
        function onButtonClick() {
            alert("ok");
            // Android側のメソッドの呼び出し
            Android.showInterstitialAd();
        }
        </script>
    </head>
    <body>
	<p id="text">サンプルWebページ</p>
        <input type="button" value="インタースティシャル広告を表示" onclick="onButtonClick();"/>
    </body>
</html>

ボタンが1つあるだけの簡単なWebサイトを用意する。WebViewで表示されたサイトのボタンをクリックすると、Android側でインタースティシャル広告を表示するメソッドを呼び出す。

インタースティシャル広告でも、マニフェストファイルにアプリIDの追加、build.gradle(Module)の設定が必要だが、バナー広告で解説、実施したため省略。レイアウトは不必要。

[MainActibity.kt]

package com.example

import android.content.Context
import androidx.appcompat.app.AppCompatActivity
import android.os.Bundle
import android.os.Handler
import android.os.Looper
import android.webkit.JavascriptInterface
import android.webkit.WebView
import com.google.android.gms.ads.AdRequest
import com.google.android.gms.ads.AdView
import com.google.android.gms.ads.FullScreenContentCallback
import com.google.android.gms.ads.LoadAdError
import com.google.android.gms.ads.MobileAds
import com.google.android.gms.ads.interstitial.InterstitialAd;
import com.google.android.gms.ads.interstitial.InterstitialAdLoadCallback

class MainActivity : AppCompatActivity() {
    // インタースティシャル広告のIDはテスト用のIDを使用
    private var interstitial:InterstitialAd? = null
    private val interAdId = "ca-app-pub-3940256099942544/1033173712";

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main)

        MobileAds.initialize(this)
        var adView:AdView = findViewById(R.id.adView)
        adView.loadAd(AdRequest.Builder().build())

        val webView:WebView = findViewById(R.id.webView)
        webView.settings.javaScriptEnabled = true;
        webView.loadUrl("https://example.com/sample.html")
        webView.addJavascriptInterface(WebAppInterface(this), "Android")
    }

    override fun onResume() {
        super.onResume()

        loadInterstitial()
    }

    // インタースティシャル広告のロードとライフサイクル毎のハンドラの実装
    private fun loadInterstitial(){
        val adRequest = AdRequest.Builder().build()
        InterstitialAd.load(this, interAdId, adRequest, object:InterstitialAdLoadCallback(){
            // ロード成功時
            override fun onAdLoaded(p0: InterstitialAd) {
                super.onAdLoaded(p0)
                interstitial = p0
                interstitial?.fullScreenContentCallback = object : FullScreenContentCallback(){
                    //広告を閉じられた時
                    override fun onAdDismissedFullScreenContent() {
                        super.onAdDismissedFullScreenContent()
                    }
                    //広告の表示成功時
                    override fun onAdShowedFullScreenContent() {
                        super.onAdShowedFullScreenContent()
                        interstitial = null
                    }
                }
            }
            // ロード失敗
            override fun onAdFailedToLoad(p0: LoadAdError) {
                super.onAdFailedToLoad(p0)
                interstitial = null
            }
        })
    }

    // インタースティシャル広告を表示
    fun showInterstitial() {
        // ロードが成功しているなら実行
        if(interstitial != null) {
            interstitial?.show(this)
        }
    }

    class WebAppInterface(private val context:Context) {
        val handler: Handler = Handler(Looper.getMainLooper())

        // JavaScriptから呼び出すメソッド
        @JavascriptInterface
        fun showInterstitialAd() {
            handler.post(Runnable {
                val act: MainActivity = context as MainActivity
                if(act != null) { act.showInterstitial() }
            })
        }
    }
}

AndroidのUI操作はメインスレッドで行わなければならないため、Handlerを使いRunnableをLooperに渡して非メインスレッド上でも実行可能にしている。

参考サイト

How do I call a function on the Main Thread from a function in a JavascriptInterface that is triggered from my javascript in the html WebView?

AndroidからJavaScriptのメソッドの呼び出し

まず、呼び出されるJavaScript側(Webサイト)を用意。

[sample.html]

<!DOCTYPE html>
<html lang="ja">
    <head>
        <meta charset="UTF-8">
        <script type="text/javascript">
        function onButtonClick() {
            // Android側のメソッドの呼び出し
            Android.showInterstitialAd();
        }
        function rewrite(txt) {
            // pタグのテキストが書き換えられる
            document.getElementById('text').innerText = txt;
        }
        </script>
    </head>
    <body>
	<p id="text">サンプルWebページ</p>
        <input type="button" value="インタースティシャル広告を表示" onclick="onButtonClick();"/>
    </body>
</html>

ボタンをクリックすると、インタースティシャル広告が表示されるのは「インタースティシャル広告の実装」と同じ。表示された広告を閉じるとPタグで表示されていたテキストが、Androidから送信されたテキストに変更される。AndroidからJavaScriptのメソッドを呼び出すにはloadUrl()を使う。

ウェブビュー.loadUrl(“javascript:メソッド名()”);

引数を渡す場合、JavaScript側のメソッドに渡す。JavaScript側から戻り値が欲しい場合は、loadUrl()では受け取れないため、JavaScript側にコールバック関数を定義する。

[MainActibity.kt]

package com.example

import android.content.Context
import androidx.appcompat.app.AppCompatActivity
import android.os.Bundle
import android.os.Handler
import android.os.Looper
import android.webkit.JavascriptInterface
import android.webkit.WebView
import com.google.android.gms.ads.AdRequest
import com.google.android.gms.ads.AdView
import com.google.android.gms.ads.FullScreenContentCallback
import com.google.android.gms.ads.LoadAdError
import com.google.android.gms.ads.MobileAds
import com.google.android.gms.ads.interstitial.InterstitialAd;
import com.google.android.gms.ads.interstitial.InterstitialAdLoadCallback

class MainActivity : AppCompatActivity() {
    // インターフェイス内で参照するためクラスフィールドとして宣言
    private lateinit var webView: WebView
    private var interstitial:InterstitialAd? = null
    private val interAdId = "ca-app-pub-3940256099942544/1033173712";

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main)

        MobileAds.initialize(this)
        var adView:AdView = findViewById(R.id.adView)
        adView.loadAd(AdRequest.Builder().build())

        webView = findViewById(R.id.webView)
        webView.settings.javaScriptEnabled = true;
        webView.loadUrl("https://example.com/sample.html")
        webView.addJavascriptInterface(WebAppInterface(this), "Android")
    }

    override fun onResume() {
        super.onResume()

        loadInterstitial()
    }

    private fun loadInterstitial(){
        val adRequest = AdRequest.Builder().build()
        InterstitialAd.load(this, interAdId, adRequest, object:InterstitialAdLoadCallback(){
            // ロード成功時
            override fun onAdLoaded(p0: InterstitialAd) {
                super.onAdLoaded(p0)
                interstitial = p0
                interstitial?.fullScreenContentCallback = object : FullScreenContentCallback(){
                    //広告を閉じられた時
                    override fun onAdDismissedFullScreenContent() {
                        super.onAdDismissedFullScreenContent()
                        // JavaScript側(WebView)のメソッドを実行
                        webView.loadUrl("javascript:rewrite('Androidからの通信です')")
                    }
                    //広告の表示成功時
                    override fun onAdShowedFullScreenContent() {
                        super.onAdShowedFullScreenContent()
                        interstitial = null
                    }
                }
            }
            //ロード失敗時
            override fun onAdFailedToLoad(p0: LoadAdError) {
                super.onAdFailedToLoad(p0)
                interstitial = null
            }
        })
    }

    // インタースティシャル広告を表示
    fun showInterstitial() {
        //ロードが成功しているなら実行
        if(interstitial != null) {
            interstitial?.show(this)
        }
    }

    class WebAppInterface(private val context:Context) {
        val handler: Handler = Handler(Looper.getMainLooper())

        @JavascriptInterface
        fun showInterstitialAd() {
            handler.post(Runnable {
                val act: MainActivity = context as MainActivity
                if(act != null) { act.showInterstitial() }
            })
        }
    }
}

webViewをインターフェイスでも使うためクラスフィールドに変更。インタースティシャル広告が閉じられたタイミングで、JavaScriptのrewrite()を呼び出している。

参考サイト

AndroidのWebViewをJavascriptエンジンとして利用する

リワード広告の実装

リワード広告でも、マニフェストファイルにアプリIDの追加、build.gradle(Module)の設定が必要だが、バナー広告で解説、実施したため省略。レイアウトは不必要。

[sample.html]

<!DOCTYPE html>
<html lang="ja">
    <head>
        <meta charset="UTF-8">
        <script type="text/javascript">
        function onInterstitialClick() {
            Android.showInterstitialAd();
        }
        function onRewardeClick() {
            // Andoroidのリワード広告の表示メソッドを呼び出し
            Android.showRewarde();
        }
        function rewrite(txt) {
            document.getElementById('text').innerText = txt;
        }
        </script>
    </head>
    <body>
	<p id="text">サンプルWebページ</p>
        <input type="button" value="インタースティシャル広告を表示" onclick="onInterstitialClick();"/><br /><br />
        <input type="button" value="リワード広告を表示" onclick="onRewardeClick();"/>
    </body>
</html>

上がWebViewで表示する簡単なWebサイトのサンプル。新しくリワード広告用のボタンを追加している。クリックされるとAndroidのリワード広告表示メソッドを呼び出す。

[MainActibity.kt]

package com.example

import android.content.Context
import androidx.appcompat.app.AppCompatActivity
import android.os.Bundle
import android.os.Handler
import android.os.Looper
import android.webkit.JavascriptInterface
import android.webkit.WebView
import com.google.android.gms.ads.AdRequest
import com.google.android.gms.ads.AdView
import com.google.android.gms.ads.FullScreenContentCallback
import com.google.android.gms.ads.LoadAdError
import com.google.android.gms.ads.MobileAds
import com.google.android.gms.ads.OnUserEarnedRewardListener
import com.google.android.gms.ads.interstitial.InterstitialAd;
import com.google.android.gms.ads.interstitial.InterstitialAdLoadCallback
import com.google.android.gms.ads.rewarded.RewardedAd
import com.google.android.gms.ads.rewarded.RewardedAdLoadCallback

class MainActivity : AppCompatActivity() {
    private lateinit var webView: WebView
    private var interstitial:InterstitialAd? = null
    private val interAdId = "ca-app-pub-3940256099942544/1033173712"
    // リワード広告用のフィールド、広告ユニットIDはテスト用のID
    private var rewarde:RewardedAd? = null
    private val rewardeId = "ca-app-pub-3940256099942544/5224354917"

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main)

        MobileAds.initialize(this)
        var adView:AdView = findViewById(R.id.adView)
        adView.loadAd(AdRequest.Builder().build())

        webView = findViewById(R.id.webView)
        webView.settings.javaScriptEnabled = true;
        webView.loadUrl("https://example.com/sample.html")
        webView.addJavascriptInterface(WebAppInterface(this), "Android")
    }

    override fun onResume() {
        super.onResume()

        loadInterstitial()
        // リワード広告をロード
        loadRewarde()
    }

    private fun loadInterstitial(){
        val adRequest = AdRequest.Builder().build()
        InterstitialAd.load(this, interAdId, adRequest, object:InterstitialAdLoadCallback(){
            override fun onAdLoaded(p0: InterstitialAd) {
                super.onAdLoaded(p0)
                interstitial = p0
                interstitial?.fullScreenContentCallback = object:FullScreenContentCallback(){
                    override fun onAdDismissedFullScreenContent() {
                        super.onAdDismissedFullScreenContent()
                        webView.loadUrl("javascript:rewrite('Androidからの通信です')")
                    }
                    override fun onAdShowedFullScreenContent() {
                        super.onAdShowedFullScreenContent()
                        interstitial = null
                    }
                }
            }
            override fun onAdFailedToLoad(p0: LoadAdError) {
                super.onAdFailedToLoad(p0)
                interstitial = null
            }
        })
    }

    fun showInterstitial() {
        if(interstitial != null) {
            interstitial?.show(this)
        }
    }

    // リワード広告のロード
    private fun loadRewarde() {
        val adRequest = AdRequest.Builder().build()
        RewardedAd.load(this, rewardeId, adRequest, object:RewardedAdLoadCallback(){
            // ロード成功時
            override fun onAdLoaded(p0: RewardedAd) {
                super.onAdLoaded(p0)
                rewarde = p0
                rewarde?.fullScreenContentCallback = object:FullScreenContentCallback(){
                    // 広告がクリックされた時
                    override fun onAdClicked() {
                        super.onAdClicked()
                    }
                    // 広告が閉じられた時
                    override fun onAdDismissedFullScreenContent() {
                        super.onAdDismissedFullScreenContent()
                        webView.loadUrl("javascript:rewrite('リワード広告が閉じられました')")
                    }
                    // 広告のインプレッションが記録された時
                    override fun onAdImpression() {
                        super.onAdImpression()
                    }
                    // 広告の表示成功した時
                    override fun onAdShowedFullScreenContent() {
                        super.onAdShowedFullScreenContent()
                        rewarde = null
                    }
                }
            }
            // ロードが失敗した時
            override fun onAdFailedToLoad(p0: LoadAdError) {
                super.onAdFailedToLoad(p0)
                rewarde = null
            }
        })
    }

    // リワード広告を表示
    fun showRewarde() {
        // ロードが成功しているなら実行
        if(rewarde != null) {
            rewarde?.show(this, OnUserEarnedRewardListener{ rewardItem ->
                val rewardAmount = rewardItem.amount
                val rewardType = rewardItem.type
            })
        }
    }

    class WebAppInterface(private val context:Context) {
        val handler: Handler = Handler(Looper.getMainLooper())

        @JavascriptInterface
        fun showInterstitialAd() {
            handler.post(Runnable {
                val act: MainActivity = context as MainActivity
                if(act != null) { act.showInterstitial() }
            })
        }
        @JavascriptInterface
        fun showRewardeAd() {
            handler.post(Runnable {
                val act: MainActivity = context as MainActivity
                // リワード広告を表示
                if(act != null) { act.showRewarde() }
            })
        }
    }
}

Webサイトの「リワード広告を表示」ボタンをクリックすると、Android側のshowRewardeAd()が呼び出されリワード広告が表示される。閉じるとWebサイトのPタグが、Android側から渡された「リワード広告が閉じられました」というテキストに変更される。

これでガワネイティブアプリでAdMob広告を一通り表示できた。

参考サイト

【Kotlin/Android Studio】AdMobでリワード広告の実装方法!動画視聴で報酬

コメント

タイトルとURLをコピーしました