Skip to content

Repository files navigation

SolidVerdant

GitHub Downloads (specific asset, latest release) Static Badge Add to Obtainium

Modern Android time tracking client for Solidtime

A native Kotlin/Jetpack Compose Android application that connects to Solidtime for secure, OAuth2-based time tracking on mobile devices.


Features

Time tracking

  • Start/stop time entries with a live elapsed timer
  • Pause and resume active timers
  • Select projects and tasks from searchable dropdowns
  • Add descriptions, tags, and billable status
  • Continue the most recent completed entry
  • Edit or delete past time entries
  • View history grouped by date, with identical entries collapsed into expandable groups
  • Pull-to-refresh to sync with the server
  • Switch between all organizations available to your Solidtime account

Android integration

  • Quick Settings tile - Start/stop tracking without opening the app, with project and task selection
  • Persistent notification - Shows elapsed time with pause and stop controls
  • Notification quick start - Start a timer with project, task, and description selection directly from the idle notification
  • Home-screen widget - View tracking state and access quick controls
  • Boot persistence - Restores notification state after reboot

Auth and configuration

  • OAuth2 with PKCE (no API keys needed)
  • Automatic token refresh
  • Custom server endpoints and OAuth client IDs
  • Server details available in the settings drawer with tap-to-copy
  • Encrypted token storage

UI

  • Material 3 with Material You dynamic colors (Android 12+)
  • Dark and light themes follow system settings
  • Edge-to-edge display with predictive back gesture support (Android 13+)
  • Available in English, Dutch, and Japanese + any language you want if you create a pull request

Quirks

  • The Quick Settings tile state won't sync with changes made on the web or desktop unless the app is open. Not a problem if you only use the tile and app.

Screenshots

The shots below are generated on the JVM (no device) by the Roborazzi + Robolectric suite — see Testing. Run ./gradlew :app:recordRoborazziDebug to regenerate them.

Track screen with a running timer and history
Track
Running timer & history
History list grouped by day
History
Entries grouped by day
Calendar month view
Calendar — Month
Month overview
Calendar week view with overlay events
Calendar — Week
Week with calendar overlay
Statistics with KPIs and charts
Statistics
KPIs, filters & charts
Time Inbox review issue cards
Time Inbox
Review issue cards
End-of-day guided review
End-of-day Review
Guided cleanup
Edit time entry sheet
Edit Entry
Create / edit sheet
Templates and favorites
Templates
Favorites & quick starts

Rendered in the Neo dark theme.

The Live activity shots below were captured on a connected Android 16 device.

SolidVerdant Android Live Update showing Working in the status bar
Live activity
Promoted ongoing notification while tracking

SolidVerdant Android Live Update in its compact status bar form
Compact live activity
Collapsed status bar presentation

Tech Stack

Core Technologies

  • Language: Kotlin
  • UI Framework: Jetpack Compose with Material 3
  • Architecture: MVVM with Clean Architecture
  • Dependency Injection: Hilt
  • Networking: Retrofit + OkHttp
  • Serialization: Kotlinx Serialization
  • Async: Kotlin Coroutines + Flow
  • Storage: DataStore Preferences with Android Keystore-backed AES-GCM encryption for OAuth secrets

Key Libraries

  • Jetpack Compose - Declarative UI framework
  • Hilt - Dependency injection
  • Retrofit - Type-safe HTTP client
  • OkHttp - HTTP interceptors and authentication
  • Kotlinx Serialization - JSON serialization
  • DataStore + Android Keystore - Tokens and transient PKCE values are encrypted with AES-GCM; non-secret app settings remain ordinary preferences
  • Custom Tabs - Secure OAuth browser flow
  • Timber - Logging

Configuration

By default, SolidVerdant connects to the official Solidtime instance at https://app.solidtime.io. To configure a custom server:

  1. Launch the app
  2. On the login screen, tap the settings icon (⚙️) in the top bar
  3. Enter your custom server endpoint and OAuth client ID
  4. Tap "Save"

Default Configuration:

  • Server Endpoint: https://app.solidtime.io
  • Client ID: 9c994748-c593-4a6d-951b-6849c829bc4e

Selfhosted

run docker exec solidtime-scheduler php artisan passport:client --name=desktop --redirect_uri=solidtime://oauth/callback --public -n

Usage

Goal of this application is to have a easy to use tile to start and stop tracking, this application does everything i need it to but pullrequests for other features are welcome, forking is fine too

  1. Login: Tap "Login with OAuth2" to authenticate via your Solidtime account
  2. View Tracking: See your current time entry with live elapsed time
  3. Switch Organization: Tap the organization name in the header while no timer is active
  4. Refresh: Pull to refresh or tap the refresh button to update tracking state
  5. Logout: Open the navigation drawer and tap logout to clear all data and return to login screen

Building for Production

Debug Build

./gradlew assembleDebug

Build Variants

  • Debug (app-debug.apk) - Includes logging, no minification, package suffix .dev
  • Release (app-release.apk) - ProGuard enabled, resources shrunk, signed for distribution

Testing

Run unit tests:

./gradlew test

Run instrumentation tests:

./gradlew connectedAndroidTest

Generate the README screenshots (pure JVM, no device/emulator — Roborazzi + Robolectric):

./gradlew :app:recordRoborazziDebug

This renders every screen across a light/dark × phone/tablet matrix into .github/screenshots/generated/ and writes the Neo-dark phone hero set to .github/screenshots/readme/.

Device and live Solidtime tests

Use the pinned development environment for Android verification:

devenv tasks run android:gate
devenv tasks run android:gate:instrumentation
devenv tasks run android:e2e:mock

The host gate is device-free. The instrumentation gate mirrors the CI connectedCheck and requires an already-connected emulator or Android device. The mock E2E task builds and installs the debug APKs and runs the device suite against a deterministic local backend. Live-portable tests can be run against an isolated local Solidtime server:

devenv up -d
devenv tasks run solidtime:test

The live task starts the official Solidtime container with disposable PostgreSQL data, resets its test account, and runs only E2E tests marked @BackendPortable. It requires one authorized physical Android device; emulator serials are rejected. Set ANDROID_SERIAL if more than one physical device is connected. The task uses adb reverse and removes the temporary test session from the device afterward. Do not use a personal Solidtime account or print the generated session file.

The reset removes all time entries from the disposable account and seeds Live Test Project, Live Test Task, and Live Test Tag for metadata-edit tests. It is also available explicitly with devenv tasks run solidtime:reset. devenv tasks run android:e2e is the mock-suite alias, and devenv tasks run android:e2e:real is the live-suite alias. The default container image is the stable solidtime/solidtime:latest; set SOLIDTIME_IMAGE_TAG=main only for an intentional upstream development compatibility run. The local API uses Solidtime's testing environment so the production per-user request throttle does not turn a rapid isolated suite into a false failure.

If a restricted development environment reports read-only Podman state under /run/user or cannot open the Gradle distribution lock, rerun the same pinned devenv task with the approved elevated container/build permission. These errors are environment restrictions, not Solidtime test results. Read the JUnit instrumentation summary to determine pass/fail; do not rely on a task wrapper's shell exit code when it suppresses the instrumentation transcript.

Verification

You can verify the authenticity of SolidVerdant APKs using the signing certificate hash below. This works with AppVerifier or Obtainium's built-in verification.

Field Value
Package ID dev.tricked.solidverdant
SHA-256 Signing Certificate 7A:38:2F:E9:14:1B:D3:DC:A4:C4:82:20:7F:FF:12:5A:82:8D:66:92:C4:0E:5A:BC:30:61:6C:33:15:C7:F3:64

You can also view this information in-app via Settings > About > Verification Info.

Links

Acknowledgments


Made with ❤️ (and almost entirely Codex) for the Solidtime community

About

ANDROID SOLIDTIME APP - Easily manage your solidtime time tracking using a android tile

Topics

Resources

Stars

11 stars

Watchers

0 watching

Forks

Releases

Contributors

Languages