0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

Claude Code でAndroidアプリを約2時間で作った話【Kotlin / Jetpack Compose】

0
Posted at

「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専門家ではないため、一部の実装は公式ドキュメントを参照の上で採用しています。誤りがあればコメントで教えていただけると助かります。

0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?