HeartMusic is an Android application that merges the world of music with physical and emotional well-being. The project aims to monitor the user's emotional state through biometric parameters detected by a smartwatch and EEG device. The goal is offer a personalized listening experience to positively influence mood.
Music has a profound impact on our emotions. HeartMusic aims to create a "bridge" between the heartbeat and music playlists. By analyzing biometric data (BPM), the app can:
- Analyze the user's current emotional state.
- Suggest targeted playlists to improve mood or accompany a moment of relaxation.
- Monitor emotional trends over time through personalized charts and insights.
This project is developed by:
- Antonio Pepe
- Luca Rotelli
- Alessandro Ascani
- Zahra Omrani
The project follows a modern Full-Stack approach, clearly separating responsibilities between client and server to ensure scalability and robustness.
- UI: Entirely developed with Jetpack Compose for a modern and reactive interface.
- Architecture: Follows the MVVM (Model-View-ViewModel) pattern.
- Networking: Uses Retrofit and OkHttp for secure communication with the backend.
- Data Persistence: Implementation of Jetpack DataStore to keep the user session active even after closing the app.
- Language: Kotlin.
- Framework: Flask for managing REST APIs.
- Database: PostgreSQL, a robust relational database for managing users, sessions, and playlists.
- Containerization: The entire backend is packaged via Docker and Docker Compose, allowing for quick and identical installation on any machine (Database + Server).
- Security: Password encryption via
werkzeug.securityand session management. - Automation: Setup for background tasks and potential future notifications.
The application is designed to be inclusive and maintainable, following official Android guidelines:
- Internationalization (i18n): Zero hardcoded strings. All user-facing text is managed via
strings.xmlresources. The app currently supports English and Italian, automatically adapting to the system language. - Adaptive Layouts: Use of Density-independent pixels (dp) and ConstraintLayout to ensure a consistent experience across different screen sizes and densities.
- Semantic Navigation: Clear back-stack management and semantic properties (
contentDescription,onClickLabel,stateDescription) to improve the experience for users with assistive technologies like TalkBack.
- Android Studio (latest version)
- Docker Desktop installed and running
Open the terminal in the /backend folder and type:
docker compose up --buildThe server will be active at http://localhost:5005.
- Open the project's root folder with Android Studio.
- Ensure the emulator is running.
- Press Run. The app will automatically communicate with the server via the special address
10.0.2.2:5005.
For a real Android device, make sure USB debugging is enabled and run:
adb reverse tcp:5005 tcp:5005while true; do
adb reverse tcp:5005 tcp:5005
sleep 2
doneThe app will then talk to http://127.0.0.1:5005 on the device.
Build the debug APK without installing it:
./gradlew assembleDebugBuild and install the debug APK on a connected device:
./gradlew installDebugClean the project if Gradle gets stuck or artifacts become stale:
./gradlew cleanCheck which devices ADB can see:
adb devicesReset ADB if the device disappears or becomes unauthorized:
adb kill-server
adb start-server
adb devicesForward the backend port to a real device:
adb reverse tcp:5005 tcp:5005
adb reverse --listRead app logs for the network and sensor flow:
adb logcat | grep "ListeningVM\|EmotionAnalysisVM\|SensorManager\|SensorCollectionViewModel"HeartMusic includes a Wear OS companion module (:wear) used to collect heart rate samples from the smartwatch. The phone app sends /start_sampling; the watch app responds with /sensor_series.
Build the Wear OS APK:
./gradlew :wear:assembleDebugThe APK is generated at:
wear/build/outputs/apk/debug/wear-debug.apkConnect the Pixel Watch with wireless debugging:
- On the watch, enable Developer options and Wireless debugging.
- Use Pair new device and run:
adb pair WATCH_REAL_IP:PAIRING_PORT- Enter the pairing code shown on the watch.
- Go back to the main Wireless debugging screen and use the IP address & Port value:
adb connect WATCH_REAL_IP:DEBUG_PORTCheck that ADB sees both phone and watch:
adb devicesInstall the Wear APK on the watch only:
adb -s WATCH_REAL_IP:DEBUG_PORT install wear/build/outputs/apk/debug/wear-debug.apkAfter installation, open HeartMusic on the watch once and grant the BODY_SENSORS permission.
Useful Wear/sensor logs:
adb logcat | grep "WearableSamplingSender\|WearableMessageListener\|SamplingMessageService\|SamplingService\|WearSensorRepository\|WearDataSender"If installation fails with:
INSTALL_FAILED_MISSING_SHARED_LIBRARY: ... com.google.android.wearable
you are installing the Wear APK on the phone instead of the watch. Run adb devices and install again with adb -s WATCH_DEVICE_ID ....
Start backend and database:
cd backend
docker compose up -dStart backend and print logs in the foreground:
cd backend
docker compose upStop backend and database:
cd backend
docker compose downCheck running containers:
cd backend
docker compose psRestart only the backend container:
cd backend
docker compose restart webTest the API from the host machine:
curl -s http://localhost:5005/api/songs
curl -s http://localhost:5005/api/playlistsTest the API and count songs:
curl -s http://localhost:5005/api/songs | python3 -c 'import sys, json; print(len(json.load(sys.stdin)["songs"]))'If the app does not see the backend on a real device:
- Run
adb devicesand confirm the device is listed asdevice. - Recreate port forwarding with
adb reverse tcp:5005 tcp:5005. - Confirm the backend is running with
docker compose ps. - Check logs with
adb logcat | grep "ListeningVM\|EmotionAnalysisVM".
If Emotion Analysis does not appear:
- Check the app logs for
SensorManagerandSensorCollectionViewModel. - Confirm the wearable/EEG data source is actually connected.
- Remember that the app can only react to real collected signals, not only to the phone's internal sensors.
If EEG samples work but HR stays at 0 samples:
- Confirm the Wear APK is installed on the Pixel Watch, not on the phone.
- Open the Wear app once and grant
BODY_SENSORS. - Check phone logs for
Sent sampling request. - Check watch logs for
Start sampling receivedandSending snapshot. - Check phone logs for
Message received on path=/sensor_series.
Project created for the Mobile and Social Sensing System course - 2025/2026