見出し画像

AdMob のネイティブ広告テンプレートが盛大にバグっていて困った話|Android|開発裏話

AdMob で「ネイティブ広告」が新たに利用可能になっていましたので、以下の Android アプリ「CountablePad」に搭載してみました。

過去に存在していたネイティブ広告とは大きく異なっていて、少し戸惑いましたが、以下のテンプレートを導入すれば直ぐに搭載可能ということだったので、そのまま従ってみました。

初めての方向けに、ネイティブ テンプレートが用意されています

ネイティブ テンプレートとは、ネイティブ広告として使用できるビューであり、コーディングが完成された状態で提供されるため、実装と変更を簡単に行えます。

初めてのネイティブ広告を数分で実装でき、大量のコードに煩わされることなく短時間でデザインをカスタマイズできます


このテンプレートは、ニュース フィード内で使用するリサイクラー ビューや、ダイアログ、アプリ内の他の場所など、どこでも好きな場所に配置できます。

ネイティブ テンプレートは、Android Studio のモジュールとして提供されているので、プロジェクトに簡単に組み込んで自由に使用できます

テンプレートを組み込めば、そのままでも使用できるとのこと。

ガイドに表示されているネイティブ広告の各イメージは、以下のようなものでした。

画像1

画像2

ところが……!

テンプレートをそのまま組み込んでリリースしたアプリに表示されたネイティブ広告は、以下のような状態でした。

画像3

▲ CountablePad(4.0.2)

・星(レーティング)の表示がおかしい
・意味のない変なバーが表示されている

というバグが混入された状態で、公式ガイドではテンプレートが提供されています。恐ろしい!

コーディングが完成された状態で提供されるため、実装と変更を簡単に行えます

いやいや、結局、不具合解析をするハメになりました。


▲ スポンサードリンク


バグ「意味のない変なバー」について

テンプレートの実装を解析して、判明したのは、このバーは「実はボタン(CallToAction)だ」ということです。

指でタッチしてみたら反応しますし、妙ちくりんなデザインかと思っていたら、広告の縦幅(サイズ)が足りなくて、潰されてしまったボタンでした。

広告の縦幅(サイズ)を大きく変更すると、ちゃんとテキストが設定されたボタンが表示されます。

ただ、このボタンをちゃんとしたサイズで表示し活用しようとすると、広告の縦幅(サイズ)が大きくなってしまうので、最早とても「Small」とは言い難く、それではやはりデザイン的にイマイチでしたので、私はボタンを削除しました。

すると、実行時にエラーが発生して、アプリがクラッシュしてしまいました。

実装を解析すると、このボタン(callToActionView)は、基本的には以下のように null の可能性を想定されていたのですが、

com.google.android.ads.nativetemplates.TemplateView

private void applyStyles() {
    ...

    if (ctaBackground != null && callToActionView != null) {
        callToActionView.setBackground(ctaBackground);
    }

    ...

一部、以下の通り、その実装が足りていませんでした。実装バグです!

com.google.android.ads.nativetemplates.TemplateView

public void setNativeAd(UnifiedNativeAd nativeAd) {
    ...

    callToActionView.setText(cta);

    ...

私の広告にはボタン(callToActionView)が存在しませんので、以上の処理で null にアクセスしてしまいます。

これを、以下のように修正して、クラッシュを防ぎます。

com.google.android.ads.nativetemplates.TemplateView

public void setNativeAd(UnifiedNativeAd nativeAd) {
    ...

    if (callToActionView != null) {
        callToActionView.setText(cta);

    ...

修正後、早速、リリースしたのですが、アプリは以下の状態でした。

画像4

▲ CountablePad(4.0.3)

やっぱり、星(レーティング)の表示がおかしい!


▲ スポンサードリンク


バグ「星(レーティング)の表示」について

まず、テンプレートの実装は以下の通りでした。

res/layout/gnt_small_template_view.xml

<RatingBar
    android:id="@+id/rating_bar"
    android:background="@color/gnt_white"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:textSize="@dimen/gnt_text_size_small"
    android:textColor="@color/gnt_gray"
    android:numStars="0"
    android:lines="1"
    android:layout_marginTop="@dimen/gnt_no_margin"
    android:layout_marginBottom="@dimen/gnt_no_margin"
    android:layout_marginStart="@dimen/gnt_no_margin"
    android:layout_marginEnd="@dimen/gnt_no_margin"
    app:layout_constraintBottom_toBottomOf="parent"
    app:layout_constraintEnd_toEndOf="parent"
    app:layout_constraintStart_toEndOf="@id/ad_notification_view"
    app:layout_constraintTop_toTopOf="parent">

</RatingBar>

RatingBar」を実装した経験があれば直ぐに気がつくことなのですが、小さな星(レーティング)を表示するには、「style="?android:attr/ratingBarStyleSmall"」の実装が必須です!

何故だろう、不思議で仕方がないのですが、「android:textSize」「android:textColor」「android:lines」が実装されています、星(レーティング)は画像ですので、これらの実装は何の意味もありません!

もし、この実装で星(レーティング)のサイズを変更し、色をも変更したかったのならば、実現性テストを全く実施していないテンプレートを公式として提供しているという暴挙です!

以下のように修正します。これで、星(レーティング)は小さくなり、広告内に収まるようになりました。

res/layout/gnt_small_template_view.xml

<RatingBar
    android:id="@+id/rating_bar"
    style="?android:attr/ratingBarStyleSmall"
    android:background="@color/gnt_white"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:numStars="0"
    app:layout_constraintBottom_toBottomOf="parent"
    app:layout_constraintEnd_toEndOf="parent"
    app:layout_constraintStart_toEndOf="@id/ad_notification_view"
    app:layout_constraintTop_toTopOf="parent" />

ところで……先程のスクリーンショットですが、星(レーティング)に色が付いていないことに、気がついたでしょうか?


▲ スポンサードリンク


バグ「星(レーティング)の色」について

実装を解析して本当に驚きましたが、この「RatingBar」に、広告のレーティングである「UnifiedNativeAd#getStarRating」を設定していない!

テンプレートの実装は以下の通りです。広告のレーティングを設定せずに、初期状態の星(レーティング)を表示しただけなのです。

com.google.android.ads.nativetemplates.TemplateView

public void setNativeAd(UnifiedNativeAd nativeAd) {
    ...

    //  Set the secondary view to be the star rating if available.
    if (starRating != null && starRating > 0) {
        secondaryView.setVisibility(GONE);
        ratingBar.setVisibility(VISIBLE);
        ratingBar.setMax(5);
        nativeAdView.setStarRatingView(ratingBar);
    } else {

    ...

実装は以下のように修正します。「RatingBar#setMax」は敢えてここで実装する必要はありませんので、「gnt_small_template_view.xml」に移動します。広告のレーティングは「RatingBar#setRating」で設定します。

com.google.android.ads.nativetemplates.TemplateView

public void setNativeAd(UnifiedNativeAd nativeAd) {
    ...

    //  Set the secondary view to be the star rating if available.
    if (starRating != null && starRating > 0) {
        secondaryView.setVisibility(GONE);
        ratingBar.setVisibility(VISIBLE);
        ratingBar.setRating(starRating.floatValue());
        nativeAdView.setStarRatingView(ratingBar);
    } else {

    ...
res/layout/gnt_small_template_view.xml

<RatingBar
    android:id="@+id/rating_bar"
    style="?android:attr/ratingBarStyleSmall"
    android:background="@color/gnt_white"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:numStars="0"
    android:max="5"
    app:layout_constraintBottom_toBottomOf="parent"
    app:layout_constraintEnd_toEndOf="parent"
    app:layout_constraintStart_toEndOf="@id/ad_notification_view"
    app:layout_constraintTop_toTopOf="parent" />

そういえば、星(レーティング)を小さくした時に気づくのですが、星(レーティング)の数が広告の端まで制限なく表示されています。

そりゃそうです、「android:numStars="0"」というような実装になっていますから。本当に、不具合だらけです!

画像5

▲ CountablePad


▲ スポンサードリンク


バグ「星(レーティング)の数」について

android:numStars="0"」で星(レーティング)の数を指定していないことだけが問題ではなく、「android:layout_width="match_parent"」というように横幅いっぱいに指定しているのも実は問題です。「android:numStars」の指定が無視されてしまうのです。

以下のように修正します。

res/layout/gnt_small_template_view.xml

<RatingBar
    android:id="@+id/rating_bar"
    style="?android:attr/ratingBarStyleSmall"
    android:background="@color/gnt_white"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:layout_gravity="center_vertical"
    android:numStars="5"
    android:max="50"
    android:stepSize="0.1"
    app:layout_constraintBottom_toBottomOf="parent"
    app:layout_constraintEnd_toEndOf="parent"
    app:layout_constraintStart_toEndOf="@id/ad_notification_view"
    app:layout_constraintTop_toTopOf="parent" />

Google Play を利用していれば馴染みなことですが、星(レーティング)は最大が「5」で「0.1」刻みです。

ですので、「android:stepSize="0.1"」を設定し、最大の「5」に到達するまでの総ステップ数である「50」を「android:max="50"」に設定します。実はこの「android:max」は、設定できる星(レーティング)の数ではなく、総ステップ数なのです。

やっと、これで修正できました!

画像6

▲ CountablePad(4.0.4)

※星(レーティング)の色は、別途、以下で変更しています


▲ スポンサードリンク


おわりに

いやはや……正直、Google は、こんな低レベルな実装能力のエンジニアで良いのならば、私を雇ってほしいです!


▲ スポンサードリンク

この記事が気に入ったらサポートをしてみませんか?