AGENTS.md - BTC Map Android Development Guide
Language : Kotlin
Build System : Gradle with Kotlin DSL
Min SDK : 29 (Android 10)
Target SDK : 36
Architecture : Android Views with ViewBinding, SQLite database, Coroutines for async
Full Build & Verification
./gradlew check # Run all verification (lint + tests)
./gradlew assembleDebug # Build debug APK
./gradlew assembleRelease # Build release APK
./gradlew bundleData # Download latest places data snapshot
# Run all unit tests
./gradlew testDebugUnitTest
# Run all instrumented tests (requires emulator/device)
./gradlew connectedDebugAndroidTest
# Run a single instrumented test class
./gradlew connectedDebugAndroidTest --tests " ExampleInstrumentedTest"
# Run a single test method
./gradlew connectedDebugAndroidTest --tests " ExampleInstrumentedTest.useAppContext"
./gradlew lint # Run lint analysis
./gradlew lintDebug # Run lint on debug build
./gradlew lintRelease # Run lint on release build
Classes : PascalCase (e.g., MapFragment, PlaceQueries, SearchAdapter)
Functions : camelCase (e.g., initSearchBar, selectPlace, setFilter)
Variables/Properties : camelCase (e.g., binding, httpClient, bottomSheetBehavior)
Constants : UPPER_SNAKE_CASE inside companion object (e.g., MIN_QUERY_LENGTH)
Package names : lowercase (e.g., org.btcmap, db.table.place)
Source files in app/src/main/kotlin/
Package structure mirrors directory structure
One class per file (filename matches class name)
Test files mirror source structure in app/src/androidTest/kotlin/
Grouped by:
Kotlin standard library (kotlinx.*)
Android framework (android.*)
AndroidX (androidx.*)
Third-party libraries (com.google.*, okhttp3.*, etc.)
Project imports (relative paths like db.db, bundle.BundledPlaces)
No wildcard imports
Sorted alphabetically within groups
Use 4 spaces for indentation (Kotlin default)
Opening brace on same line for classes/functions
Space after // in comments
Line length: typically under 120 chars (not strictly enforced)
Chained calls: one call per line with leading dot
Multi-parameter functions: one parameter per line with comma on previous line
Use ?. and ?: extensively
Prefer late initialization (lateinit var) over nullable types for view bindings
Use by lazy for expensive lazy initialization
Use !! sparingly (only when you're certain value is non-null)
Use viewLifecycleOwner.lifecycleScope.launch for Fragment coroutines
Use withContext(Dispatchers.IO) for blocking operations
Use Dispatchers.Main.immediate for UI updates requiring immediate execution
Extensions are preferred over utility classes
Extensions live in files named after the extended type (e.g., FragmentExt.kt extends Fragment)
Use receiver type aliases for cleaner code
private var _binding : MapFragmentBinding ? = null
private val binding get() = _binding !!
override fun onCreateView (...): View {
_binding = MapFragmentBinding .inflate(inflater, container, false )
return binding.root
}
override fun onDestroyView () {
super .onDestroyView()
_binding = null
}
Use org.btcmap.db.Database which provides full database layer abstraction
All the tables are stored in org.btcmap.db.table package
Read table schema and available request before considering changes or additions
Any schema change must include a migration
Use try-catch for anything that might cause a crash
Always close resources in try-finally or use .use {}
Use Material Design components
Use BottomSheetBehavior for bottom sheets
Handle window insets for edge-to-edge display
Use isVisible from AndroidX for visibility control
Group constants in companion object at the top of class
Use descriptive names (e.g., MIN_QUERY_LENGTH not MIN_QL)
app/src/main/kotlin/org/btcmap/
├── App.kt # Application singleton
├── Activity.kt # This app uses a single shared activity
├── Api.kt # Abstracts away all API interactions
├── boost/ # Stuff related to place boosts
├── bundle/ # Bundled data (only places, currently)
├── comment/ # Place comments feature
├── db/ # Database schema, migrations and queries
├── i18n/ # Multilanguage support
├── map/ # Map functionality
├── place/ # Place details
├── search/ # Search functionality
├── settings/ # User preferences
├── util/ # Various utilities and extension functions
└── view/ # Custom views
Networking : OkHttp with coroutines extension
Maps : MapLibre (Open-source Mapbox alternative)
UI : Material Design Components
Async : Kotlin Coroutines
QR Codes : QRGenerator
Color Picker : Colorpicker library
Instrumented tests are run by humans and are lower priority
Run unit tests (app/src/test) before reporting any task as done