Skip to content

About

Native Android utility app for DESCO prepaid electricity users featuring real-time balance tracking, Room DB caching, WorkManager background alerts, MPAndroidChart, and PDF report generation.

Topics

Resources

Stars

1 star

Watchers

0 watching

Forks

Repository files navigation

DESCO Smart

DESCO Smart is a powerful and lightweight Android application designed to help DESCO prepaid electricity users monitor their consumption with ease. It provides real-time balance updates, detailed recharge history, and smart low-balance notifications to ensure you never run out of electricity unexpectedly.

Developed by Utsho with a focus on simplicity and utility.

Important

Disclaimer: This repository is an independent application project and is not an official DESCO application. It depends on public DESCO web API endpoints, which may change without notice.

📥 Download

You can download the latest version of the app directly from the link below:

Caution

Important for Notifications: To get low-balance alerts correctly, you must set the App Battery to "Unrestricted", "Don't Optimize" or "No Restrictions" and enable "Auto-start" in your phone settings. Otherwise, Android may stop the background check.

Note: After downloading, you may need to allow "Install from Unknown Sources" in your Android settings to install the APK.

✨ Features

  • Connect a prepaid meter using either an account number or meter number.
  • Save and manage multiple meters locally.
  • Switch the active meter from the main screen.
  • View customer information such as name, account number, meter number, phone, address, feeder, and phase.
  • View the current prepaid balance and current-month spending.
  • Estimate the full-month cost from the amount used so far.
  • Show a suggested recharge amount when the projected monthly cost exceeds the remaining balance.
  • Display a 12-month usage chart and toggle between kWh and BDT.
  • View approximately one year of recharge history, including amount, date, payment mode, transaction/order ID, and energy amount.
  • Calculate recharge totals for the current month and current year when the full history response is available.
  • Configure a separate low-balance threshold for each saved meter.
  • Run background balance checks and send a notification when a meter newly enters the low-balance state.
  • Resume background scheduling after device reboot or app replacement.
  • Generate a multi-page PDF recharge report and save it under Downloads/DescoReports.

Application Flow

SplashActivity
   |
   +-- no saved/active meter --> LoginActivity --> verify meter --> MainActivity
   |
   +-- active meter exists -------------------------------> MainActivity

MainActivity
   |
   +-- DashboardFragment  -> customer, balance, estimate, 12-month chart
   +-- HistoryFragment    -> recharge history and totals
   +-- ReportsFragment    -> PDF report generation
   +-- SettingsFragment   -> rename/delete meters, alert limits, scheduling
   |
   +-- Switch Meter dialog / AddMeterActivity

Tech Stack

Area Technology
Language Java 11
UI Android Views, Material Components, View Binding
Local database Room 2.6.1
Networking Retrofit 2.9.0 + OkHttp 4.12.0 + Gson
Background work WorkManager 2.9.0
Charts MPAndroidChart 3.1.0
PDF Android PdfDocument
Minimum Android API 24
Target / Compile SDK API 35
Build system Gradle 8.13 / Android Gradle Plugin 8.12.3

Project Structure

app/src/main/
├── AndroidManifest.xml
├── java/com/example/descosmartapp/
│   ├── api/
│   │   ├── ApiClient.java          # Retrofit/OkHttp creation and caching
│   │   └── DescoApi.java           # DESCO Retrofit endpoint definitions
│   ├── db/
│   │   ├── AppDatabase.java        # Room database singleton
│   │   ├── DbExecutor.java         # Single-thread DB execution helper
│   │   ├── MeterDao.java           # Meter persistence operations
│   │   └── MeterProfile.java       # Room entity
│   ├── model/
│   │   ├── BalanceResponse.java
│   │   ├── CustomerResponse.java
│   │   ├── MonthlyResponse.java
│   │   └── RechargeResponse.java
│   ├── service/
│   │   ├── DescoService.java       # API facade, fallback logic, alerts
│   │   └── MeterRegistration.java  # Meter lookup and save workflow
│   ├── ui/
│   │   ├── SplashActivity.java
│   │   ├── LoginActivity.java
│   │   ├── MainActivity.java
│   │   ├── AddMeterActivity.java
│   │   ├── adapters/
│   │   │   ├── MeterManageAdapter.java
│   │   │   └── RechargeAdapter.java
│   │   └── fragments/
│   │       ├── DashboardFragment.java
│   │       ├── HistoryFragment.java
│   │       ├── ReportsFragment.java
│   │       └── SettingsFragment.java
│   ├── utils/
│   │   ├── Constants.java
│   │   ├── DateRanges.java
│   │   ├── ReportPdfGenerator.java
│   │   └── UiInsets.java
│   └── worker/
│       ├── BalanceCheckWorker.java
│       ├── BootReceiver.java
│       ├── ScheduleCalculator.java
│       └── WorkScheduler.java
└── res/
    ├── layout/                     # Activities, fragments and list rows
    ├── drawable/                   # App UI backgrounds and icons
    ├── menu/                       # Bottom navigation menu
    └── values/                     # Colors, strings and themes

Design Patterns Used

The project intentionally demonstrates several common software design patterns.

Pattern Main location Implementation Why it is used
Singleton db/AppDatabase.java instance + getInstance() Keeps one Room database instance for the entire application.
Singleton service/DescoService.java Holder + getInstance() Keeps one shared service object for DESCO API operations.
DAO db/MeterDao.java MeterDao interface Separates Room/SQL operations from UI and service code.
Facade service/DescoService.java Public fetch...() methods Hides Retrofit calls, primary/fallback APIs, validation, merging, and notification helpers behind a simpler interface.
Adapter ui/adapters/RechargeAdapter.java RecyclerView adapter Converts recharge model objects into RecyclerView rows.
Adapter ui/adapters/MeterManageAdapter.java RecyclerView adapter Converts saved meter models into interactive meter-management rows.
Strategy service/DescoService.java DataCheck<T> + withFallback() Lets each API operation provide its own “valid response” rule while reusing the same fallback algorithm.
Builder api/ApiClient.java Retrofit.Builder, OkHttpClient.Builder Builds configured networking objects step by step.
Builder worker/WorkScheduler.java Constraints.Builder, OneTimeWorkRequest.Builder Builds configured WorkManager jobs step by step.
Template Method ui/MainActivity.java overridden onCreate() Android owns the Activity lifecycle and calls the subclass hook.
Template Method ui/adapters/RechargeAdapter.java overridden adapter methods RecyclerView defines the rendering lifecycle and calls the adapter hooks.
Template Method worker/BalanceCheckWorker.java overridden doWork() WorkManager controls execution and calls the task-specific work hook.

One-line viva answers

  • Singleton: One shared object is returned throughout the application.
  • DAO: Database operations are isolated behind a dedicated interface.
  • Facade: A simple service interface hides several complex subsystems.
  • Adapter: Converts one data/interface form into the form required by another component.
  • Strategy: Interchangeable validation rules are passed into one common algorithm.
  • Builder: A complex object is configured step by step and created with build().
  • Template Method: A framework defines the overall algorithm/lifecycle and a subclass overrides selected hook methods.

Networking and DESCO API

Two base URLs are configured in utils/Constants.java:

Primary:  https://prepaid.desco.org.bd/api/unified/customer/
Fallback: https://prepaid.desco.org.bd/api/tkdes/customer/

DescoService first tries the primary API. If the request fails or does not contain usable data, it executes the equivalent call against the fallback API.

Endpoints used

Operation Endpoint Main parameters
Customer by account getCustomerInfo accountNo
Customer by meter getCustomerInfo meterNo
Balance getBalance accountNo
Monthly consumption getCustomerMonthlyConsumption accountNo, monthFrom, monthTo
Recharge history getRechargeHistory accountNo, dateFrom, dateTo
Recharge history by meter getRechargeHistory meterNo, dateFrom, dateTo

The model classes include Gson alternate field names where the upstream API may return different JSON property names.

Recharge-history range

The app requests roughly the previous 12 months in two date ranges and merges the results. Splitting the request helps work with the upstream recharge-history service while still presenting one combined list.

Local Database

Room stores saved meter profiles in a database named:

desco_db

The meters table contains:

Field Purpose
id Auto-generated primary key
label User-friendly name such as Home or Office
accountNo DESCO account number
meterNo DESCO meter number
lowBalanceThreshold Alert threshold in BDT
isActive Whether this is the currently selected meter
createdAt Local creation timestamp
meterState Retained only for Room v1 schema compatibility

MeterDao.activateMeter() deactivates all meters before selecting one, so the app normally keeps a single active meter.

Background Low-Balance Alerts

WorkScheduler schedules a one-time WorkManager request for the next configured check and BalanceCheckWorker schedules the following check when its work completes.

Configured check times are:

07:00
10:00
13:00
17:00
21:00

The worker requires an active network connection. For each saved meter it:

  1. Fetches the latest balance.
  2. Compares the balance with that meter's configured threshold.
  3. Sends a high-priority notification when the meter newly becomes low.
  4. Stores a small SharedPreferences flag so the same low state is not repeatedly notified.
  5. Clears that flag after the balance rises above the threshold, allowing a future low-balance transition to notify again.

BootReceiver restores scheduling after boot, package replacement, or supported quick-boot broadcasts when saved meters exist.

WorkManager execution is OS-managed, so these times should be treated as desired check points rather than alarm-clock-level exact execution times.

⚠️ Notification Troubleshooting

If you are not receiving background low-balance notifications, please check the following settings on your Android device (especially for Xiaomi, Samsung, Oppo, and Vivo):

  1. Battery Optimization: Go to App Info > Battery and set it to "Unrestricted" or "Don't Optimize".
  2. Auto-start: If your phone has an "Auto-start" setting, make sure it is enabled for DESCO Smart.
  3. Notification Permissions: Ensure that notifications are allowed in App Info > Notifications.

These settings prevent the Android system from killing the app's background processes, ensuring you get alerts on time.

Dashboard Calculations

The estimated full-month cost is a simple linear projection:

estimated month cost = (cost used so far / elapsed days) × days in current month

If the projected remaining requirement is greater than the current balance, the suggested recharge is rounded upward to the next BDT 100.

This is an estimate only; it does not model tariff slabs, future behavior changes, emergency balance rules, or other billing adjustments.

PDF Reports

The Reports screen creates a landscape recharge-history PDF containing:

  • DESCO-style heading and report title
  • Account and meter information
  • User-defined meter name
  • Current balance and configured alert limit
  • Customer name, address, and S&D information when available
  • Report period
  • Recharge rows with order number, meter number, date, total amount, and energy amount
  • Generated date and page numbering

Save location

  • Android 10+ (API 29+): saved with MediaStore under Downloads/DescoReports.
  • Android 9 and lower: saved directly to the public Downloads directory and requires legacy write-storage permission.

Example filename:

DESCO_Home_Recharge_Report_20260809_011500.pdf

Permissions

The manifest requests:

Permission Reason
INTERNET DESCO API requests
POST_NOTIFICATIONS Low-balance notifications on Android 13+
RECEIVE_BOOT_COMPLETED Restore background balance scheduling after reboot
WRITE_EXTERNAL_STORAGE (max API 28) Save reports on legacy Android versions

The application disables cleartext HTTP traffic and does not enable Android backup.

Getting Started

Requirements

  • Android Studio with support for Android Gradle Plugin 8.12.x
  • JDK 17 for the Android Gradle Plugin/Gradle build runtime (the app source/target compatibility is Java 11)
  • Android SDK Platform 35
  • An Android device/emulator running API 24 or newer
  • Internet access for Gradle dependencies and live DESCO data

Open in Android Studio

  1. Clone or download the repository.
  2. Open the DescoSmartApp project folder in Android Studio.
  3. Allow Gradle to sync and download dependencies.
  4. Make sure Android SDK 36 is installed.
  5. Run the app configuration on an emulator or physical device.

Command-line build

macOS/Linux:

./gradlew assembleDebug

Windows:

gradlew.bat assembleDebug

The debug APK is normally created under:

app/build/outputs/apk/debug/

Usage

  1. Launch the app.
  2. Enter a DESCO account number or meter number.
  3. Optionally give the meter a friendly name.
  4. Tap Verify & Add Meter.
  5. Use the bottom navigation for Dashboard, History, Reports, and Settings.
  6. Add extra meters from the switch-meter dialog or Settings.
  7. Set the desired low-balance limit for each meter in Settings.
  8. Grant notification permission on Android 13+ if you want background alerts.

Security Note

ApiClient contains a TLS compatibility configuration that currently allows all certificates and hostnames. This is intentionally used to ensure reliable data fetching from DESCO utility servers, which may use certificates not recognized by default Android system trust managers.

This behavior is necessary for consistent operation with existing DESCO endpoints but it disables standard certificate validation. This should be reviewed if the app is intended for production-grade security handling sensitive user credentials. Prefer fixing server-side certificate chains or using specific certificate pinning where possible.

Privacy and Data Handling

  • Saved meter profiles and alert thresholds are stored locally in Room.
  • Low-balance notification state is stored locally in SharedPreferences.
  • Meter/account identifiers are sent to the configured DESCO API endpoints when data is requested.
  • Generated reports are written to the device Downloads area.
  • The project does not contain an account-password login flow or its own remote user database.

Current Tests

The repository currently includes only the default sample tests:

  • Local JUnit test checking 2 + 2 = 4.
  • Instrumented test checking the application package name.

For stronger coverage, useful next tests would include:

  • ScheduleCalculator.nextDelay() around exact check times and midnight.
  • DateRanges month/year boundaries.
  • DescoService.stateLabel() and showAlert() threshold behavior.
  • MeterDao active-meter transaction rules.
  • Response parsing for alternate DESCO JSON field names.
  • Monthly estimate and recharge-total calculations.

Known Limitations

  • Live features depend on the availability and response format of external DESCO endpoints.
  • There is no offline cache for live customer, balance, consumption, or recharge responses.
  • The monthly bill estimate uses linear projection rather than a full electricity tariff calculation.
  • Background work can be delayed by Android battery optimization, Doze, OEM policies, or lack of connectivity.
  • Recharge history totals are intentionally hidden when only a partial yearly history request succeeds.
  • The current test suite is minimal.
  • The project has no license file, so reuse/distribution terms are not explicitly granted by this repository.

Key Classes at a Glance

Class Responsibility
ApiClient Builds and caches Retrofit clients and shared OkHttp configuration.
DescoApi Declares HTTP endpoints.
DescoService Central API facade, fallback handling, UI mapping, balance state helpers, notifications.
MeterRegistration Looks up input as account/meter number and persists the verified meter.
AppDatabase / MeterDao Stores and manages local meter profiles.
DashboardFragment Shows live meter/customer data, estimates, and monthly chart.
HistoryFragment Displays recharge records and totals.
ReportsFragment Coordinates data collection and PDF generation.
ReportPdfGenerator Draws and saves the multi-page recharge report.
MeterManageAdapter Renames, deletes, and updates thresholds for saved meters.
WorkScheduler Schedules the next background balance check.
BalanceCheckWorker Fetches balances and triggers low-balance notifications.
BootReceiver Restores background scheduling after reboot/update.

App name: DESCO Smart
Application ID: com.example.descosmartapp
Version: 1.0 (versionCode 1)

About

Native Android utility app for DESCO prepaid electricity users featuring real-time balance tracking, Room DB caching, WorkManager background alerts, MPAndroidChart, and PDF report generation.

Topics

Resources

Stars

1 star

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages