Androidアプリ開発

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

この記事は約29分で読めます。
スポンサーリンク

こんにちは、まっさん(@Tera_Msaki)です。

この記事は Android スマホ用のアプリ開発の中で、
今後の開発で再使用性が高いと思われるコーディングをまとめたものです。
Java での開発経験、XML 構文規則、Android のアプリ開発経験がある方を対象としています。
Android のアプリ開発でお役にたててれば、嬉しいです。
(これから Android のアプリ開発や Java での開発を始めたい方への案内は、
記事の最後で紹介します)

この記事のテーマ


 Google Mobile Ads SDK を使用して、アプリにインタースティシャル広告を実装する

インタースティシャル広告 は、画面全面に表示する広告のことです。
アプリ画面の一部として表示するバナー広告と違って、
アプリ利用者の利便性を下げる可能性がありますが、
バナー広告に比べて、クリック率が高い傾向にあり、
収益の向上に期待がもてるようになります。

インタースティシャル広告をアプリに実装する

Google Mobile Ads SDKcom.google.android.gms:play-services-ads )は、
バナー広告の実装でも利用しているライブラリで、
バナー広告を実装済みであれば、プロジェクト・アプリのビルド環境( Gradleファイル)が設定済みのため、
新しく設定する必要はありません。
AdMobの管理画面で、インタースティシャル広告の広告ユニットを追加するだけで、
インタースティシャル広告が使用できるようになります。
今回は、バナー広告の実装済みのアプリに
新しくインタースティシャル広告を追加で実装する方法について、解説したいと思います。

◎インタースティシャル広告の注意点
インタースティシャル広告の実装には、禁止事項 があります。
アプリの読み込み時や終了時の表示、過度の繰り返し、予期しないタイミングでの表示などです。
過度の繰り返しについては、アプリ側でコントロールする方法と、
広告ユニットの
フリークエンシーキャップ の設定で行えます。
広告を表示するタイミングとして、
アプリの利用者が広告を見る余裕のあるタイミングで、
アプリのコンテンツが切り替わる合間とガイドラインで定義しています。

ある特定機能の使用でインタースティシャル広告を表示させたい場合、
フリークエンシーキャップでは表示間隔は制限できても、使用回数で制限できません。
使用回数で制限したい場合は、アプリ側でコントロールする必要があります。

フリークエンシーキャップを有効にして、10分間に1回表示で制限します。

◎インタースティシャル広告クラス
インタースティシャル広告の制御は、AdInterstotial クラスとして実装します。
インタースティシャル広告の表示は、所定回数( SHOW)の表示指示で広告を表示するよう実装します。
表示指示の回数は、
一時ファイルに保持して、アプリ終了時も値を永続化させます。

public class AdInterstitial {
    private static final boolean    DEBUG = false;
    private static final String     TAG = AdInterstitial.class.getSimpleName();
    private static final String     AD_SHOW_COUNT = "AD_SHOW_COUNT";
    private static final int        SHOW = 5;
    private InterstitialAd          interstitialAd;
    public boolean                  interstitialAdLoaded = false;
    private int                     errorCode;
    private String                  errorDomain;
    private String                  errorMessage;
    private ResponseInfo            responseInfo;
    private AdError                 cause;
    private final String            temporary;
    private final PropertiesHandler temporaryHandler;
    private int                     count;

    // コンストラクタ //
    public AdInterstitial(Context context, String adUnitId) {
        temporary = String.format("%s.temporary",context.getString(R.string.app_name));
        temporaryHandler = new PropertiesHandler(context);
        count = Integer.parseInt(temporaryHandler.getProperty(temporary, AD_SHOW_COUNT, "1"));
        AdRequest adRequest = new AdRequest.Builder().build();
        InterstitialAd.load(context, adUnitId, adRequest,
                new InterstitialAdLoadCallback() {
                    @Override
                    public void onAdLoaded(@NonNull InterstitialAd newInterstitialAd) {
                        interstitialAd = newInterstitialAd;
                        interstitialAd.setFullScreenContentCallback(new FullScreenContentCallback() {
                                                                        @Override
                                                                        public void onAdClicked() {
                                                                            // Called when a click is recorded for an ad.
                                                                            if (DEBUG) Log.d(TAG, "Ad was clicked.");
                                                                        }
                                                                        @Override
                                                                        public void onAdDismissedFullScreenContent() {
                                                                            // Called when ad is dismissed.
                                                                            // Set the ad reference to null so you don't show the ad a second time.
                                                                            if (DEBUG) Log.d(TAG, "Ad dismissed fullscreen content.");
                                                                            unsetInterstitialAd();
                                                                        }
                                                                        @Override
                                                                        public void onAdFailedToShowFullScreenContent(@NonNull AdError adError) {
                                                                            // Called when ad fails to show.
                                                                            if (DEBUG)  Log.e(TAG, "Ad failed to show fullscreen content.");
                                                                            unsetInterstitialAd();
                                                                        }
                                                                        @Override
                                                                        public void onAdImpression() {
                                                                            // Called when an impression is recorded for an ad.
                                                                            if (DEBUG)  Log.d(TAG, "Ad recorded an impression.");
                                                                        }
                                                                        @Override
                                                                        public void onAdShowedFullScreenContent() {
                                                                            // Called when ad is shown.
                                                                            if (DEBUG)  Log.d(TAG, "Ad showed fullscreen content.");
                                                                        }
                                                                    });
                        interstitialAdLoaded = true;
                    }
                    @Override
                    public void onAdFailedToLoad(@NonNull LoadAdError loadAdError) {
                        // Gets the domain from which the error came.
                        errorDomain = loadAdError.getDomain();
                        // Gets the error code. See
                        // https://developers.google.com/android/reference/com/google/android/gms/ads/AdRequest#constant-summary
                        // for a list of possible codes.
                        errorCode = loadAdError.getCode();
                        // Gets an error message.
                        // For example "Account not approved yet". See
                        // https://support.google.com/admob/answer/9905175 for explanations of
                        // common errors.
                        errorMessage = loadAdError.getMessage();
                        // Gets additional response information about the request. See
                        // https://developers.google.com/admob/android/response-info for more
                        // information.
                        responseInfo = loadAdError.getResponseInfo();
                        // Gets the cause of the error, if available.
                        cause = loadAdError.getCause();
                        // All of this information is available via the error's toString() method.
                        if (DEBUG) Log.d(TAG, loadAdError.toString());
                        unsetInterstitialAd();
                    }
                });
    }

    // エラー取得 //
    public String  getErrorDomain() { return errorDomain; }
    public int getErrorCode() { return errorCode; }
    public String getErrorMessage() { return errorMessage; }
    public ResponseInfo getResponseInfo() {return responseInfo; }
    public AdError getCause() { return cause;}

    // 広告表示 //
    public void adInterstitialShow(Activity activity){
        if (DEBUG) Log.d(TAG, String.format("adInterstitialShow : %d", count));
        if (interstitialAd != null) {
            count = SHOW <= count ? 1 : count + 1;
            temporaryHandler.setProperty(temporary, AD_SHOW_COUNT, String.valueOf(count));
            if (SHOW <= count ) interstitialAd.show(activity);
        } else {
            if (DEBUG) Log.d(TAG, "The interstitial ad wasn't ready yet.");
        }
    }

    // 広告初期化 //
    public void unsetInterstitialAd() {
        interstitialAd = null;
        interstitialAdLoaded = false;
    }
}

コンストラクタで一時ファイルから表示指示の回数( AD_SHOW_COUNT )の取得と、
広告ユニットID を使って、インタースティシャル広告( InterstitialAd )をロードします。
広告表示では、表示指示の回数をカウントアップし、
所定の回数以上でロード済みのインタースティシャル広告を表示します。

◎プロパティハンドラークラス
一時ファイルの読み書きは、PropertiesHandler クラスとして実装します。

public class PropertiesHandler {
    private static final boolean    DEBUG = false;
    private static final String     TAG = PropertiesHandler.class.getSimpleName();
    private final File              path;
    private String[]                keyValues;
    private List<String>            keyValueList;

    //コンストラクタ
    public PropertiesHandler(Context context) {
        path = context.getFilesDir();
    }

    //プロパティ読込
    public String getProperty(String propertiesFile,
                              String key,
                              String defaultValue) {
        Properties properties = new Properties();
        String value = null;
        try (FileInputStream fileInputStream = new FileInputStream(new File(path, propertiesFile).toString())) {
            properties.load(fileInputStream);
            value = properties.getProperty(key);
            if (value == null) {
                //プロパティがない場合は追加
                setProperty(propertiesFile,key ,defaultValue);
                value = defaultValue;
            }
            switch (isValueType(defaultValue)) {
                case InputType.TYPE_CLASS_TEXT:
                    break;
                case InputType.TYPE_CLASS_NUMBER:
                    value = isValueType(value) == InputType.TYPE_CLASS_NUMBER ? value: defaultValue;
                    break;
                case InputType.TYPE_NUMBER_FLAG_DECIMAL:
                    value = isValueType(value) == InputType.TYPE_NUMBER_FLAG_DECIMAL ? value: defaultValue;
                    break;
                default:
            }
        } catch (IOException e) {
            Log.d(TAG, Objects.requireNonNull(e.getMessage()));
            e.printStackTrace();
        }
        if (DEBUG) Log.d(TAG, String.format("%s:%s:%s",key,value,defaultValue));
        return value;
    }

    //プロパティ書込
    public void setProperty(String propertiesFile,
                            String key,
                            String newValue) {
        Properties properties = new Properties();
        getProperties(propertiesFile);
        if (keyValues != null) {
            for (int i = 0; i < keyValues.length; i++) {
                //行頭、行末の空白を取り除く
                keyValues[i] = keyValues[i].trim();
                if (keyValues[i] == null || keyValues[i].length() == 0) {
                    //空白
                } else if (keyValues[i].charAt(0) == '#') {
                    //コメント
                } else if (keyValues[i].charAt(0) == '['
                        && keyValues[i].charAt(keyValues[i].length() - 1) == ']') {
                    //セクション
                } else if (keyValues[i].length() >= 3
                        && keyValues[i].contains("=")
                        && keyValues[i].length() > keyValues[i].indexOf("=") + 1) {
                    //キー&バリュー
                    properties.setProperty(keyValues[i].substring(0, keyValues[i].indexOf("=")),
                            keyValues[i].substring(keyValues[i].indexOf("=") + 1));
                }
            }
            properties.remove(key);
        }
        if (newValue.length() > 0) properties.put(key, newValue);
        try (FileOutputStream fileOutputStream = new FileOutputStream(new File(path, propertiesFile).toString())) {
            properties.store(fileOutputStream, "");
        } catch (IOException e) {
            Log.d(TAG, Objects.requireNonNull(e.getMessage()));
            e.printStackTrace();
        }
    }

    //値判定
    public int isValueType(String value) {
        //defaultValueの型を判定
        try {
            float f = Float.parseFloat(value);
            if (value.contains("."))
                //小数点を含む場合はFloat
                return InputType.TYPE_NUMBER_FLAG_DECIMAL;
            else
                //少数点を含まない場合はInteger(Long)
                return InputType.TYPE_CLASS_NUMBER;
        } catch(Exception e) {
            //Floatに型変化できない場合はString
            return InputType.TYPE_CLASS_TEXT;
        }
    }
    :   
}

◎アクティビティ
アクティビティでは、AdInterstotial クラスのインスタンス化とインタースティシャル広告の表示を指示します。
下記のサンプルでは、アクティビティで PLAYボタン をクリックした際に、
インタースティシャル広告を表示するようにしています。
インタースティシャル広告( InterstitialAd
は1回表示すると初期化されるため、
画面のリロードでインタースティシャル広告がロードされるよう、onResumeに配置します。

    private AdInterstitial          adInterstitial;
        : 
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
     setContentView(R.layout.activity_main);
        // Google Mobile Ads SDK を初期化
        MobileAds.initialize(getApplicationContext(), initializationStatus -> {
            if (DEBUG) Log.d(TAG, "MobileAds:onInitialComplete");
        });
        :
        // play ボタン
        play = findViewById(R.id.play);
        play.setOnClickListener(v -> {
            adInterstitial.adInterstitialShow(this);
            :
        });
        :
    }

    // onResume //
    @Override
    protected void onResume() {
        super.onResume();
        :
        // インタースティシャル広告
        adInterstitial = new AdInterstitial(context, context.getString(R.string.adUnitId));
        :
    }

広告ユニットID( adUnitId )は、stings.xml に定義します。

インタースティシャル広告を実装している Androidアプリです。

今回は、ここまでです。

参考 : インタースティシャル広告

誤字脱字、意味不明でわかりづらい、
もっと詳しく知りたいなどのご意見は、
このページの最後にある
コメントか、
こちら
から、お願いいたします♪

ポチッとして頂けると、
次のコンテンツを作成する励みになります♪

ブログランキング・にほんブログ村へ

◎これからAndroidのアプリ開発やJavaでの開発を始めたい方へ

初めての Android のアプリ開発では、アプリケーション開発経験がない方や、
アプリケーション開発経験がある方でも、Java や C# などのオブジェクト指向言語が初めての方は、
書籍などによる独学ではアプリ開発できるようになるには、
かなりの時間がかかりますので、オンラインスクールでの習得をおススメします。

未経験者からシステムエンジニアを目指すのに最適かと、
まずは無料相談から♪

無料でJava言語を学べるのは、かなり魅力的♪
でも、応募資格は35歳以下です

未経験者からプログラマーを目指すのに最適かと、
まずは無料カウンセリングから♪

カリキュラムとサポートがしっかりしています、
お得なキャンペーンとかいろいろやっています♪

ゲーム系に強いスクール、UnityやUnrealEngineを習得するのに最適かと、
まずは無料オンライン相談から♪

コメント欄

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