「AIでアプリが作れる」とは聞いていたが、本当に動くものができるとは思っていなかった。
筆者はフルスタックエンジニア歴20年超。Androidネイティブ開発は専門外だったが、
Claude Code を使って Kotlin + Jetpack Compose のステップカウンターアプリを約2時間で完成 させた。
その過程で気づいた「ハマりどころ」と「うまくいったプロンプトパターン」をまとめる。
作ったもの:StepLog
- 機能:歩数カウント、日次・週次の歩数グラフ表示、目標歩数の設定
- スタック:Kotlin / Jetpack Compose / Room / MVVM / Material3
- 開発時間:約2時間(Claude Code との対話含む)
- 開発環境:Android Studio Meerkat / Claude Code(ターミナル起動)
なぜ Claude Code を使ったか
業務で Claude Cowork を使い始めてから、Claudeとの対話型作業の速度感に慣れてきた。
「Androidアプリも同じように作れるのでは?」と思い立ち、週末に試してみた。
最初から「完成品を作ってもらう」ではなく、
「設計を一緒に考えながら実装を進める」 スタンスを取ったのが成功の要因だったと思う。
事前準備:CLAUDE.md が鍵
Claude Code でプロジェクトを始める前に、CLAUDE.md を書くことを強く推奨する。
これはプロジェクトルートに置く設定ファイルで、Claude が起動するたびに自動で読み込む。
# StepLog - CLAUDE.md
## スタック
- 言語:Kotlin
- UI:Jetpack Compose(XMLレイアウトは一切使わない)
- アーキテクチャ:MVVM(ViewModel + StateFlow)
- DB:Room
- DI:Hilt
- ターゲットAPI:34(Android 14)、最小API:26(Android 8)
## コーディング規約
- Coroutines + Flow のみ使用(LiveData は使わない)
- UI State は sealed class または data class で定義
- 副作用は ViewModel で管理し、Composable には渡さない
## 禁止事項
- deprecated なAPIは使わない。古いAPIを提案する場合は必ず代替を示すこと
- XMLレイアウトは生成しない
CLAUDE.md に書いておくことで、毎回同じ前置きをプロンプトに書かなくて済む。
「Jetpack Composeで」「MVVMで」などを毎回書く手間がなくなる。
実際の進め方:5ステップ
Step 1: アーキテクチャ設計から始める
いきなりコードを書かせるのではなく、まず設計を言語化させた。
プロンプト:
StepLogアプリのパッケージ構成を提案してください。
機能は歩数カウント、日次/週次グラフ表示、目標設定です。
CLAUDE.md のスタック・規約に従ってください。
Claudeの出力(一部):
com.example.steplog/
├── data/
│ ├── db/
│ │ ├── StepDatabase.kt
│ │ └── StepDao.kt
│ ├── model/
│ │ └── StepRecord.kt
│ └── repository/
│ └── StepRepository.kt
├── domain/
│ └── usecase/
│ └── GetWeeklyStepsUseCase.kt
├── ui/
│ ├── home/
│ │ ├── HomeScreen.kt
│ │ └── HomeViewModel.kt
│ └── history/
│ ├── HistoryScreen.kt
│ └── HistoryViewModel.kt
└── MainActivity.kt
この時点で「設計に納得できるか」を確認する。後から変更するのが一番コストが高い。
Step 2: データ層から実装する
UI から始めると動作確認ができず手戻りが増える。
データ層 → ViewModel → UI の順番 で進めた。
プロンプト:
StepRecord の Roomエンティティ、StepDao、StepDatabaseを実装してください。
StepRecord は date(LocalDate)と steps(Int)を持ちます。
ここでハマったのが LocalDate の Room 対応。
Roomは LocalDate をそのまま保存できないため、TypeConverterが必要になる。
Claudeは自動的に TypeConverter を生成してくれたが、念のため確認は必要。
// Claude が生成した TypeConverter(確認してから採用)
class Converters {
@TypeConverter
fun fromLocalDate(date: LocalDate?): Long? {
return date?.toEpochDay()
}
@TypeConverter
fun toLocalDate(epochDay: Long?): LocalDate? {
return epochDay?.let { LocalDate.ofEpochDay(it) }
}
}
Step 3: ViewModel と StateFlow を実装する
プロンプト:
HomeViewModel を実装してください。
今日の歩数の取得・更新と、目標歩数の設定機能を持ちます。
StateFlow で UI State を管理してください。
UI State は sealed class / data class で定義してもらう。
Loading / Success / Error の状態管理をきちんと書いてもらうのがポイント。
// Claude が生成した UI State の例
data class HomeUiState(
val todaySteps: Int = 0,
val targetSteps: Int = 10000,
val isLoading: Boolean = false,
val error: String? = null
)
Step 4: Compose UI を実装する
データ層と ViewModel が揃った状態でUIを書くと、
「このデータをどう表示するか」に集中できてプロンプトが書きやすい。
プロンプト:
HomeScreen を実装してください。
HomeUiState を受け取り、以下を表示します:
- 今日の歩数(大きなテキスト)
- 目標歩数に対する進捗(LinearProgressIndicator)
- 歩数を手動入力するボタン
Material3 を使ってください。
Compose のプロンプトで重要なのは 「副作用をどこで処理するか」を明示すること。
ダイアログの表示・非表示などは ViewModel の StateFlow で管理するよう指定すると、
Composable がシンプルに保たれる。
Step 5: ビルドエラーを Claude に渡す
実装後、ビルドして出たエラーをそのまま貼り付ける。
以下のビルドエラーを修正してください:
e: /path/to/StepDao.kt:12:5: error: Not sure how to convert a Cursor to this method's return type
エラーメッセージをそのままコピペするだけで、たいていは修正案を出してくれる。
「なぜこのエラーが起きるか」の説明もセットで出てくるので、勉強にもなる。
ハマったポイントと対策
① deprecated な API を提案することがある
Compose は進化が速く、古いAPIが提案されることがある。
CLAUDE.md に deprecated なAPIは使わない と書いておくだけで発生頻度が下がる。
それでも出てきた場合は「このAPIはdeprecatedですか?代替を教えてください」と聞けばよい。
② コンテキストが長くなると精度が落ちる
1セッションで詰め込みすぎると、前半に決めた設計を忘れて矛盾したコードを出すことがある。
機能単位でセッションを区切るのが有効。各セッションの冒頭に「現在の設計は〇〇です」と要約を渡す。
③ Hilt の DI 設定は丁寧にプロンプトを書く
依存関係のスコープ(@Singleton、@ViewModelScoped など)を誤るとランタイムエラーになる。
「ApplicationレベルでSingletonとして提供し、ViewModelにはコンストラクタインジェクションで渡す」
のように詳細に指定すると誤りが減る。
④ センサーAPIは変化が速い。必ず公式ドキュメントと照合する
歩数センサー(TYPE_STEP_COUNTER)の取得コードは、Claudeが古い実装パターンを出すことがある。
Android 14以降のPermissionの扱い(ACTIVITY_RECOGNITION)など、
センサー・パーミッション周りは必ず公式ドキュメントを確認すること。
// パーミッション要求(Android 10以降)
// Claude が提案したコードを確認して採用
<uses-permission android:name="android.permission.ACTIVITY_RECOGNITION"/>
うまくいったプロンプトパターン
| シーン | 効果的なプロンプトの書き方 |
|---|---|
| 設計の相談 | 「〇〇機能を追加したい。現在の設計は△△です。どのように実装すべきか提案してください」 |
| 実装の依頼 | 「△△を実装してください。CLAUDE.mdの規約に従い、〇〇と□□の2つの制約を守ってください」 |
| エラー解消 | ビルドエラーをそのままコピペ+「修正してください」 |
| レビュー依頼 | 「以下のコードにバグや改善点があれば指摘してください」 |
| 疑問の確認 | 「このコードで△△は起きませんか?理由も教えてください」 |
完成品のビルドまでの流れ(再現手順)
# 1. Android Studio で新規プロジェクト作成(Empty Compose Activity)
# 2. CLAUDE.md をプロジェクトルートに作成
# 3. Claude Code を起動
claude
# 4. 以降は対話形式で実装を進める
build.gradle.kts の依存関係追加も Claude に頼める:
現在の build.gradle.kts に以下を追加してください:
Room、Hilt、Compose Navigation の最新安定版。
バージョンカタログ(libs.versions.toml)を使って管理してください。
正直なところ
- 速い:設計さえ固まれば、ボイラープレートを書く時間がほぼゼロになる
- 楽しい:「次はこの機能を足したい」というサイクルが速く回り、モチベーションが保ちやすい
- 過信は禁物:生成されたコードは必ず読む。特に非同期処理・パーミッション・センサーAPIは要確認
- 固有名詞・APIは自分で調べる:Claudeが出してくる固有名詞やAPIの存在は、そのままコピペせず検索で確認する習慣を持つこと(これは筆者が過去に痛い目を見た経験から)
まとめ
Claude Code は「コードを書いてくれるツール」ではなく、
「設計の相談相手 + 実装の補助者」として使うと真価を発揮する。
特に Androidの専門家でない筆者でも2時間でアプリが動いたのは、
CLAUDE.md による文脈の固定と、設計 → データ層 → ViewModel → UI の順序を守ったことが大きかった。
専門外の技術に挑戦する入口として、Claude Code は非常に有効なツールだと実感している。
筆者はフルスタックエンジニア(Web系)。Android専門家ではないため、一部の実装は公式ドキュメントを参照の上で採用しています。誤りがあればコメントで教えていただけると助かります。