Skip to content

Repository files navigation

FlowerApp

AI-Powered Flower Identification Android Application

FlowerApp application logo

FlowerApp is an Android computer-vision application that classifies 102 flower categories with a TensorFlow Lite model running entirely on the device. This repository demonstrates the mobile machine-learning integration through Kotlin, Jetpack Compose, Android system image APIs, and lifecycle-aware state management.

Kotlin Android TensorFlow Lite License: MIT

Repository scope

FlowerApp is a published Android application available on Google Play. To protect the production application's proprietary user interface and product design, the complete production UI source is not included in this repository.

This public repository provides:

  • core Android application logic;
  • TensorFlow Lite model integration;
  • image preprocessing and on-device inference;
  • camera handling;
  • Photo Picker and gallery handling;
  • scoped FileProvider integration;
  • ViewModel and StateFlow state management;
  • model-contract validation tests;
  • a simplified Jetpack Compose demonstration UI.

The public demo UI is intentionally different from the production UI. The screenshots below are from the published production application, and this repository does not contain the complete source code or every feature of that application.

Production application screenshots

These images show the published production application. Its visual design, animations, media, navigation, and complete UI implementation are intentionally excluded from this public repository.

FlowerApp production welcome screen FlowerApp production home screen FlowerApp production corn poppy prediction

FlowerApp production tiger lily prediction FlowerApp production rose prediction FlowerApp production sunflower prediction

Key features

Capability Implementation
Flower recognition 102-class MobileNetV2 TensorFlow Lite model
Inference Fully on-device; selected images are not uploaded
Gallery input Android system Photo Picker
Camera input Activity Result API with a scoped, non-exported FileProvider
Image safety Bounded decoding, MIME checks, and EXIF orientation handling
UI state Lifecycle-aware StateFlow exposed by a ViewModel
Model safety Runtime tensor shape, type, and label-count validation
Results Top prediction, confidence, and inference-only latency
Privacy No Internet, storage, analytics, advertising, or tracking dependency

Application workflow

Photo Picker ─┐
              ├─> Safe bitmap decode ─> EXIF correction ─> 224 × 224 RGB
Camera ───────┘                                              │
                                                             v
                                              Float32 normalization (1/255)
                                                             │
                                                             v
                                              TensorFlow Lite inference
                                                             │
                                                             v
                                         Top-one label, confidence, latency
  1. Select a flower image through the system Photo Picker or capture one with the camera.
  2. Decode the image at a bounded size and apply its orientation metadata.
  3. Resize the bitmap to 224 × 224 pixels and convert RGB channels to FLOAT32 values in the range [0, 1].
  4. Run the bundled TensorFlow Lite model locally.
  5. Select the highest output score and display its flower label, confidence, and model-inference time.
  6. Delete managed temporary camera files after processing or cancellation.

Architecture

MainActivity
└── FlowerDemoScreen (Jetpack Compose)
    ├── Photo Picker / Camera launchers
    └── FlowerViewModel
        ├── FlowerUiState (StateFlow)
        ├── TemporaryCameraFileManager
        └── FlowerImageProcessor
            ├── SafeBitmapDecoder
            ├── ImagePreprocessor
            └── TensorFlowFlowerClassifier
                └── TensorFlow Lite Interpreter

The UI observes immutable state for model checking, idle, loading, success, and error conditions. Decode and inference work run away from the main thread. Interpreter access is serialized, the classifier is reused between predictions, and resources are closed with the ViewModel lifecycle.

TensorFlow Lite integration

The bundled classifier validates its model contract before accepting predictions. It requires one input tensor, one output tensor, matching FLOAT32 types, the expected shapes, and one label per output class.

Model property Contract
Architecture MobileNetV2
Input 1 × 224 × 224 × 3
Input type FLOAT32
Channel order RGB
Normalization channel value ÷ 255.0
Output 1 × 102
Output type FLOAT32
Output activation Softmax
Selection Top-one argmax
Labels 102 non-empty entries

The related Flower Classification project documents dataset preparation, model evaluation, and TensorFlow Lite conversion. This Android repository focuses on safe mobile integration and does not redistribute the Oxford 102 Flowers dataset.

Image input and preprocessing

SafeBitmapDecoder limits the largest decoded dimension to 1024 pixels before the model-specific resize. Android 9 and newer use ImageDecoder; Android 8 uses sampled BitmapFactory decoding. The Android 8 path reads EXIF orientation and applies the required rotation or reflection.

ImagePreprocessor then:

  1. scales the bitmap to 224 × 224;
  2. extracts pixels in RGB order;
  3. writes each channel to a native-order direct ByteBuffer;
  4. divides channel values by 255.0;
  5. rewinds the buffer before interpreter invocation.

Camera, gallery, and FileProvider

  • Gallery selection uses ActivityResultContracts.PickVisualMedia with image-only input.
  • Camera capture uses ActivityResultContracts.TakePicture.
  • Captured images are written to cacheDir/camera_images/.
  • A non-exported FileProvider exposes only that managed cache path.
  • Temporary images are deleted after processing, cancellation, reset, or stale-file cleanup.
  • Camera hardware is optional, and camera permission is requested only when capture is selected.

Privacy and permissions

Inference runs locally. The public application logic contains no network client and requests no Internet or broad storage permission. It includes no analytics, advertising, tracking, Firebase, or remote service integration.

Declared permission:

<uses-permission android:name="android.permission.CAMERA" />

Gallery access is provided by the system Photo Picker. Application backup and device-transfer extraction are disabled for application data.

See the public Privacy Policy for a complete description of image handling, permissions, and data practices.

Project structure

.
├── app/
│   ├── build.gradle.kts
│   ├── proguard-rules.pro
│   └── src/
│       ├── main/
│       │   ├── AndroidManifest.xml
│       │   ├── assets/                  # TFLite model and 102 labels
│       │   ├── java/.../flowerapp/
│       │   │   ├── classifier/          # Model contract and preprocessing
│       │   │   ├── data/                # Decode/inference coordination
│       │   │   ├── ui/                  # Simplified Compose demo
│       │   │   ├── utils/               # Safe decoding and camera files
│       │   │   ├── viewmodel/           # Lifecycle-aware state
│       │   │   └── MainActivity.kt
│       │   └── res/                      # Manifest resources and XML policies
│       └── test/                         # Local unit and model-contract tests
├── docs/images/
│   ├── branding/
│   └── google-play/                      # Production application screenshots
├── gradle/                               # Version catalog and wrapper
├── README.md
├── LICENSE
└── THIRD_PARTY_NOTICES.md

Requirements

  • Android Studio with support for Android Gradle Plugin 8.11.1
  • JDK 17 or newer for Gradle
  • Android SDK 36
  • Android 8.0 (API 26) or newer device/emulator
  • Included Gradle wrapper

Setup

git clone https://github.com/fatemehsabourinia/FlowerApp.git
cd FlowerApp

Open the repository root in Android Studio, allow Gradle sync to complete, select the app run configuration, and run it on an Android 8.0 or newer device or emulator.

Build and validation

Build a debug APK:

./gradlew --no-daemon :app:assembleDebug

Run the local validation sequence:

./gradlew --no-daemon :app:testDebugUnitTest
./gradlew --no-daemon :app:lintDebug
./gradlew --no-daemon :app:assembleDebug

The test suite covers model tensor contracts, label alignment, preprocessing bounds, prediction selection, startup privacy constraints, temporary camera-file management, and ViewModel state transitions. Device-level camera and Photo Picker flows should additionally be verified on representative Android versions.

Validation reproduced on 18 July 2026:

  • 16 local unit tests passed with 0 failures and 0 skipped tests.
  • Android lint completed with 0 errors and 17 warnings.
  • Debug APK assembly completed successfully.
  • Instrumentation tests were not run.

The lint warnings are dependency/version advisories and upstream TensorFlow Lite native-library 16 KB alignment notices; no lint error is suppressed by a baseline.

Google Play

The Google Play listing identifies the application as FlowerApp and the developer as Alireza Zaeri & Fatemeh Sabourinia. Availability may vary by country, account, or Google Play access conditions.

The production package ID is com.zaeri.sabourinia.flowerapp, which is also retained as this repository's Android application ID. The app display name remains Flower Identifier, while FlowerApp is the canonical repository name.

Limitations

  • The public Compose interface is a simplified engineering demonstration, not the production interface.
  • The repository does not include every production application feature or production UI resource.
  • Classification is limited to the 102 flower categories represented by the model.
  • The classifier does not implement calibrated uncertainty or non-flower rejection.
  • Predictions can be incorrect and must not be treated as scientific identification.
  • Inference time varies by device, Android version, thermal state, and current system load.
  • Automated device/instrumentation coverage is not included.

Future improvements

  • Add automated device tests for camera, Photo Picker, and process recreation flows.
  • Add adaptive launcher icon resources for modern Android launchers.
  • Expand accessibility and localization coverage in the demonstration UI.
  • Evaluate quantized model variants and delegate performance across representative devices.
  • Add continuous integration for unit tests, lint, and debug assembly.

Contributors

This project was developed by Fatemeh Sabourinia and Alireza Zaeri.

Licence

Original source code in this repository is available under the MIT License. The existing licence retains both project developers as copyright holders.

Dependencies, pretrained components, datasets, the TensorFlow Lite model, production screenshots, and branding may remain subject to separate upstream terms. See THIRD_PARTY_NOTICES.md for details.

Releases

Packages

Contributors

Languages