2026-08-21 公開 / アプリ開発
広告がコンテンツに重なる違反通知。1回目の修正は、渡したオプションが黙って無視されていた
Androidで公開しているゲーム2本に、「前面で広告がコンテンツに重なっている」という違反通知が届きました。重ならない設定に変えて解決したつもりでしたが、翌日その修正がまったく効いていなかったばかりか、状況を悪化させていたと分かりました。何を間違えたのかと、結局どう直したのかを書きます。
違反の内容
画面下部に出る帯状の広告が、ゲームの操作領域の上に覆いかぶさって描かれているという指摘でした。広告そのものは正しく表示されています。問題は、その下にあるはずのコンテンツが隠れていることです。
この手の指摘は、利用者が誤って広告に触れてしまう状況を防ぐためのものです。ゲームの操作部分が広告の裏に隠れていれば、操作しようとしたタップが広告のタップになります。意図の有無に関係なく、構造として起きうるなら違反という扱いになります。
1回目の修正: 「重ならない」オプションを渡した
使っていた広告表示のライブラリには、バナーを出すときのオプションがあります。ドキュメントを見て、重ねずに表示領域を詰める指定にあたるものを見つけ、それを false にしました。
// 1回目の修正(効いていなかった)
showBanner({ ..., overlap: false });
さらに、それまで手作業で下部に余白を作っていた回避策も一緒に削除しました。重ならない設定にしたのだから、余白を自分で作る処理は二重になる、と考えたからです。
ビルドは通り、実機でも広告は出ました。ここで完了にしました。
実際には、そのオプションは存在しなかった
翌日あらためて確認したところ、使っているバージョンのライブラリに、そのオプションは実装されていませんでした。
ここが一番の落とし穴でした。存在しないオプションを渡しても、エラーは出ません。設定オブジェクトの中の知らないキーは、単に無視されます。ビルドも通りますし、実行時にも何も言われません。渡した側からは、効いているのか無視されているのか区別がつきません。
そして悪いことに、一緒に消した「手作業の余白」のほうは本当に効いていました。効かない設定を足して、効いていた回避策を外したので、差し引きで重なりは修正前より広がっていました。「直した」と判断した操作が、実際には悪化だったことになります。
実機で見て「広告が出ている」ことは確認しましたが、「重なっていないこと」は確認していませんでした。見るべきものが違っていた、という話でもあります。
2回目の修正: 重なりを消すのではなく、先に場所を空ける
考え方を変えました。広告が出てから避けるのではなく、出る前から場所を空けておくという順序にしました。
これは順序の問題として重要です。広告は読み込みに時間がかかり、いつ表示されるかはこちらで決められません。「表示されたことを検知してから画面を縮める」方式だと、検知して縮めるまでのわずかな時間、必ず重なっている瞬間ができます。その瞬間を捉えられれば、それは違反です。
そこで、広告を要求する前に、Web側のレイアウトで下部に帯のぶんの領域を確保してしまうことにしました。
/* 先に場所を空けておく。既定値は帯の標準の高さ */
.stage { height: calc(100dvh - var(--ad-bottom)); }
// 1. 先に確保 → 2. それから広告を要求する
setAdArea(50); // 帯の標準の高さぶん、先に空ける
await showBanner({ ... });
// 3. 実際の高さが分かったら、そこで補正する
addListener('bannerAdSizeChanged', (size) => {
if (size.height > 0) setAdArea(size.height);
});
この順序なら、どの瞬間を切り取っても重なっていません。広告が出るまでの間は、単に下に少し余白があるだけです。
「読み込みに失敗したとき」で、もう一度つまずいた
これで解決かと思いましたが、もう1回直しています。広告の読み込みに失敗したときの扱いです。
空けた場所は、広告が出ないなら無駄です。だから「高さが0で通知が来たら、空けた場所を戻して全画面に広げる」処理を入れていました。ところが実際には、広告が正常に出ている最中にも高さ0の通知が来ることがありました。そのたびに場所の確保が解除され、また重なります。
直し方は、高さ0という数値を信じるのをやめることでした。
- 高さ0の通知は無視する(場所は確保したまま)
- 全画面に戻すのは、「読み込みに失敗した」という明示的な通知が来たときだけ
「値が0だから広告が無い」は推測です。「失敗した」は事実の通知です。推測で状態を変えると、推測が外れたときに元の不具合へ戻ります。
ついでに: 一度使ったバージョン番号は二度と使えない
この修正を配信する過程で、別の壁にも当たりました。ストアへアップロードするとき、すでに使ったことのある内部の通し番号は再利用できません。取り下げたビルドの番号でも、一度受け付けられていれば使えません。
今回は修正を短い間隔で3回配信したので、番号が飛び飛びになりました。表向きのバージョン名は据え置いたまま、内部の番号だけを進めることになります。
この番号は、あとから戻せない数少ない値の1つです。間違えて大きい値で上げてしまうと、それより小さい番号は永久に使えません。今はリポジトリに番号の台帳を置いて、次に使う値をそこで管理しています。覚えておく方式は、修正を急いでいるときに必ず失敗します。
持ち帰れること
- 設定オブジェクトに渡した値は、黙って無視されることがある。効いていないことがエラーにならない以上、効いた結果のほうを確認するしかありません
- 「新しい対策を入れる」と「古い回避策を消す」を同時にやらない。片方が効いていなかったとき、差し引きで悪化します
- 確認する対象を言い換える。「広告が出ている」ではなく「重なっていない」。指摘された言葉のまま確認します
- 避けるのではなく、先に場所を空ける。あとから避ける方式は、避けるまでの一瞬が必ず残ります
- 推測で状態を戻さない。「値が0だから無い」ではなく「失敗した通知が来たから無い」で判断します
- 戻せない値は台帳で管理する。ストアの通し番号のように再利用できないものは、記憶に頼ると急いでいるときに間違えます
この件で残った教訓は、「直したつもり」が最も危ない状態だということです。違反通知が来ている間はまだ見ていますが、直したと判断した瞬間に見るのをやめます。今回はそのあとに悪化していました。直したと言えるのは、指摘された言葉で確認し直したときだけだと思っています。