Проблема
Мне нужен был простой инструмент: список задач, учёт расходов и таймер для фокусировки. Казалось бы — чего проще?
Но вот реальность:
Todoist — бесплатно только 5 проектов, дальше ₽359/мес
TickTick — помодоро и календарь только в Premium за ₽249/мес
Money Manager — реклама на каждом экране, ₽199 за отключение
Forest — ₽299 за приложение
Итого: чтобы покрыть задачи + бюджет + таймер, нужно либо 3-4 приложения, либо платить ~₽500-800/мес.
Мне показалось это абсурдным. И я решил сделать своё.
Решение: Todo Budget
Одно приложение, в котором есть:
Планировщик задач — приоритеты, подзадачи, повторяющиеся задачи, свайп-жесты, напоминания, поиск
Учёт финансов — расходы/доходы по категориям, лимиты, долги, графики, виджет баланса
Помодоро-таймер — настраиваемые интервалы, статистика
Заметки — текст + голосовой ввод
Полностью бесплатно. Без подписок. Без in-app покупок. Без premium-тира.
Технологии
Компонент | Технология |
|---|---|
Язык | Kotlin |
UI | Jetpack Compose + Material 3 |
БД | Room (SQLite) |
Настройки | DataStore Preferences |
Min SDK | 21 (Android 5.0) |
Target SDK | 35 (Android 15) |
Размер APK | 9 МБ (R8-оптимизация) |
Почему Jetpack Compose?
Для соло-разработчика Compose — спасение. Вместо XML-layout + adapter + ViewHolder можно написать:
LazyColumn { items(tasks) { task -> TaskCard( task = task, onSwipeComplete = { viewModel.completeTask(it) }, onSwipeDelete = { viewModel.deleteTask(it) } ) } }
Это и список, и свайпы, и анимации. В XML это было бы 3 файла и 200 строк.
R8 и уменьшение APK
Исходный APK весил 18 МБ. После настройки R8:
buildTypes { release { minifyEnabled true shrinkResources true proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro' } }
APK уменьшился до 9 МБ — ровно в 2 раза.
Room и локальное хранение
Все данные хранятся локально. Ничего не уходит на серверы. База данных зашифрована.
@Database( entities = [Task::class, Expense::class, Income::class, Note::class, Debt::class, BudgetLimit::class, FinancialSnapshot::class, PomodoroSession::class], version = ... ) abstract class AppDatabase : RoomDatabase() { abstract fun taskDao(): TaskDao abstract fun expenseDao(): ExpenseDao // ... }
8 сущностей, 8 DAO, все связи через Flow для реактивного UI.
Архитектура
app/src/main/java/ru/todobudget/todo/ ├── MainActivity.kt # Главный хаб ├── TodoActivity.kt # Задачи ├── BudgetActivity.kt # Бюджет ├── ProductivityToolsActivity.kt # Помодоро ├── NotesActivity.kt # Заметки ├── SettingsActivity.kt # Настройки ├── AppDatabase.kt # Room БД ├── TodoBudgetWidget.kt # Виджет └── ui/theme/ # Тема
Каждый экран — отдельная Activity с Compose-контентом. Да, я знаю про single-activity с Navigation Compose, но для приложения такого масштаба это было бы оверинжиниринг.
Проблемы, с которыми столкнулся
1. Утечки памяти в виджете
AppWidgetProvider удерживал ссылку на Context, что вызывало утечки. Решение — слабые ссылки и корректная очистка в onDisabled().
2. Точные будил��ники на Android 12+
Начиная с API 31, SCHEDULE_EXACT_ALARM требует явного разрешения. Пришлось добавить fallback на setAndAllowWhileIdle() для устройств без этого разрешения.
3. Помодоро-таймер в фоне
Service + Foreground Notification, чтобы система не убивала таймер. На Xiaomi/MIUI пришлось добавить инструкцию для пользователя по отключению автоочистки.
Монетизация
Баннерная реклама Яндекс (Yandex Ads) — ненавязчивый баннер внизу экрана. Никаких полноэкранных вставок. Никаких rewarded видео.
Приложение остаётся полностью функциональным без какой-либо оплаты. Реклама — единственный источник дохода.
Результат
9 МБ APK
4 инструмента в одном
Работает оффлайн
Все данные локально
Бесплатно навсегда
Уже в RuStore
Ссылки
Буду рад вопросам и обратной связи. Если есть идеи, что добавить — пишите в комментариях.
