連載ストックリスト:Android版「見開きPDFビューア」開発記録
この記事は、ChatGPTとの壁打ちと、Codex・Android StudioのGemini・Geminiアプリの保存会話、Gitの変更履歴・ソースコードの調査を元に作成しました。配布直前に気づいた想定違いは、筆者自身の振り返りです。
初稿について
全6回の開発記録を、初稿として先行公開します。公開後も説明や構成を推敲し、完成後も同じ記事を更新します。AIの回答は当時の記録として引用し、実装・実行結果で確認できた範囲と未確認の点を本文で補足しています。分かりにくい箇所や説明不足の点があれば、コメントや編集リクエストでお知らせください。
記念バッジを作ることから、コードを一人ずつ届け、引き換え結果をアプリで表示することまで、作業が広がりました。
図1 記念バッジを受け取って表示するまでの流れと、配布運用の全体像です。番号は利用の流れを整理したもので、開発の時系列ではありません。アプリ実装と配布フォームの作業日も同一視していません。
連載一覧
Android用「見開きPDFビューア」を、AIと開発した記録です。第1〜4回は主に時系列、第5〜6回は並行して進めた制作・配布をテーマ別に振り返ります。日付は2026年です。本編全6回に、第4回の補足記事を加えた構成です。
| 回 | 内容 | Qiita |
|---|---|---|
| 第1回 | iOS版からAndroid版へ:移植と最初の2日間 | 第1回を読む |
| 第2回 | クローズドテスト中の品質改善 | 第2回を読む |
| 第3回 | テスト完了から初回製品版公開まで | 第3回を読む |
| 第4回 | 公開後のサンプルPDFカタログとヘルプ | 第4回を読む |
| 第4回補足 | 実機検証と記録の自動化 | 補足を読む |
| 第5回 | アイコン・フィーチャーグラフィック・チップ画像の制作 | 第5回を読む |
| 第6回 | 記念バッジとプロモーションコードの配布 | この記事 |
本編全6回と第4回補足は、初稿として公開中です。第6回は本編の最終回です。
Android用「見開きPDFビューア」のVer.2.0.0に合わせて、公開記念の「こよみバッジ」を用意しました。プロモーションコードで受け取れるようにすれば、アプリを使ってもらう動機になるかもしれないと感じたためです。
ところが、配布する段階で、一つのコードを複数のユーザーに使い回してもらう、という想定では進められないことに気づきました。ユーザーごとに異なるコードを渡す必要があるので、急いでGoogleフォームとGoogle Apps Script(GAS)による配布の仕組みを作ることになりました。
今回は、その前段の画像制作とアプリ側の対応から、配布フォームの相談までを振り返ります。第4回のカタログ・ヘルプ改善と並行していた作業です。プロンプトは原文全文、回答は抜粋。アプリ側の日付は2026年、日本時間で整理しています。フォーム制作の会話の絶対日時は未確認なので、10月19日の製品版公開より前か後かを断定していません。
マンガの4人を、記念バッジにする
アプリのリリースや1周年を記念したバッジを見かけることがあり、自分のアプリでも用意してみたいと思っていました。初回の製品版公開では実現できなかったため、Ver.2.0の公開に合わせて作ることにしました。今後の配布にも使えるよう、まずはマンガの4人それぞれについて、日本語版と英語版の画像を用意しました。
独立記事で紹介するサンプルマンガを制作したCodexの会話では、10月11日の朝に次の依頼を出しています。
キャラ4人の記念バッジを作成してください。1024x1024 px PNG アルファチャンネルなし
4人分を作成しました。すべて 1024×1024 px・RGB PNG・アルファチャンネルなしです。
続けて英語版も依頼しました。
英語版も作成してください。
英語版4点を作成しました。すべて 1024×1024 px・RGB PNG・アルファチャンネルなしです。
保存済みの8画像を読み取り、寸法とRGB形式を確認しました。このうち、今回アプリへ追加したのは「こよみ」のバッジです。ほかの人物の画像は、今後の配布に備えた素材として用意しました。第5回で紹介した通常のBronze/Silver/Goldのチップ画像とは別の記念アイテムです。マンガの制作自体は独立記事で扱います。
図2 初期に制作した日本語版・英語版の8画像。当時の保存素材を縮小して並べています。今回アプリへ追加したのは、こよみのバッジです。
最初は、無料で直接取得する実装だった
バッジを配布する方法ですが、ゲームアプリなどでは無料で購入できるアイテムを含めるケースがあります。また、プロモーションコードを配布している広告なども時々見かけます。バッジを入手する体験は、開発者を応援するバッジの購入手順のチュートリアルになることも期待しました。
同じ10月11日、Android StudioのGeminiへ追加を依頼しています。
Ver.2.0公開記念チップを追加します。まず、必要な変更点を考えてください。
名称: Ver.2.0公開記念こよみバッジ
画像: store_listing/tip-icon/tameshibu_badge_koyomi.png
その後、価格を指定しました。
バッジの価格は0円(無料)にします。
計画を確認して実装を進めた回答には、次のようにあります。
チップ画面 (
TipScreen.kt): ¥0 (無料) 表示と直接取得(Claim)に対応しました。
最初の実装では、こよみバッジを特別扱いし、無料の取得ボタンからアプリ側で取得状態を反映する処理を入れていました。この段階からプロモーションコードで配布していたわけではありません。
通常の商品を、コードで無料引き換えする形へ変える
アプリに機能を追加してから、Play Consoleで商品を登録すると、無料で販売できない国があることに気が付きました。
同日、提供方法を変更する指示を出しています。
Ver.2.0公開記念こよみバッジを、1回限りのアイテムで提供する方法から、Play Consoleの「プロモーション」機能を使用し、アイテムを無料で引き換え可能なコードを生成してユーザーに入力してもらう方法に変更します。無料でアイテムを販売できない国があるためです。
ここにある国ごとの提供可否は、当時その変更を依頼した際の理由です。現在のストア制度を一般的に説明するものとしては扱っていません。
計画の承認後、Geminiは次のように報告しました。
Ver.2.0公開記念こよみバッジの提供方法を、ハードコードされた0円アイテムから、Google Play Consoleの「プロモーション(プロモーションコード)」機能を利用する方式(通常のインアプリ商品ベース)に変更しました。
変更差分でも、無料アイテムを示す特別なプロパティや直接取得の処理を外し、通常の商品として扱う形へ変わったことを確認できます。
第3回で紹介した非消耗型への変更は、購入したものをどう保持するかという話でした。今回は、記念アイテムをどう受け取ってもらうか、という別の変更です。「1回限りのアイテム」という表現も、バッジを一度しか表示できないという意味ではありません。
図3 保存済みこよみバッジと、提供方法の変更。画像は新たに生成せず、当時の制作素材を使用しています。
入力欄を作っても、引き換えまで通るとは限らない
今回使った1回限りのプロモーションコードには、Playストアで入力する方法と、アプリ内のGoogle Play購入画面で入力する方法があります。初めて使う人のために、アプリ内にも案内を用意したいと考えました。現在の利用方法については、Googleの公式説明も確認しています。以下は、その入口を整えていた当時の記録です。
10月11日には、コードを入力する入口の追加を依頼しました。
設定画面の応援リンクの次に「プロモコードを入力」リンクを追加して、プロモーションコードを入力するダイアログを表示・入力できる機能を追加してください。
ユーザーがプロモーションコードを入力し、「利用する」ボタンをタップすると、Google Playストアの公式引き換えURL (
https://play.google.com/redeem?code=...) へディープリンクし、コードが自動入力された状態でスムーズに引き換えを行えるようにしました。
しかし、その後の端末確認ではエラーを報告しています。最初の起動方法の修正後にも、次の依頼が続きました。
端末SC-53Dでプロモーションコードを入力すると、'このコードはご利用いただけません。もう一度お試しください。コードが特定のアプリを対象としている場合は、そのアプリでご利用ください。'エラーが表示される。原因を調べてください。
Geminiは購入画面からの利用手順へ誘導するよう変更し、回答には次の対応が記されています。
ダイアログ内の「応援画面へ移動」ボタンからワンタップで該当画面(
TipScreen)へ直接誘導します。
ただ、別の端末でも相談が続きます。
端末Pixel 8aでゴールドチップを購入する手順で、「コードの利用」が表示されない原因を調べてください。
この回答では、Play Consoleのキャンペーン状態や商品との関連付けが原因として説明されました。しかし、このターンにConsoleを調べた実行記録はなく、実際の登録状態を確認した証拠にはなりません。また、前の回答にある「必ずアプリ内購入フローで入力する必要がある」という断定も、後述するアプリ外での引き換えに関する記録と分けて読む必要があります。
ここで伝えたいのは、入力欄の追加だけで引き換えの流れが完成したわけではなく、端末で起きたことを伝えながら、入口や案内を変更し続けたことです。Google Playでの利用方法は、前述の公式説明と照らし合わせ、当時のAI回答と区別しています。
引き換えた後、アプリへ戻ってもバッジが出ない
プロモーションコードのテストを続けました。Playストアでプロモーションコードを入力してからアプリに戻ると、バッジが表示されないことに気が付きました。
アプリ内で購入した場合は、私が確認した範囲では、購入後にバージョン画面へ必ずバッジが表示されていました。一方、Playストア側で購入・コードの引き換えを済ませてアプリへ戻った場合には、同じ画面に表示されないことがありました。
図4 当時の筆者の確認では、アプリ内の購入では表示され、アプリ外の購入・引き換えから戻ると未表示の場合がありました。下段に、購入状態の再取得を追加した対応を示しています。
10月12日には、その症状を次のように伝えています。
プロモーションコードを利用した直後にアプリを実行して設定画面を開いても、バッジが表示されない。
回答の変更部分を抜粋します。
queryPurchases()メソッドを外部から呼び出し可能なパブリックメソッドに変更しました。
修正差分では、応援画面や設定画面を表示した際に購入状態を再取得する処理を追加しています。アプリの外で引き換えた情報を、アプリ内のバッジ表示へつなぐ変更です。
この会話にはビルド成功と単体テスト8件成功が残っています。後述するように、自分でもコードを使えることを確かめました。ただし、保存された会話・実行記録だけでは、修正後に全端末で引き換えから表示まで確認したとは言えません。途中の対応にはリソースのビルド失敗から修正した記録もあり、最初から順調に完成したわけではありませんでした。
これらは10月19日19:10のv2.0.0(versionCode 33)公開に先立つ開発です。バッジの実装を、製品版公開後に始めたようには並べていません。
配布直前に、コードを一人ずつ渡す仕組みが必要になる
アプリの機能を作ることと、ユーザーへコードを届けることは、別の作業でした。
自分でコードが使えることを確認した後、一部のテスターに配り、問題が起きないか様子を見ました。フィードバックはありませんでしたが、Play Consoleを繰り返し確認するうちに、配布したコードが利用できなくなっていることに気づきました。一つのコードを複数人で使えると思っていたのですが、今回発行した「1回限りのコード」は、一人が使えばほかの人は使えないものでした。
そこでコード配布のテストをいったん中断し、対策を考えました。Geminiで配布方法を調べ、個別配布のためにGoogleフォーム+GASを作りました。それからプロモーションコードを50個作成し、自分で動作を確認して、配布のテストを再開しました。ここでいうテストは、アプリのクローズドテストとは別に、コードの配布・引き換えを確かめる作業です。
最初に50個用意したのは、クローズドテストに参加してくれた人が20人以下で、今回のコード配布のテストに参加する人数も多くはないと見込んだからです。アプリのダウンロード数も大きく伸びている状況ではありませんでした。まずは小さく始め、足りなくなれば追加するつもりでした。これは当時の見込みで、実際に何人が引き換えたかを示す数字ではありません。
配布を中断してから再開するまでの流れと、50個から始めた理由は、私自身の振り返りです。配布方法を相談した内容は、Android Studioではなく、Geminiアプリの会話「Playストアプロモーションコードの消費仕組み」に残っていました。
Googleフォームの回答者にスプレッドシートからプロモーションコードURLを1つずつ自動返信するGASのサンプルコードを教えてください。
Googleフォームの回答送信をトリガーにして、スプレッドシートにストックされた未配布のプロモーションコードURLを1件取り出し、回答者に自動返信するGoogle Apps Script(GAS)のサンプルコードと設定手順です。
回答で提案されたのは、フォームの回答をきっかけに、スプレッドシートの未配布URLを一つ取り出してメールする仕組みです。管理用のCodesシートには、次の列を用意する説明がありました。
| 列 | 内容 |
|---|---|
| A:Code_URL | 配布するコードのURL |
| B:Status | 未配布/配布済みの状態 |
| C:Sent_To | 配布先メールアドレス |
| D:Sent_At | 配布日時 |
複数の回答が同時に来ても同じ在庫を選ばないよう、LockServiceを使う案も含まれています。コードを生成するのはPlay Console側で、GASは用意したコードのURLを選んで配る役割でした。
実際に案内しているこよみバッジのプロモーションコード受取フォームは、Androidスマートフォンで開いてください。プロモーションコードの使用期限は2027年9月30日です。フォームには、コードをメールで送ること、メールアドレスを配布目的で保存・収集することが明記されていました。受取確認とメールの項目も、送信せずに確認しています。
ユーザー側から見ると、フォームでコードを受け取る手順と、Google Playで引き換えてアプリ内で表示を確かめる手順に分かれます。
図5 受取フォーム→メール→Google Playでの引き換え→アプリ内の表示確認。購入状態の反映は、前節で説明した再取得の対応を前提にしています。実際の画面や選択肢は、Google Playの案内に従ってください。
コードの貼り付け方から、メールの押しやすさまで相談する
続いて、設定方法も具体的に尋ねています。
gasサンプルコードを貼り付ける詳細な手順を教えて。
回答には、フォームから渡されるイベント情報を使うため、エディタ上でそのまま実行する方法と、フォームを送信して動かす方法を区別する説明がありました。途中には、Apps ScriptではなくAppSheetの画面が開いてしまったという相談もあります。コードを受け取った後にも、実際の設定を進めるためのやり取りが続いていました。
メールの見た目も変更しています。
GASでプロモーションコードのリンクをタップしやすいボタンスタイルのHTMLメールで送信する書き方を教えて。
GASでボタンスタイルのリンクを含んだHTMLメールを送信する場合、GmailApp.sendEmail のオプション引数 htmlBody を使用します。
長いURLをそのまま渡すだけでなく、スマートフォンでタップしやすくする依頼です。回答ではHTMLメールのボタンと、HTMLを表示できない環境向けの平文本文を用意する方法が提案されています。
在庫の減少と、同じ相手への重複配布を扱う
次に、配り続けると起きる問題への対応を依頼しています。
スプレッドシート内の未配布コードが残り10件以下になったら管理者に警告メールを送る処理を追加して。
スプレッドシート内の未配布コードの残数をカウントし、残り10件以下になった際に管理者へ警告メールを送信する処理を追加したコードです。
さらに、同じメールアドレスで繰り返し回答された場合も相談しました。
同じメールアドレスからの複数回回答でコードが2重配布されないようチェックするGASコードを追加して。
C列(Sent_To)に同じメールアドレスが既に存在するかを事前にチェックし、二重配布をブロックします。
回答には、メールアドレスの前後の空白と大文字・小文字をそろえて比較し、既に配布していれば以前のリンクを再案内する説明があります。同時送信による同じコードの重複と、同じアドレスが新しいコードを繰り返し受け取ることは、分けて扱っていました。ただし、メールアドレスの一致を調べることは、別アドレスも含めた同一人物の判定ではありません。
ここまでの追加依頼とサンプルコードの回答は確認できました。一方、現在稼働しているGAS本体、各改善を統合した最終版、送信結果や実際の二重配布防止のテストは、今回の資料とは照合できていません。通知の頻度や、配布後にメール送信が失敗した場合の再処理まで完成済みとは書いていません。
図6 フォーム・GAS・コード在庫・メールの役割。会話中のサンプル設計を整理したもので、最終GASの動作保証や実コードを含みません。
アプリの外にも、使ってもらうための開発があった
アプリ内の入口とサンプルを整える開発と並行して、今回は、マンガの人物を使った記念アイテムを用意し、コードを受け取り、引き換え、アプリへ戻って表示するまでの流れを作っています。
配布フォームは、最後の段階で気づいた想定違いを埋めるための追加開発でした。これから同じような企画を進めるなら、アイテムの実装と一緒に、コードの渡し方、引き換え方、戻った後の反映まで先に確かめたいと思います。
今回の教訓:バッジの無料配布をアプリ内だけで処理すれば、きっと楽になるに違いない。
この連載は、iOS版を元に当初想定した機能のコードが簡単にそろった驚きから始まりました。その後には、動作を確かめること、端末差に対応すること、読むものや説明を用意すること、配布の仕組みを作ることが続きました。コードがそろうことと、実際に使ってもらうまでの流れがそろうことの間に、多くの作業があった開発記録です。
前の記事:第5回:アイコン・フィーチャーグラフィック・チップ画像の制作
全6回の最終回です。
関連する補足:実機を増やした後の検証と記録の自動化





