DEV Community

Cover image for I Built an Android App in 4 Days With Zero Android Experience — Using Claude Code and a Two-Layer AI Protocol
Raio
Raio

Posted on • Edited on

I Built an Android App in 4 Days With Zero Android Experience — Using Claude Code and a Two-Layer AI Protocol

Four days. That's how long it took to go from zero Android experience to a working MVP — with background processing, push notifications, data scraping, chart visualization, and a 10-level alert system.

I'm not a programmer. I'm a control systems engineer. For 15 years, I've been designing control logic for motorcycle ECUs — traction control, quickshifters, drive-by-wire systems for European sport bike manufacturers. My job is drawing flowcharts and writing specifications, then handing them to software engineers who turn them into code. I read C, but I don't write it professionally. My strongest language is VBA.

Kotlin, Jetpack Compose, Gradle — completely foreign territory.

But I had a few weeks off and a real problem to solve.

The Problem

I hold a life insurance product that includes an investment component. The provider's online portal shows almost nothing useful — no charts, no trend visualization, no way to compare performance against a benchmark index. The product had been slowly declining in value, and after the new year, it dropped several steps further. I needed to see the actual data, not just a feeling.

No existing app could do this. So I decided to build one.

The Two-Layer Protocol

Before this project, I built a CAN bus analysis tool (CanAna) using AI in the same way. The two-layer structure — separating Design AI from Implementation AI — already existed at that point. What didn't exist was a protocol. Design documents lived inside a single ChatGPT chat. Nothing was saved locally. There were no structured handover documents, no investigation flow, no rules. When the chat's token limit approached, context silently compressed, and design decisions made days ago drifted without anyone noticing. The result was scorched earth.

That disaster taught me the structure alone isn't enough — you need the protocol. Here's what I built from the wreckage:

Design AI (Claude.ai) — handles requirements analysis, system design, and creates structured implementation instructions as Markdown files. Never touches code. The reason for having a Design AI in the loop is simple: I want to brush up vague requirements to specification level using screenshots, diagrams, and multimodal input — something that's difficult with CLI-based Claude Code.

Implementation AI (Claude Code) — receives specific, scoped instructions and executes them. Writes code, runs builds, reports results. Doesn't make design decisions.

Me — the bridge. I relay instructions, test on real devices, make judgment calls, and handle Git.

When something breaks: investigate first, discuss options, then — and only then — fix. No blind thrashing.

Two-Layer AI Protocol overview

How I arrived at this protocol — what exactly went wrong with CanAna, and what rules emerged from the wreckage — is covered in detail in Article 2.

The Timeline

Day 1 — Drawing the Map

I can read C, but that's in the embedded world. What I actually write day-to-day is VBA and flowcharts. I know what object-oriented programming is — conceptually. I've never used Java, Node.js, or Kotlin. I had zero experience building standalone applications, let alone Android apps. This was my first time opening Android Studio.

The first thing the Design AI and I did was select the tech stack. Kotlin, Jetpack Compose, Material3 — none of these were familiar to me. But the Design AI explained the rationale: these are the de facto standard for Android development in 2026, and there's no reason for a beginner to choose older technologies. That made sense.

Next, we decomposed the entire project into 7 steps. Environment setup, project scaffold, data layer, data normalization, detection logic, UI, background processing. This became the roadmap for the next four days.

By the end of Day 1, builds were passing on both the emulator and the physical device (Xiaomi Mi 13T / Android 15). I hadn't written a single line — not even a single character — of code yet, but I'd confirmed the development foundation was working.

Day 2 — Two Walls at Once

When I started implementing the data layer, I hit two walls simultaneously.

First wall. I'd planned to fetch data from Sony Life Insurance via CSV download, but when the Implementation AI hit the URL from my design doc, it returned a 404. The CSV endpoint had been discontinued. We immediately switched to HTML scraping. But Sony Life's HTML tables were riddled with colspan and rowspan attributes, and the target column positions weren't fixed. It took 4 instruction prompts to establish a dynamic column detection approach.

Second wall. The original design called for Room (Android's ORM) as the local database. Builds wouldn't pass. AGP 9.0 had reduced kapt support, creating a Kotlin version incompatibility with Room's annotation processor. We tried migrating to KSP — still incompatible. After 6 prompts of trial and error, we abandoned Room entirely. SharedPreferences + Gson instead. For an app like ExitWatcher, where normalized data amounts to a few thousand records at most, Gson provides more than sufficient performance.

With zero Android experience, I had no way to predict these landmines. What mattered was how fast we cut our losses after hitting them.

Day 3 — Substance Builds Up

With the data fetching infrastructure in place, the app's substance grew rapidly.

The benchmark index (eMAXIS) data was available as CSV, though encoded in Shift_JIS. With two disparate data sources ready, I implemented the DataNormalizer. It rebases both datasets to 100 as of October 1, 2025, and joins them via date-based INNER JOIN. This isn't just displaying numbers — it's statistical processing that transforms two differently-scaled datasets into a comparable form.

In the afternoon, I moved to detection logic design. Four independent judgment axes: exit price judgment (holdings vs. exit threshold), trend judgment (rate of change over the last N days), deadline judgment (relative performance vs. last defense line), and expiration judgment (days remaining until target date). These results are aggregated into a 10-level ranking system, from S++ to G, each with its own color and emoji. Starting with ✨ and ending with ☠.

When I displayed Japanese text on the emulator, the fonts were broken — CJK fallback was rendering Chinese characters. Bundled Noto Sans JP to fix it. A small issue, but the kind that's embarrassing if you leave it.







ExitWatcher rank detail: 10-tier rating system from S++ to G
Rank Japanese English
S++ 絶好調 Excellent
S+ 好調 Healthy
S 順調 On Track
A 許容範囲 Acceptable
B 要観察 Watch
C 注意 Caution
D 警戒 Warning
E 危険 Danger
F 撤退検討 Consider Exit
G 即撤退 Exit Now
Japanese UI English
ランク詳細説明 Rank Detail
条件 Condition
説明 Description
現在 Current

Day 3 — running on fumes

Day 4 — The Final Push

The last day had the highest task density of all.

First, charts. The Design AI initially recommended Vico, a Compose-native chart library. I was convinced by the explanation and chose Vico. But before implementation started, a thought occurred to me — why not ask Claude Code which library it's more proficient with? I suggested this to the Design AI, who agreed. Claude Code's answer: "I'm more comfortable with MPAndroidChart." We changed course. This experience led to a new rule: before committing to a library, check the Implementation AI's proficiency first.

With MPAndroidChart, we built a dual-line chart, a Y=100 reference line, tap-to-inspect markers, and an 8-level time range filter (1 month through ALL). The X-axis was initially index-based, causing uneven time spacing — fixed by switching to epochDay-based values.

The UI has 6 screens. Main screen (overall judgment card + rank display), chart screen, settings screen, rank detail screen, normalized data table, and debug screen. The settings screen allows users to modify and persist all detection logic parameters from the UI.

Background processing. WorkManager with a OneTimeWorkRequest chain and exponential backoff (×3: 08:15 → 09:00 → 11:15 → 17:00). Sony Life's site only exposes the last 20 business days of data, so the app fetches daily in the background, accumulates history, and merge-deduplicates. If you want historical data, you have to collect it yourself.

Push notifications use edge detection. They fire only when the rank crosses a threshold in either the deterioration or improvement direction. Users can configure those thresholds in settings.







ExitWatcher performance comparison chart: Sony fund vs eMAXIS benchmark
Japanese UI English
パフォーマンス比較 Performance Comparison
ソニー世界株式型GI Sony Global Equity GI
eMAXISオルカン eMAXIS All Country
基準値 Baseline
基準日: 2025/10/01 = 100 Base date: 2025/10/01 = 100
表示データ: 23件 Data points: 23



Time filters: 1/2M, 1M, 3M, 6M, 1Y, 3Y, 5Y







ExitWatcher main screen comparison: Rank D (warning) vs Rank S+ (healthy)
Japanese UI English
総合判定 Overall Verdict
D 警戒 D — Warning
S+ 好調 S+ — Healthy
積立金額 Invested Amount
撤退価格 Exit Price
トレンド(5日) Trend (5-day)
相対パフォ Relative Performance
残り日数 Days Remaining
正規化データ Normalized Data
パフォーマンス比較 Performance Comparison
設定 Settings
終了 Exit


That evening, I installed the APK on the physical device and ran through everything. All screens worked. Background fetching ran. Notifications fired. v1.0.0 MVP complete.

YATTAAA! MVP complete!

What the Numbers Mean

53 structured instruction prompts. 7 step-chats. One assembly chat orchestrating everything. 4 days.

What these numbers represent is density.

Each instruction prompt follows a defined format — what to do, what the completion criteria are, how to report results. Once the Design AI and I align on a requirement, the Design AI automatically generates the instruction prompt in a format the Implementation AI can readily consume. The Implementation AI executes according to that format and returns results in an equally structured form. The Design AI and I review, then issue the next instruction. This cycle ran 53 times.

The 7 steps correspond to development phases: environment setup, scaffold, data layer, normalization, detection logic, UI, background processing. Each step ran in an independent chat, with result reports flowing up to the parent chat — the assembly.

In other words, this isn't a story about "I asked an AI and waited 4 days for an app." It's a story about a human orchestrating 53 concrete cycles of judgment and execution, and driving them to completion in 4 days.

What Failed

Room + kapt on AGP 9.0. An incompatibility impossible to predict without Android experience. 6 prompts to evaluate three options (downgrade AGP, migrate to KSP, abandon Room), landing on SharedPreferences. Time lost: about 2 hours.

Vico chart library. The Design AI recommended it. I was convinced and chose it. But when I asked the Implementation AI which library it was more proficient with, it said MPAndroidChart. Because we checked before implementation started, we changed course with zero rework. Lesson: verify the Implementation AI's proficiency before committing to a library.

Sony Life CSV discontinuation. The data source assumed in the design simply didn't exist. Pivoting to HTML scraping and handling the complex colspan table structure took 4 prompts.

None of these failures derailed the project, because the two-layer protocol contained them. When we hit a wall, the Implementation AI didn't try to thrash its way through alone — it investigated and reported. The Design AI and I discussed options. Only after agreement did we proceed with a fix. This "investigate first, discuss, then fix" flow kept the damage contained and the loss-cutting decisions fast.

This Wasn't a One-Off

Before this project, I built Bridgiron — a desktop development support tool — using the same protocol. Same two-layer separation, same structured handover documents, same discipline.

I've been using Claude Code for about 4 weeks. In that time, I've systematized a reusable protocol for AI-augmented development that works across domains and tech stacks.

What's Next

How this protocol was born is already written. It's the story of what I learned from CanAna's scorched earth, and what rules I established from the wreckage.

Next, I'll write about Bridgiron — the tool that supports the protocol. After that, I'll dig into why the V-model development philosophy from 15 years of automotive ECU work translates directly to AI-augmented development.

If you feel like "AI improves development speed but quality won't stabilize" — it might not be a prompt problem. It might be a process problem.


Control systems engineer, 15 years in motorcycle ECU development. Specializing in traction control and quickshifter logic design for European sport bike manufacturers. Currently systematizing AI-augmented development workflows and documenting what works.

Series:

Top comments (0)