Files
markandClaude Fable 5 edb367cca3 feat: system media controls (MediaSession) for the active server (#1)
* feat: add system media controls for the active server

Add a media3 MediaSessionService that mirrors playback on the active
RelayTV server as a system media session (lock screen / quick settings):

- MediaControlService polls GET /status and publishes state, metadata,
  artwork, and remote volume; forwards play/pause, next/previous, seek,
  stop, and volume to the server HTTP API
- RelayRemotePlayer implements SimpleBasePlayer over the remote state
- RemoteStatus parses /status defensively across server versions
- New Settings screen (toolbar menu) with a media-controls toggle and a
  Manage servers shortcut; fix open_servers intent handling via
  onNewIntent when MainActivity is already running

Release prep:

- Bump to versionCode 6 / versionName 1.3.0
- Wire optional release signing from MYAPP_RELEASE_* gradle properties
- Add FOREGROUND_SERVICE(_MEDIA_PLAYBACK) permissions and lint opt-ins
- Update privacy policy, release checklist (Play Console foreground
  service declaration), README, and Gradle daemon heap

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>

* ci: sign release bundle in GitHub Actions

Decode the upload keystore from the RELEASE_KEYSTORE_BASE64 secret and pass
the MYAPP_RELEASE_* signing properties to Gradle via ORG_GRADLE_PROJECT_*
env vars, so tagged releases produce a signed .aab. Fail fast if the keystore
secret is missing, and verify the bundle signature after the build.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>

---------

Co-authored-by: Claude Fable 5 <noreply@anthropic.com>
2026-07-06 19:45:34 -05:00

68 lines
1.9 KiB
Groovy

plugins {
id "com.android.application"
id "org.jetbrains.kotlin.android"
}
android {
namespace = "pro.relaytv"
compileSdk = 35
defaultConfig {
applicationId = "pro.relaytv"
minSdk = 26
targetSdk = 35
versionCode = 6
versionName = "1.3.0"
}
// Release signing is configured via gradle.properties (see todo.md /
// docs/RELEASE_CHECKLIST.md); without those properties the release
// build stays unsigned so CI and local debug workflows keep working.
signingConfigs {
release {
if (project.hasProperty("MYAPP_RELEASE_STORE_FILE")) {
storeFile = file(MYAPP_RELEASE_STORE_FILE)
storePassword = MYAPP_RELEASE_STORE_PASSWORD
keyAlias = MYAPP_RELEASE_KEY_ALIAS
keyPassword = MYAPP_RELEASE_KEY_PASSWORD
}
}
}
buildTypes {
release {
minifyEnabled = true
shrinkResources = true
proguardFiles(
getDefaultProguardFile("proguard-android-optimize.txt"),
"proguard-rules.pro"
)
if (project.hasProperty("MYAPP_RELEASE_STORE_FILE")) {
signingConfig = signingConfigs.release
}
}
debug {
minifyEnabled = false
}
}
compileOptions {
sourceCompatibility = JavaVersion.VERSION_17
targetCompatibility = JavaVersion.VERSION_17
}
kotlinOptions {
jvmTarget = "17"
}
}
dependencies {
implementation "androidx.core:core-ktx:1.13.1"
implementation "androidx.appcompat:appcompat:1.7.0"
implementation "androidx.activity:activity-ktx:1.9.2"
implementation "com.google.android.material:material:1.12.0"
implementation "com.squareup.okhttp3:okhttp:4.12.0"
implementation "androidx.work:work-runtime-ktx:2.9.1"
implementation "androidx.media3:media3-session:1.7.1"
}