A social music discovery and tracking Android application that connects users through their music listening experiences with location-based features.
Sora is a Jetpack Compose-based Android app that allows users to:
- Track their music listening history with location data
- Discover what friends are listening to in real-time
- Share playlists and favorite songs
- Visualize listening patterns on an interactive map
- Connect with friends through music
- Language: Kotlin
- UI Framework: Jetpack Compose with Material 3
- Architecture: MVVM (Model-View-ViewModel)
- Backend: Supabase (PostgreSQL, Auth, Storage, Realtime)
- Music Integration: Spotify API
- Maps: Google Maps Android API
- Authentication: OAuth 2.0 with AppAuth
- Networking: Ktor Client
- Serialization: Kotlinx Serialization
- Image Loading: Coil
- Minimum SDK: 24 (Android 7.0)
- Target SDK: 34 (Android 14)
app/src/main/java/com/example/sora/
├── data/
│ ├── model/ # Data models (User, Song, Artist, Album, etc.)
│ └── repository/ # Data repositories for API interactions
├── feed/ # Social feed features
├── friends/ # Friends management UI
├── library/ # User's music library (playlists, songs)
├── main/ # Home screen and main feed components
├── map/ # Location-based music visualization
├── service/ # Background services (song tracking)
├── ui/ # Reusable UI components and theme
├── utils/ # Utility classes and helpers
├── viewmodel/ # ViewModels for business logic
├── MainActivity.kt # Main application activity
└── SplashActivity.kt # Splash screen
- Android Studio Hedgehog (2023.1.1) or newer
- JDK 17 or higher
- Android SDK 34
- An Android device or emulator running API 24+
-
Clone the repository:
git clone https://github.com/kellenGary/Sora.git cd Sora -
Create
local.propertiesfile in the root directory:sdk.dir=/path/to/your/Android/sdk # API Keys SUPABASE_URL=your_supabase_url SUPABASE_ANON_KEY=your_supabase_anon_key SPOTIFY_CLIENT_ID=your_spotify_client_id SPOTIFY_CLIENT_SECRET=your_spotify_client_secret GOOGLE_MAPS_API_KEY=your_google_maps_api_key
-
Sync Gradle:
./gradlew sync
-
Build the project:
./gradlew build
- Open the project in Android Studio
- Select a device or emulator
- Click the "Run" button or press
Shift + F10
./gradlew installDebugUnit tests verify business logic, data models, and utility functions without requiring an Android device.
./gradlew :app:testDebugUnitTest./gradlew :app:testDebugUnitTest --tests "com.example.sora.SoraUnitTests"After running tests, open the HTML report:
open app/build/reports/tests/testDebugUnitTest/index.htmlThe project includes the following unit tests:
SoraUnitTests.kt:
testUserModelCreation- Validates User data modeltestDisplayNameValidation- Tests display name validation rulestestGeographicFunctions- Tests coordinate validation and distance calculationstestSongFormatting- Tests song/artist formattingtestSongModelProperties- Tests Song model properties
Test Files Location: app/src/test/java/com/example/sora/
UI tests run on an Android device or emulator and test the actual UI components using Compose Testing.
- A connected Android device or running emulator
- Verify device connection:
adb devices
./gradlew connectedDebugAndroidTest./gradlew connectedDebugAndroidTest -Pandroid.testInstrumentationRunnerArguments.class=com.example.sora.HeaderComposeTestAfter running tests, open the HTML report:
open app/build/reports/androidTests/connected/index.htmlThe project includes the following Compose UI tests:
HeaderComposeTest.kt:
headerDisplaysSoraLogoAndTitle- Tests header component renderingheaderComponentRendersWithoutCrashing- Tests component stability
ActiveUserCardComposeTest.kt:
activeUserCardDisplaysUserName- Tests user name displayactiveUserCardHandlesClickInteraction- Tests click interactionsactiveUserCardDisplaysInitialWhenNoAvatar- Tests fallback avatar display
SettingCardComposeTest.kt:
settingCardRendersSuccessfully- Tests settings card renderingsettingOptionBoxDisplaysWithCorrectStyling- Tests option box stylingsettingCardHasCorrectLayout- Tests layout structure
Test Files Location: app/src/androidTest/java/com/example/sora/
- Run unit tests frequently during development (they're fast!)
- Run UI tests before committing to ensure UI stability
- Check test coverage to identify untested code paths
- Keep tests isolated - each test should be independent
- Use meaningful test names that describe what is being tested
To run all tests in CI:
# Unit tests (fast)
./gradlew :app:testDebugUnitTest
# UI tests (requires emulator/device)
./gradlew connectedDebugAndroidTest
# Both
./gradlew check connectedDebugAndroidTest- Real-time song tracking with location data
- Integration with Spotify API
- Background service for continuous tracking
- Follow friends and see their listening activity
- Share playlists and favorite songs
- Real-time activity feed
- Mutual friends discovery
- Interactive map showing where songs were listened to
- Discover music from specific locations
- Location history visualization
- Material 3 Design
- Dark mode support
- Smooth animations and transitions
- Responsive layouts
androidx.core:core-ktx:1.13.1androidx.activity:activity-compose:1.9.3androidx.compose.bom:2024.05.00
io.github.jan-tennert.supabase:postgrest-ktio.github.jan-tennert.supabase:gotrue-ktio.github.jan-tennert.supabase:storage-ktio.github.jan-tennert.supabase:realtime-kt
junit:junit:4.13.2- Unit testing frameworkandroidx.compose.ui:ui-test-junit4- Compose UI testingandroidx.test.ext:junit:1.1.5- Android JUnit extensionsandroidx.test.espresso:espresso-core:3.5.1- UI testing
See app/build.gradle.kts for complete dependency list.
- Fork the repository
- Create your feature branch:
git checkout -b feature/amazing-feature - Commit your changes:
git commit -m 'Add amazing feature' - Push to the branch:
git push origin feature/amazing-feature - Open a Pull Request
- Follow Kotlin coding conventions
- Write tests for new features
- Use meaningful variable and function names
- Document complex logic with comments
- Run tests before submitting PR
This project is private and proprietary.
Kellen Gary - @kellenGary
Project Link: https://github.com/kellenGary/Sora