Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
84 changes: 31 additions & 53 deletions .github/workflows/android_build.yml
Original file line number Diff line number Diff line change
Expand Up @@ -3,78 +3,57 @@ name: Android Build
on:
push:
branches:
- master # Change this to your main branch name (e.g., master)
- dev
- '**' # Trigger on push to any branch

jobs:
build-debug:
name: Build debug
# Build debug APK for all feature branches --> and not master
if: github.ref_name != 'master'
runs-on: ubuntu-latest
if: github.ref =='refs/heads/dev'
steps:
- name: Checkout code
uses: actions/checkout@v2

- name: Setup JDK
uses: actions/setup-java@v3
steps:
- uses: actions/checkout@v4
- uses: actions/setup-java@v4
with:
distribution: temurin
java-version: '17'

- name: Setup Gradle
uses: gradle/actions/setup-gradle@v3
with:
gradle-version: 7.4.2

- name: Setup Android NDK
uses: nttld/setup-ndk@v1.2.0
with:
ndk-version: r25c

- name: Grant execute permission for gradlew
run: chmod +x ./gradlew
- uses: gradle/actions/setup-gradle@v4
with: { gradle-version: 7.4.2 }
- uses: nttld/setup-ndk@v1.2.0
with: { ndk-version: r25c }
- run: chmod +x ./gradlew

- name: Build debug APK
run: ./gradlew assembleDebug

- name: Upload APK artifact
- name: Upload debug APK
uses: actions/upload-artifact@v4
with:
name: RECORDA-debug # Change this to your desired artifact name
path: ./app/build/outputs/apk/debug/*.apk
name: RECORDA-debug
path: app/build/outputs/apk/debug/*.apk

build-master:
name: Build master
build-release:
# Build release APK ONLY for master branch
if: github.ref_name == 'master'
runs-on: ubuntu-latest
if: github.ref == 'refs/heads/master'
steps:
- name: Checkout code
uses: actions/checkout@v2

- name: Setup JDK
uses: actions/setup-java@v3
steps:
- uses: actions/checkout@v4
- uses: actions/setup-java@v4
with:
distribution: temurin
java-version: '17' # Change this to the required Java version for your Android project

- name: Setup Gradle
uses: gradle/actions/setup-gradle@v3
with:
gradle-version: 7.4.2

- name: Setup Android NDK
uses: nttld/setup-ndk@v1.2.0
with:
ndk-version: r25c

- name: Grant execute permission for gradlew
run: chmod +x ./gradlew
java-version: '17'
- uses: gradle/actions/setup-gradle@v4
with: { gradle-version: 7.4.2 }
- uses: nttld/setup-ndk@v1.2.0
with: { ndk-version: r25c }
- run: chmod +x ./gradlew

- name: Build release APK
run: ./gradlew assembleRelease

- name: Sign app APK
uses: r0adkll/sign-android-release@v1
# ID used to access action output
id: sign_app
with:
releaseDirectory: app/build/outputs/apk/release
Expand All @@ -83,11 +62,10 @@ jobs:
keyStorePassword: ${{ secrets.KEY_STORE_PASSWORD }}
keyPassword: ${{ secrets.KEY_PASSWORD }}
env:
# override default build-tools version (33.0.0) -- optional
BUILD_TOOLS_VERSION: "34.0.0"
- name: Upload APK artifact

- name: Upload release APK
uses: actions/upload-artifact@v4
with:
name: RECORDA-release # Change this to your desired artifact name
path: ${{steps.sign_app.outputs.signedReleaseFile}} # Change the path to the location of your APK file

name: RECORDA-release
path: ${{ steps.sign_app.outputs.signedReleaseFile }}
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -38,3 +38,4 @@ output.json
obj/
.externalNativeBuild
app/.cxx/
/TODO.md
5 changes: 2 additions & 3 deletions .idea/gradle.xml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

52 changes: 52 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
# Changelog

All notable changes to RECORDA will be documented in this file.

The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).

---

## [1.4] – 2026-05-22

### Added
- **Dark theme support** – RECORDA now follows the system-wide dark/light mode setting. Dark-mode colours are aligned with the companion app [SENDA](https://github.com/NeuropsyOL/SENDA).
- **In-app tutorial** – a step-by-step guide is available via the new tutorial button in the main toolbar, helping new users get started quickly.

### Fixed
- App crash caused by a missing runtime permission request.
- Release APK signing now uses GitHub repository secrets for secure, reproducible builds.

### Changed
- GitHub Actions CI workflows refactored: reduced code duplication, fixed branch name references, and bumped all action versions to their latest supported releases.

---

## [1.3] – 2023-12-12

### Added
- Quality monitoring for recorded LSL streams (good / laggy / bad states with colour highlighting and heads-up notifications).
- Support for both regular and irregular LSL streams in quality checks.
- Configurable thresholds for laggy/bad detection (timeout and sampling-rate deviation).

### Fixed
- Incorrect stream-list indexing when scrolling (quality-indicator updates).

---

## [1.2] – 2023

### Added
- Settings dialog with optional custom recording name.
- Automatic unique file-name generation if no name is provided.

---

## [1.1] – 2022

### Added
- Initial public release of RECORDA.
- Detect and record LSL streams to XDF format on Android 8.0+.
- Refresh button to rescan the network for available streams.
- Start/Stop recording with on-device file-finalisation notification.

8 changes: 8 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
[![Android Build](https://github.com/NeuropsyOL/RECORDA/actions/workflows/android_build.yml/badge.svg)](https://github.com/NeuropsyOL/RECORDA/actions/workflows/android_build.yml)

# RECORDA
> 📋 See [CHANGELOG.md](CHANGELOG.md) for the full version history.

## Overview

**RECORDA** is an Android application to record [LabStreamingLayer](https://labstreaminglayer.readthedocs.io/) (LSL) streams directly on a smartphone.
Expand All @@ -24,11 +26,17 @@ However, since **RECORDA** is using the LSL framework, it can record any kind of
### Getting the APK file
Download the [latest release](https://github.com/NeuropsyOL/RECORDA/releases/latest) and install the apk on your smartphone or tablet running Android 8.0 or higher.

### In-App Tutorial
Tap the tutorial button in the main toolbar to open a step-by-step walkthrough of the app's features.

### Recording Data:
After the start of the application, the user is presented with the home screen, containing all main UI elements.
The user can refresh the list of available network streams by clicking the refresh button at the top right. All available streams are then listed in the list view below in the format *Stream Name (Sampling Rate)*. The desired streams should be selected from this list before starting the recording. Recording is initiated by pressing the *Start* button. Once the experiment is complete, the user should press the *Stop* button and wait while the file is finalized. The application will display a notification when the file is ready, including the file’s location on the device.
The gear button on the top left opens a *settings* dialog. An optional recording name can be configured in the settings; if no name is provided, a unique name will be automatically generated for each new file.

## Dark Theme
RECORDA supports the system-wide dark/light mode. When dark mode is active on your device, the app automatically switches to a dark colour scheme that is visually aligned with the [SENDA](https://github.com/NeuropsyOL/SENDA) companion app.


## Quality Monitoring
During a recording, **RECORDA** monitors the quality of the selected streams.
Expand Down
2 changes: 1 addition & 1 deletion app/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@

# Sets the minimum version of CMake required to build the native library.

cmake_minimum_required(VERSION 3.4.1)
cmake_minimum_required(VERSION 3.12)

# Creates and names a library, sets it as either STATIC
# or SHARED, and provides the relative paths to its source code.
Expand Down
23 changes: 12 additions & 11 deletions app/build.gradle
Original file line number Diff line number Diff line change
@@ -1,23 +1,23 @@
apply plugin: 'com.android.application'
apply plugin: 'org.jetbrains.kotlin.android'

android {
compileSdk 33
compileSdk 34
namespace "de.uol.neuropsy.recorda"
ndkVersion "25.2.9519653"
defaultConfig {
applicationId "com.uol.neuropsy.LSLReceiver"
applicationId "de.uol.neuropsy.recorda"
minSdkVersion 26
targetSdkVersion 31
versionCode 4 // increment with every release
versionName '1.3' // change with every release
targetSdkVersion 34
versionCode 5 // increment with every release
versionName '1.4' // change with every release
setProperty("archivesBaseName", "RECORDA-$versionName")
testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner"
externalNativeBuild {
cmake {
cppFlags "-std=c++11 -frtti -fexceptions"
arguments '-DANDROID_STL=c++_shared'
}
}

}

buildTypes {
Expand All @@ -33,10 +33,9 @@ android {
}
}
}
externalNativeBuild {
cmake {
externalNativeBuild.cmake {
version '3.24.1+'
path "../libxdf/CMakeLists.txt"
}
}

}
Expand All @@ -47,8 +46,10 @@ dependencies {
androidTestImplementation('com.android.support.test.espresso:espresso-core:3.0.2', {
exclude group: 'com.android.support', module: 'support-annotations'
})
implementation "androidx.viewpager2:viewpager2:1.0.0"
//noinspection GradleCompatible
implementation 'com.android.support:appcompat-v7:28.0.0'
implementation 'androidx.appcompat:appcompat:1.6.1'
implementation 'com.google.android.material:material:1.11.0'
testImplementation 'junit:junit:4.13'
//noinspection GradleCompatible
implementation 'com.android.support:cardview-v7:28.0.0'
Expand Down
10 changes: 9 additions & 1 deletion app/src/main/AndroidManifest.xml
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@
<uses-permission android:name="android.permission.WAKE_LOCK" />
<uses-permission android:name="android.permission.READ_PHONE_STATE" />
<uses-permission android:name="android.permission.FOREGROUND_SERVICE"/>
<uses-permission android:name="android.permission.FOREGROUND_SERVICE_DATA_SYNC"/>


<application android:allowBackup="true"
Expand Down Expand Up @@ -36,10 +37,17 @@
android:screenOrientation="portrait"
android:theme="@style/AppTheme.NoActionBar"/>

<activity
android:name="de.uol.neuropsy.recorda.TutorialActivity"
android:screenOrientation="portrait"
android:theme="@style/AppTheme.NoActionBar"/>


<service
android:name="de.uol.neuropsy.recorda.LSLService"
android:enabled="true"
android:exported="true"></service>
android:exported="true"
android:foregroundServiceType="dataSync"></service>
</application>

</manifest>
Loading
Loading