ItzjustElias/CarScanner

An Android app that identifies cars from photos using AI, rates how rare they are, and turns car spotting into a collection game.

Kotlin

4

4 commits

updated Oct 13, 2026

See the code

See what people are saying

SourceMessageScoreDate

Visited the Zoute Grand Prix in Knokke, found every car/parking app overly monetized, so I built my own free open-source car scanner in Kotlin / Jetpack Compose (r/SideProject)

Last sunday, I visited the Zoute Grand Prix in Knokke and noticed how frustratingly overly monetized and paywalled most car-scanning apps were. Instead of complaining about it, I decided to build my own :) I wanted to share what I've built so far and hear your feedback! # Tech Stack: *…

1

Oct 13, 2026

Visited the Zoute Grand Prix in Knokke, found every car/parking app overly monetized, so I built my own free open-source car scanner in Kotlin / Jetpack Compose (r/coolgithubprojects)

Last sunday, I visited the Zoute Grand Prix in Knokke and noticed how frustratingly overly monetized and paywalled most car-scanning apps were. Instead of complaining about it, I decided to build my own :) I wanted to share what I've built so far and hear your feedback! # Tech Stack: *…

1

Oct 13, 2026

README

CarScanner App

🚗 CarScanner

Spot a car. Snap it. Collect it.

An Android app that identifies cars from photos using AI, rates how rare they are,
and turns car spotting into a collection game.


License: MIT Platform Kotlin Jetpack Compose

Gemini Firebase No Server Cost

Stars Forks Issues PRs Welcome Last commit


Features · Rarity Tiers · Build It · Scoring · Troubleshooting · Contributing


📖 Table of Contents

Click to expand

✨ About

Take a photo of a car (or pick one from your gallery) and CarScanner tells you what it is, how rare it is, and how much it's worth. Every scan earns points based on rarity and value, so you level up and fill your garage with a collection of cards.

[!TIP] Designed to be forked. Anyone can run their own copy on their own phone for free, using their own Firebase project and their own Gemini API key. No server required.

(back to top)

🎯 Features

FeatureDetails
📸Two ways to scanLive camera with a viewfinder, or pick an image from your gallery
🧠AI identificationMake, model, year, body style, estimated value, production numbers and a fun fact
💎7 rarity tiersFrom Common all the way to Divine, which has an animated rainbow
🏆Points and levelsScore depends on rarity, value, how few were built, age and AI certainty
🏠GarageYour collection as rarity-colored cards, paged for speed, with search, filters and sorting
📊Profile pageLevel, total garage value, unique models, scans this week, favorite brand, per-rarity breakdown, best scoring and most valuable cars
🛠️Fix wrong scansTap "Not the right car?", type the real car and the AI fills in the details
🔐Google sign-inWith delete and sign-out confirmations
🌐Web-search groundingOptional, lets the AI look up very new cars
🔒Local dataEverything stays on your phone, separate per Google account

[!NOTE] Re-scanning a model you already own only earns 10% of the normal points, so no farming the same parked Civic.

(back to top)

💎 Rarity Tiers

TierBadgeBase points
CommonCommon10
UncommonUncommon20
RareRare40
EpicEpic70
LegendaryLegendary120
MythicalMythical200
DivineDivine350

[!NOTE] The badge colors above are approximations for this README. The exact in-app colors live in the theme code.

(back to top)

🧰 Tech Stack

Kotlin Jetpack Compose Material 3 Firebase Gemini Gradle

AreaLibrary
UIJetpack Compose (Material 3)
CameraCameraX
StorageRoom + Paging 3
AuthFirebase Auth + Credential Manager (Google sign-in)
ImagesCoil
NetworkingOkHttp
AIGemini API

(back to top)

🚀 Build It Yourself

About 15 minutes. You need:

  • Android Studio (latest stable)
  • A Google account
  • An Android phone, or an emulator with Google Play
flowchart LR
    A[1. Clone] --> B[2. Firebase]
    B --> C[3. Gemini key]
    C --> D[4. Run]
    style A fill:#7F52FF,color:#fff,stroke:none
    style B fill:#DD2C00,color:#fff,stroke:none
    style C fill:#8E75B2,color:#fff,stroke:none
    style D fill:#3DDC84,color:#000,stroke:none

1️⃣ Clone and open

git clone https://github.com/ItzjustElias/CarScanner.git

Open the folder in Android Studio and let Gradle sync. It will fail until step 2 is done, that's expected.

2️⃣ Create a free Firebase project (Google sign-in)

  1. Go to the Firebase console and click Add project. The free Spark plan is enough, no credit card needed.
  2. Add an Android app with package name com.example.carscanner (if you change the package name in app/build.gradle.kts, use that one instead).
  3. Add your debug SHA-1 to that app. In Android Studio open the Gradle panel, then app > Tasks > android > signingReport, and copy the SHA1 of the debug variant. Or run ./gradlew signingReport in a terminal.
  4. In Firebase go to Build > Authentication > Get started > Sign-in method and enable Google.
  5. Download google-services.json (Project settings > Your apps) and put it in the app/ folder.

[!WARNING] Do not commit google-services.json. It's already in .gitignore.

[!IMPORTANT] Download google-services.json after enabling Google sign-in and adding the SHA-1, otherwise it won't contain the web client ID the app needs.

3️⃣ Get a free Gemini API key

  1. Go to Google AI Studio and create an API key (free tier, no card).
  2. In the project root, create or open local.properties (Android Studio creates it) and add:
GEMINI_API_KEY=your_key_here
# Optional:
GEMINI_MODEL=gemini-2.5-flash
GEMINI_SEARCH=true

See local.properties.example. This file is git-ignored.

4️⃣ Run it

Connect your phone with USB debugging on (or start an emulator) and press Run ▶️.

To keep the app installed, use Build > Build APK(s) and install the APK on your phone.

(back to top)

⚙️ Configuration

Setting (local.properties)DefaultWhat it does
GEMINI_API_KEYnoneYour Gemini API key (required)
GEMINI_MODELgemini-2.5-flashModel used for scans. Change it if Google renames or retires it
GEMINI_SEARCHtrueLets the AI search the web for very new cars. Set to false if you hit quota errors. The app also falls back automatically

(back to top)

🧮 How Scoring Works

flowchart TD
    A[📸 Photo] --> B[🧠 AI picks a rarity tier]
    B --> C{Very valuable or<br>very limited?}
    C -- yes --> D[Floor enforced:<br>a $5M car can't be Common]
    C -- no --> E[Base points for tier]
    D --> E
    E --> F[+ value bonus<br><i>logarithmic</i>]
    F --> G[+ low production bonus]
    G --> H[+ classic bonus<br><i>30+ and 50+ years</i>]
    H --> I[× AI certainty]
    I --> J{Already scanned<br>this model?}
    J -- yes --> K[10% of points]
    J -- no --> L[🏆 Full points]
    style A fill:#4285F4,color:#fff,stroke:none
    style L fill:#3DDC84,color:#000,stroke:none
    style K fill:#9E9E9E,color:#fff,stroke:none

On top of the base points per tier:

  • 💰 a value bonus (logarithmic, so a $1M car isn't 100x a $10k car)
  • 🏭 a bonus for low production runs
  • 🕰️ a bonus for classics (30+ and 50+ years old)
  • 🎯 multiplied by how certain the AI is, and reduced to 10% for models you've already scanned

The AI picks the tier, then the app enforces a floor for very valuable or very limited cars so a $5M car can't be rated Common.

[!TIP] Want to tweak the balance? All the numbers are in domain/PointsCalculator.kt and domain/Models.kt.

(back to top)

🗂️ Project Structure

app/src/main/java/com/example/carscanner/
├── auth/         Google sign-in (Credential Manager + Firebase)
├── data/         Room database, Gemini API client, repository
├── domain/       rarity tiers, points and level rules
└── ui/
    ├── login/        sign-in screen
    ├── garage/       collection, search/filter, detail sheet, "fix this car"
    ├── scan/         camera, gallery picker, result screen
    ├── profile/      stats page
    ├── theme/        colors, typography, animated rarity styling
    └── components/   shared widgets

(back to top)

⚠️ Important Notes

[!CAUTION] Your API key is compiled into the app. That's fine for your own phone. Never publish an APK you built with your key, and never commit local.properties. For a public app you would need a backend that holds the key.

[!WARNING] Photos are sent to Google's Gemini API for identification. Free-tier requests may be used by Google to improve its products, so avoid photographing license plates or people.

[!NOTE] The AI can be wrong, especially for rare, modified or very new cars. Values and production numbers are estimates, not market data. Use "Not the right car?" to fix a scan.

[!NOTE] Free-tier API limits apply and change over time. Check Google's rate limit docs and your usage in AI Studio.

(back to top)

🩺 Troubleshooting

Build error: default_web_client_id not found

google-services.json has no web client ID. Enable Google sign-in in Firebase, add your SHA-1, re-download the file, then clean and rebuild.

Fallback: copy the Web client ID from Firebase into a string resource and reference it in auth/AuthManager.kt.

Google sign-in fails ("developer error")

The SHA-1 in Firebase doesn't match your build. Re-add it and re-download google-services.json.

"Missing Gemini API key"

Add GEMINI_API_KEY to local.properties and rebuild.

"Free daily limit reached"

You hit the free quota. Wait for it to reset, or set GEMINI_SEARCH=false.

"That Gemini model isn't available"

Change GEMINI_MODEL to a current model from AI Studio.

(back to top)

🗺️ Roadmap

  • Camera and gallery scanning
  • Rarity tiers, points and levels
  • Garage with search, filters and sorting
  • Profile and stats page
  • Fix wrong scans
  • Achievements
  • Export / backup
  • Full car detail page
  • Dark / light theme toggle
  • More languages

See the open issues for proposed features and known problems.

(back to top)

🤝 Contributing

Contributions make open source great, and they are greatly appreciated. Issues and pull requests are welcome.

  1. Fork the project
  2. Create your feature branch (git checkout -b feature/amazing-feature)
  3. Commit your changes (git commit -m 'Add amazing feature')
  4. Push to the branch (git push origin feature/amazing-feature)
  5. Open a pull request

[!WARNING] Please don't commit secrets or google-services.json.

Contributors

(back to top)

📄 License

Distributed under the MIT License. See LICENSE for more information.

This project is not affiliated with Google, Firebase or any car manufacturer. Brand names belong to their respective owners.


If you like CarScanner, give it a ⭐ and go spot something rare!

Star History

ai-car-scan
ai-car-scanner
ai-scanner
android-app
car
cars
carscanner
gemini-api
jetpack-compose
kotlin
kotlin-android
ocr

ItzjustElias/CarScanner

An Android app that identifies cars from photos using AI, rates how rare they are, and turns car spotting into a collection game.

Kotlin

4

4 commits

updated Oct 13, 2026

See the code

See what people are saying

SourceMessageScoreDate

Visited the Zoute Grand Prix in Knokke, found every car/parking app overly monetized, so I built my own free open-source car scanner in Kotlin / Jetpack Compose (r/SideProject)

Last sunday, I visited the Zoute Grand Prix in Knokke and noticed how frustratingly overly monetized and paywalled most car-scanning apps were. Instead of complaining about it, I decided to build my own :) I wanted to share what I've built so far and hear your feedback! # Tech Stack: *…

1

Oct 13, 2026

Visited the Zoute Grand Prix in Knokke, found every car/parking app overly monetized, so I built my own free open-source car scanner in Kotlin / Jetpack Compose (r/coolgithubprojects)

Last sunday, I visited the Zoute Grand Prix in Knokke and noticed how frustratingly overly monetized and paywalled most car-scanning apps were. Instead of complaining about it, I decided to build my own :) I wanted to share what I've built so far and hear your feedback! # Tech Stack: *…

1

Oct 13, 2026

README

CarScanner App

🚗 CarScanner

Spot a car. Snap it. Collect it.

An Android app that identifies cars from photos using AI, rates how rare they are,
and turns car spotting into a collection game.


License: MIT Platform Kotlin Jetpack Compose

Gemini Firebase No Server Cost

Stars Forks Issues PRs Welcome Last commit


Features · Rarity Tiers · Build It · Scoring · Troubleshooting · Contributing


📖 Table of Contents

Click to expand

✨ About

Take a photo of a car (or pick one from your gallery) and CarScanner tells you what it is, how rare it is, and how much it's worth. Every scan earns points based on rarity and value, so you level up and fill your garage with a collection of cards.

[!TIP] Designed to be forked. Anyone can run their own copy on their own phone for free, using their own Firebase project and their own Gemini API key. No server required.

(back to top)

🎯 Features

FeatureDetails
📸Two ways to scanLive camera with a viewfinder, or pick an image from your gallery
🧠AI identificationMake, model, year, body style, estimated value, production numbers and a fun fact
💎7 rarity tiersFrom Common all the way to Divine, which has an animated rainbow
🏆Points and levelsScore depends on rarity, value, how few were built, age and AI certainty
🏠GarageYour collection as rarity-colored cards, paged for speed, with search, filters and sorting
📊Profile pageLevel, total garage value, unique models, scans this week, favorite brand, per-rarity breakdown, best scoring and most valuable cars
🛠️Fix wrong scansTap "Not the right car?", type the real car and the AI fills in the details
🔐Google sign-inWith delete and sign-out confirmations
🌐Web-search groundingOptional, lets the AI look up very new cars
🔒Local dataEverything stays on your phone, separate per Google account

[!NOTE] Re-scanning a model you already own only earns 10% of the normal points, so no farming the same parked Civic.

(back to top)

💎 Rarity Tiers

TierBadgeBase points
CommonCommon10
UncommonUncommon20
RareRare40
EpicEpic70
LegendaryLegendary120
MythicalMythical200
DivineDivine350

[!NOTE] The badge colors above are approximations for this README. The exact in-app colors live in the theme code.

(back to top)

🧰 Tech Stack

Kotlin Jetpack Compose Material 3 Firebase Gemini Gradle

AreaLibrary
UIJetpack Compose (Material 3)
CameraCameraX
StorageRoom + Paging 3
AuthFirebase Auth + Credential Manager (Google sign-in)
ImagesCoil
NetworkingOkHttp
AIGemini API

(back to top)

🚀 Build It Yourself

About 15 minutes. You need:

  • Android Studio (latest stable)
  • A Google account
  • An Android phone, or an emulator with Google Play
flowchart LR
    A[1. Clone] --> B[2. Firebase]
    B --> C[3. Gemini key]
    C --> D[4. Run]
    style A fill:#7F52FF,color:#fff,stroke:none
    style B fill:#DD2C00,color:#fff,stroke:none
    style C fill:#8E75B2,color:#fff,stroke:none
    style D fill:#3DDC84,color:#000,stroke:none

1️⃣ Clone and open

git clone https://github.com/ItzjustElias/CarScanner.git

Open the folder in Android Studio and let Gradle sync. It will fail until step 2 is done, that's expected.

2️⃣ Create a free Firebase project (Google sign-in)

  1. Go to the Firebase console and click Add project. The free Spark plan is enough, no credit card needed.
  2. Add an Android app with package name com.example.carscanner (if you change the package name in app/build.gradle.kts, use that one instead).
  3. Add your debug SHA-1 to that app. In Android Studio open the Gradle panel, then app > Tasks > android > signingReport, and copy the SHA1 of the debug variant. Or run ./gradlew signingReport in a terminal.
  4. In Firebase go to Build > Authentication > Get started > Sign-in method and enable Google.
  5. Download google-services.json (Project settings > Your apps) and put it in the app/ folder.

[!WARNING] Do not commit google-services.json. It's already in .gitignore.

[!IMPORTANT] Download google-services.json after enabling Google sign-in and adding the SHA-1, otherwise it won't contain the web client ID the app needs.

3️⃣ Get a free Gemini API key

  1. Go to Google AI Studio and create an API key (free tier, no card).
  2. In the project root, create or open local.properties (Android Studio creates it) and add:
GEMINI_API_KEY=your_key_here
# Optional:
GEMINI_MODEL=gemini-2.5-flash
GEMINI_SEARCH=true

See local.properties.example. This file is git-ignored.

4️⃣ Run it

Connect your phone with USB debugging on (or start an emulator) and press Run ▶️.

To keep the app installed, use Build > Build APK(s) and install the APK on your phone.

(back to top)

⚙️ Configuration

Setting (local.properties)DefaultWhat it does
GEMINI_API_KEYnoneYour Gemini API key (required)
GEMINI_MODELgemini-2.5-flashModel used for scans. Change it if Google renames or retires it
GEMINI_SEARCHtrueLets the AI search the web for very new cars. Set to false if you hit quota errors. The app also falls back automatically

(back to top)

🧮 How Scoring Works

flowchart TD
    A[📸 Photo] --> B[🧠 AI picks a rarity tier]
    B --> C{Very valuable or<br>very limited?}
    C -- yes --> D[Floor enforced:<br>a $5M car can't be Common]
    C -- no --> E[Base points for tier]
    D --> E
    E --> F[+ value bonus<br><i>logarithmic</i>]
    F --> G[+ low production bonus]
    G --> H[+ classic bonus<br><i>30+ and 50+ years</i>]
    H --> I[× AI certainty]
    I --> J{Already scanned<br>this model?}
    J -- yes --> K[10% of points]
    J -- no --> L[🏆 Full points]
    style A fill:#4285F4,color:#fff,stroke:none
    style L fill:#3DDC84,color:#000,stroke:none
    style K fill:#9E9E9E,color:#fff,stroke:none

On top of the base points per tier:

  • 💰 a value bonus (logarithmic, so a $1M car isn't 100x a $10k car)
  • 🏭 a bonus for low production runs
  • 🕰️ a bonus for classics (30+ and 50+ years old)
  • 🎯 multiplied by how certain the AI is, and reduced to 10% for models you've already scanned

The AI picks the tier, then the app enforces a floor for very valuable or very limited cars so a $5M car can't be rated Common.

[!TIP] Want to tweak the balance? All the numbers are in domain/PointsCalculator.kt and domain/Models.kt.

(back to top)

🗂️ Project Structure

app/src/main/java/com/example/carscanner/
├── auth/         Google sign-in (Credential Manager + Firebase)
├── data/         Room database, Gemini API client, repository
├── domain/       rarity tiers, points and level rules
└── ui/
    ├── login/        sign-in screen
    ├── garage/       collection, search/filter, detail sheet, "fix this car"
    ├── scan/         camera, gallery picker, result screen
    ├── profile/      stats page
    ├── theme/        colors, typography, animated rarity styling
    └── components/   shared widgets

(back to top)

⚠️ Important Notes

[!CAUTION] Your API key is compiled into the app. That's fine for your own phone. Never publish an APK you built with your key, and never commit local.properties. For a public app you would need a backend that holds the key.

[!WARNING] Photos are sent to Google's Gemini API for identification. Free-tier requests may be used by Google to improve its products, so avoid photographing license plates or people.

[!NOTE] The AI can be wrong, especially for rare, modified or very new cars. Values and production numbers are estimates, not market data. Use "Not the right car?" to fix a scan.

[!NOTE] Free-tier API limits apply and change over time. Check Google's rate limit docs and your usage in AI Studio.

(back to top)

🩺 Troubleshooting

Build error: default_web_client_id not found

google-services.json has no web client ID. Enable Google sign-in in Firebase, add your SHA-1, re-download the file, then clean and rebuild.

Fallback: copy the Web client ID from Firebase into a string resource and reference it in auth/AuthManager.kt.

Google sign-in fails ("developer error")

The SHA-1 in Firebase doesn't match your build. Re-add it and re-download google-services.json.

"Missing Gemini API key"

Add GEMINI_API_KEY to local.properties and rebuild.

"Free daily limit reached"

You hit the free quota. Wait for it to reset, or set GEMINI_SEARCH=false.

"That Gemini model isn't available"

Change GEMINI_MODEL to a current model from AI Studio.

(back to top)

🗺️ Roadmap

  • Camera and gallery scanning
  • Rarity tiers, points and levels
  • Garage with search, filters and sorting
  • Profile and stats page
  • Fix wrong scans
  • Achievements
  • Export / backup
  • Full car detail page
  • Dark / light theme toggle
  • More languages

See the open issues for proposed features and known problems.

(back to top)

🤝 Contributing

Contributions make open source great, and they are greatly appreciated. Issues and pull requests are welcome.

  1. Fork the project
  2. Create your feature branch (git checkout -b feature/amazing-feature)
  3. Commit your changes (git commit -m 'Add amazing feature')
  4. Push to the branch (git push origin feature/amazing-feature)
  5. Open a pull request

[!WARNING] Please don't commit secrets or google-services.json.

Contributors

(back to top)

📄 License

Distributed under the MIT License. See LICENSE for more information.

This project is not affiliated with Google, Firebase or any car manufacturer. Brand names belong to their respective owners.


If you like CarScanner, give it a ⭐ and go spot something rare!

Star History

ai-car-scan
ai-car-scanner
ai-scanner
android-app
car
cars
carscanner
gemini-api
jetpack-compose
kotlin
kotlin-android
ocr