Point your camera at anything, know everything.
This is the full feature catalog for LifeLens, grouped into Core (MVP) features that ship for the Qwen Code Hackathon and Stretch features that build on the same foundation. Each major feature lists a short description, a User workflow (the steps the user takes), and a Technical requirements note (the modules and APIs involved).
See the delivery scope in plan.md and the implementation detail in TECHNICAL.md.
These are the features that make LifeLens demoable and complete for the hackathon.
Point the camera at any object and get an identification with a confidence-appropriate answer. This is the heart of the app.
User workflow
- Open LifeLens; the scanner (camera preview) is the home screen.
- Frame the object in view.
- Tap the capture button.
- See a brief loading state while the image is analyzed.
- Land on a results screen showing what it is.
Technical requirements
:feature:scanner— CameraX preview +ImageCapture.:core:network— Qwen-VL call via DashScope (qwen-vl-max/qwen2.5-vl-72b-instruct).:core:data—ScanRepository.identify(...)orchestrates capture → analyze → persist.:core:model— returns a structuredIdentification(name,ScanCategory,attributes).
One Qwen call decides what kind of thing it's looking at and shapes the output accordingly, then a CategoryHandler enriches it.
User workflow
- Scan any object — no mode-switching required.
- LifeLens automatically shows the right layout: nutrition panel for food, spec sheet + price for products, knowledge card for everything else.
Technical requirements
- Structured-output system prompt in
:core:networkthat returnscategory. CategoryHandlerstrategy/registry in:core:data(FoodHandler,ElectronicsHandler,BookHandler,ClothingHandler,PlantHandler,DocumentHandler,GenericHandler) selected byScanCategory.:core:model—ScanCategoryenum.
For products (electronics, appliances, gadgets), show a clean, structured spec sheet.
User workflow
- Scan a product (e.g. a laptop).
- View its identified model.
- Read the spec sheet (key attributes) on the results screen.
Technical requirements
ElectronicsHandlerin:core:datamaps Qwen attributes into spec fields.:core:model—Identification.attributes.:feature:results— spec sheet presentation.
After identifying a product, LifeLens runs a live web/shopping search and has Qwen synthesize a current price range plus the cheapest places to buy, each with a link.
User workflow
- Scan a product.
- LifeLens fetches live listings in the background.
- View a price range and a ranked list of buy options with prices and links.
- Tap a buy link to open the listing.
Technical requirements
:core:search—AggregatingSearchClientfans out to free Google + DuckDuckGo + Bing scrapes (Google first) plus optional keyed Serper, merged and deduped.:core:data—RegionProviderlocalizes the query + currency to the user's country (coarse location); generic USD when denied.:core:network— second Qwen call synthesizesPriceInfofrom listings.:core:data—ElectronicsHandlerbuilds the query from theIdentificationand orchestrates search → synthesis.:core:model—PriceInfo,BuyOption.SEARCH_API_KEY(see docs/API-KEYS.md).
Recognize a dish and its ingredients and return calories with a protein/carbs/fat breakdown and a portion estimate.
User workflow
- Scan a plate of food.
- View the identified dish and main ingredients.
- Read calories, macros, and the estimated portion.
Technical requirements
FoodHandlerin:core:data.:core:model—NutritionInfo(calories, protein, carbs, fat, portion).:feature:results— nutrition panel.
Extract readable text from documents, labels, and signs using Qwen-VL's built-in reading ability.
User workflow
- Scan a document or sign.
- Read the transcription on the result sheet's "Transcribed text" card.
- Share it via the system share sheet.
Technical requirements
:core:network— Qwen-VL OCR via the same multimodal call; the IDENTIFY prompt transcribes visible text into theTextattribute.DocumentHandlerin:core:dataroutesScanCategory.DOCUMENT(bound@IntoSetinDataModule).:feature:results—DocumentResultBodyrenders the transcription with anACTION_SENDshare action.
Every scan is saved locally and searchable, with its image, identification, and price/nutrition data.
User workflow
- Open the History tab.
- Scroll saved scans (image thumbnail + name + timestamp).
- Type in the search box to filter.
- Tap a scan to re-open its full result.
Technical requirements
:core:database— Room entities + DAOs,Flow-based queries.:core:data—HistoryRepository.:feature:history—HistoryScreen,HistoryViewModel.- Images stored as file paths (not blobs); see TECHNICAL.md.
Manage saved scans.
User workflow
- Tap a scan in the Library to re-open its result.
- On a saved result, tap the heart to favorite / unfavorite it.
- Tap share to send the scan's summary via the system share sheet.
- Tap delete to remove the scan; the screen pops back to the Library.
Technical requirements
:core:database—setFavorite/deleteByIdDAO methods,isFavoritefield.:core:data—HistoryRepository.toggleFavorite/deletemutations.:feature:results—ResultsViewModel.toggleFavorite()/delete()(the latter emitsResultEvent.Deletedto pop back); heart/trash controls on the saved-detail sheet; AndroidACTION_SENDshare.
Enter API keys and preferences in-app; keys are stored securely and never hard-coded.
User workflow
- Open Settings.
- Paste the DashScope key and (optionally) the search key.
- Toggle preferences (e.g. enable live pricing, theme).
- Save; keys persist across launches.
Technical requirements
:core:datastore— DataStore for settings + secure key storage.:feature:settings—SettingsScreen,SettingsViewModel.- Keys also readable from
BuildConfig(see docs/API-KEYS.md).
Every screen handles the unhappy paths gracefully.
User workflow
- On slow networks, see a clear loading indicator.
- On failure, see a friendly error with a retry action.
- Offline, still browse cached history and the last result.
Technical requirements
:core:common—Resultwrapper + typed error model.- ViewModels expose sealed
UiState(Loading/Success/Empty/Error). :core:data—NetworkMonitorconnectivity check; an offline fresh scan resolves toResultsUiState.Offlinecarrying the most recent saved scan (Room), with one-tapretry().:core:designsystem— sharedLoadingIndicator, error, and empty components.
The minimum that must work end-to-end for a compelling demo:
- Scan → identify a general object (Qwen-VL happy path). (Features 1, 2)
- Product path: spec sheet + live grounded price with buy links. (Features 3, 4)
- Food path: dish + calories & macros. (Feature 5)
- Persist every scan and browse a searchable history; favorite/re-open/share/delete. (Features 7, 8)
- Results detail screen for each scan. (part of 1–5)
- Settings for API keys via DataStore. (Feature 9)
- Solid states: loading / empty / error / offline last-result fallback. (Feature 10)
- Document text extraction as a lightweight bonus within the same call. (Feature 6)
Anything below is Stretch — nice to have, built on the same architecture, pursued only after the MVP is green.
Grouped by theme. Each is intentionally additive — it reuses the existing modules and the CategoryHandler registry.
Detect and label several objects in a single photo and let the user pick which to drill into.
User workflow
- Scan a scene with multiple items.
- See tappable labels/boxes over each detected object.
- Tap one to get its full result.
Technical requirements — richer prompt returning a list in :core:network; multi-result UI in :feature:results; owns no new module.
Fast path for barcodes and QR codes for exact product lookups.
User workflow
- Point at a barcode/QR.
- LifeLens recognizes it instantly and jumps to the product/link.
Technical requirements — CameraX capture in :feature:scanner; Qwen-VL reads the code/label from the frame (staying Qwen-only), routing into ScanRepository.
Extract text and translate it inline.
User workflow
- Scan a foreign sign or menu.
- Read the original text.
- Toggle to the translated text.
Technical requirements — Qwen-VL OCR + Qwen translation in :core:network; GenericHandler extension; language preference in :core:datastore.
Watch a scanned product and get notified when the price drops.
User workflow
- On a product result, tap "Watch price".
- Set a target price.
- Receive a notification when a listing drops below it.
Technical requirements — WorkManager periodic job re-running SearchClient; new watchlist table in :core:database; notifications from :app.
Scan two items and see a side-by-side comparison.
User workflow
- Scan product A, then product B.
- Open compare view.
- Read a spec + price comparison table.
Technical requirements — compare screen in :feature:results; Qwen synthesis of a diff in :core:data.
Collect products and export the list.
User workflow
- Add products to a wishlist.
- Export as text/CSV or share.
Technical requirements — wishlist entity in :core:database; export in :feature:history.
Aggregate food scans into a daily log with calorie/macro goals.
User workflow
- Scan meals through the day.
- Open the daily log.
- See totals vs. your goal and progress rings.
Technical requirements — aggregate queries in :core:database; goals in :core:datastore; a nutrition dashboard (new lightweight screen or a :feature:history tab).
Ask natural-language questions about the scanned item ("is this good for a vegan?", "does it support Wi‑Fi 6?").
User workflow
- On a result, tap "Ask".
- Speak or type a question.
- Read Qwen's grounded answer.
Technical requirements — chat-style follow-up call in :core:network seeded with the Identification context; optional speech-to-text; conversation UI in :feature:results.
Always show the most recent result and full history when offline.
User workflow
- Lose connectivity.
- Still open history and the last scan.
Technical requirements — Room as source of truth in :core:database; cache policy in :core:data. (Shipped in the MVP: an offline fresh scan falls back to the most recent saved scan via NetworkMonitor + ResultsUiState.Offline with retry; browsing the full library offline is the remaining stretch.)
Generate a polished image card for a scan to share to social/chat.
User workflow
- Tap share on a result.
- Choose "Share as card".
- Send the rendered image.
Technical requirements — Compose-to-bitmap rendering in :core:designsystem; share intent in the feature.
Render labels over the live camera feed instead of a captured still.
Technical requirements — continuous ImageAnalysis + overlay in :feature:scanner; throttled Qwen calls in :core:data.
Organize saved scans into user-named collections.
User workflow
- Long-press scans to select.
- Add them to a collection.
- Browse by collection.
Technical requirements — collection tables in :core:database; grouping UI in :feature:history.
Full Material 3 dark theme.
Technical requirements — dynamic + dark color schemes in :core:designsystem; theme preference in :core:datastore.
Content descriptions, semantics, focus order, and ≥48dp targets throughout.
Technical requirements — semantics across all :feature:* screens and :core:designsystem components.
Five Jetpack Glance widgets bring LifeLens to the home screen. (Android removed third-party lock-screen widgets on phones in API 21, so these are home-screen App Widgets — kept compact enough to suit lock contexts on launchers/OEMs that still allow it.)
| Widget | Shows | Tap |
|---|---|---|
| Quick Scan | Amber scan button | Opens the app to the camera |
| Last Scan | Most recent scan — title + price / kcal | Opens the app |
| Library Stats | Total scans + today's count | Opens the app |
| Daily Calories | Sum of today's food-scan calories + recent meals | Opens the app |
| Price Watch | Latest priced item + price-trend delta | Opens the app |
User workflow
- Long-press the home screen → Widgets → LifeLens.
- Drop a widget (e.g. Daily Calories) onto the home screen and resize it.
- Widgets refresh periodically and reflect your latest library.
- Tap any widget to jump into the app.
Technical requirements
:feature:widget— oneGlanceAppWidget+GlanceAppWidgetReceiverper widget, anappwidget-providerXML descriptor, and manifest<receiver>s merged into:app.- Reads the library via a Hilt
@EntryPoint(WidgetEntryPoint→HistoryRepository.observeHistory()), wrapped inrunCatchingso any failure degrades to a safe empty state. - Taps open
MainActivityviaactionStartActivity(ComponentName(...))— no compile-time dependency on:app. - Previews are standard Compose
@Previewapproximations (a Glance composable can't render on the ordinary Compose preview host).
| Feature | Primary module(s) |
|---|---|
| Point-and-scan identification | :feature:scanner, :core:network, :core:data |
| Category routing + handlers | :core:data (CategoryHandler registry) |
| Product spec sheet | ElectronicsHandler (:core:data), :feature:results |
| Live price grounding | :core:search, :core:network, :core:data |
| Food & nutrition | FoodHandler (:core:data), :feature:results |
| Document / OCR | :core:network, DocumentHandler (:core:data), :feature:results |
| Scan history + manage | :core:database, :core:data, :feature:history |
| Settings & API keys | :core:datastore, :feature:settings |
| Robust UI states | :core:common, :core:designsystem, all features |
| Home-screen widgets | :feature:widget (Glance) |