diff --git a/.idea/kotlinc.xml b/.idea/kotlinc.xml
index fdf8d99..d4b7acc 100644
--- a/.idea/kotlinc.xml
+++ b/.idea/kotlinc.xml
@@ -1,6 +1,6 @@
-
+
\ No newline at end of file
diff --git a/app/build.gradle.kts b/app/build.gradle.kts
index 6695ae7..6dcbac4 100644
--- a/app/build.gradle.kts
+++ b/app/build.gradle.kts
@@ -1,6 +1,8 @@
plugins {
alias(libs.plugins.android.application)
alias(libs.plugins.kotlin.android)
+ alias(libs.plugins.compose.compiler)
+ id("org.jetbrains.kotlin.plugin.serialization") version "2.0.20"
}
android {
@@ -10,7 +12,7 @@ android {
defaultConfig {
applicationId = "usr.empty.player"
minSdk = 34
- targetSdk = 34
+ targetSdk = 35
versionCode = 1
versionName = "0.0.1α"
@@ -63,11 +65,6 @@ dependencies {
implementation(libs.androidx.media3.common)
implementation(libs.androidx.media3.session)
- androidTestImplementation(libs.androidx.junit)
- androidTestImplementation(libs.androidx.espresso.core)
- androidTestImplementation(platform(libs.androidx.compose.bom))
- androidTestImplementation(libs.androidx.ui.test.junit4)
-
debugImplementation(libs.androidx.ui.tooling)
debugImplementation(libs.androidx.ui.test.manifest)
}
\ No newline at end of file
diff --git a/app/src/main/java/usr/empty/player/MainActivity.kt b/app/src/main/java/usr/empty/player/MainActivity.kt
index 6a1d3d8..e884543 100644
--- a/app/src/main/java/usr/empty/player/MainActivity.kt
+++ b/app/src/main/java/usr/empty/player/MainActivity.kt
@@ -6,15 +6,17 @@ import android.net.Uri
import android.os.Bundle
import android.os.Environment
import android.provider.Settings
-import android.util.Log
import androidx.activity.ComponentActivity
import androidx.activity.compose.rememberLauncherForActivityResult
import androidx.activity.compose.setContent
import androidx.activity.enableEdgeToEdge
import androidx.activity.result.contract.ActivityResultContracts
import androidx.compose.foundation.clickable
+import androidx.compose.foundation.layout.Arrangement
import androidx.compose.foundation.layout.Column
+import androidx.compose.foundation.layout.Row
import androidx.compose.foundation.layout.fillMaxSize
+import androidx.compose.foundation.layout.fillMaxWidth
import androidx.compose.foundation.layout.padding
import androidx.compose.foundation.lazy.LazyColumn
import androidx.compose.foundation.lazy.items
@@ -26,12 +28,14 @@ import androidx.compose.material3.Text
import androidx.compose.runtime.Composable
import androidx.compose.runtime.mutableStateListOf
import androidx.compose.runtime.remember
-import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.graphics.RectangleShape
+import androidx.compose.ui.platform.LocalContext
import androidx.compose.ui.tooling.preview.Preview
import androidx.compose.ui.unit.dp
import androidx.compose.ui.unit.sp
+import kotlinx.serialization.encodeToString
+import kotlinx.serialization.json.Json
import usr.empty.player.ui.theme.PlayerTheme
@@ -72,6 +76,7 @@ fun uriToPath(uri: Uri): String {
@Composable
fun MainLayout(modifier: Modifier = Modifier) {
+ val context = LocalContext.current
val notas = remember { mutableStateListOf() }
val pickAudioLauncher = rememberLauncherForActivityResult(
@@ -92,12 +97,38 @@ fun MainLayout(modifier: Modifier = Modifier) {
}
Column(modifier.fillMaxSize()) {
- Button(shape = RectangleShape, colors = ButtonDefaults.buttonColors(
- containerColor = MaterialTheme.colorScheme.secondaryContainer, contentColor = MaterialTheme.colorScheme.secondary
- ), modifier = Modifier.align(Alignment.CenterHorizontally), onClick = {
- pickAudioLauncher.launch("audio/*")
- }) {
- Text("add track")
+ Row(
+ horizontalArrangement = Arrangement.Absolute.SpaceEvenly,
+ modifier = Modifier.fillMaxWidth(),
+ ) {
+ Button(shape = RectangleShape, colors = ButtonDefaults.buttonColors(
+ containerColor = MaterialTheme.colorScheme.secondaryContainer, contentColor = MaterialTheme.colorScheme.secondary
+ ), modifier = Modifier, onClick = {
+ pickAudioLauncher.launch("audio/*")
+ }) {
+ Text("add track")
+ }
+// VerticalDivider()
+ Button(shape = RectangleShape, colors = ButtonDefaults.buttonColors(
+ containerColor = MaterialTheme.colorScheme.secondaryContainer, contentColor = MaterialTheme.colorScheme.secondary
+ ), modifier = Modifier, onClick = {
+ context.startService(Intent(context, PlayerService::class.java).apply {
+ putExtra("check", "empty")
+ putExtra("type", "pause")
+ })
+ }) {
+ Text("| pause |")
+ }
+ Button(shape = RectangleShape, colors = ButtonDefaults.buttonColors(
+ containerColor = MaterialTheme.colorScheme.secondaryContainer, contentColor = MaterialTheme.colorScheme.secondary
+ ), modifier = Modifier, onClick = {
+ context.startService(Intent(context, PlayerService::class.java).apply {
+ putExtra("check", "empty")
+ putExtra("type", "play")
+ })
+ }) {
+ Text("| play >")
+ }
}
NotaList(notas)
}
@@ -105,13 +136,20 @@ fun MainLayout(modifier: Modifier = Modifier) {
@Composable
fun NotaList(notas: List, modifier: Modifier = Modifier) {
+ val context = LocalContext.current
LazyColumn(
modifier = modifier,
) {
items(notas) { nota ->
Column(modifier = Modifier
.fillParentMaxWidth()
- .clickable { }
+ .clickable {
+ context.startService(Intent(context, PlayerService::class.java).apply {
+ putExtra("check", "empty")
+ putExtra("type", "nota")
+ putExtra("nota", Json.encodeToString(nota))
+ })
+ }
.padding(4.dp)
.padding(start = 16.dp)) {
Text(
@@ -121,7 +159,6 @@ fun NotaList(notas: List, modifier: Modifier = Modifier) {
nota.artist, fontSize = 12.sp
)
}
- Log.d("nya", nota.toString())
}
}
}
diff --git a/app/src/main/java/usr/empty/player/Nota.kt b/app/src/main/java/usr/empty/player/Nota.kt
new file mode 100644
index 0000000..bc6e84e
--- /dev/null
+++ b/app/src/main/java/usr/empty/player/Nota.kt
@@ -0,0 +1,13 @@
+package usr.empty.player
+
+import androidx.media3.common.MediaItem
+import androidx.media3.exoplayer.ExoPlayer
+
+
+class Nota(val descriptor: NotaDescriptor) {
+ val mediaSource = MediaItem.fromUri(descriptor.source)
+
+ fun prepare(player: ExoPlayer) {
+ player.setMediaItem(mediaSource)
+ }
+}
\ No newline at end of file
diff --git a/app/src/main/java/usr/empty/player/PlayerService.kt b/app/src/main/java/usr/empty/player/PlayerService.kt
index f48c1cd..a71b6fd 100644
--- a/app/src/main/java/usr/empty/player/PlayerService.kt
+++ b/app/src/main/java/usr/empty/player/PlayerService.kt
@@ -8,11 +8,14 @@ import androidx.media3.session.MediaSession
import androidx.media3.session.MediaSessionService
import com.google.common.util.concurrent.Futures
import com.google.common.util.concurrent.ListenableFuture
+import kotlinx.serialization.json.Json
+import java.util.concurrent.ConcurrentLinkedDeque
class PlayerService : MediaSessionService() {
- private var mediaSession: MediaSession? = null
- var player: ExoPlayer? = null
+ private lateinit var mediaSession: MediaSession
+ lateinit var player: ExoPlayer
+ private var virtualQueue = ConcurrentLinkedDeque()
override fun onCreate() {
super.onCreate()
@@ -20,26 +23,35 @@ class PlayerService : MediaSessionService() {
player = this
mediaSession = MediaSession.Builder(this@PlayerService, this).setCallback(MediaSessionCallback()).build()
}
- Log.d("meow", "memememe")
}
override fun onStartCommand(intent: Intent?, flags: Int, startId: Int): Int {
+ Log.d("nya", "start!!!")
intent?.run {
-
+ if (getStringExtra("check") != "empty") return@run
+ handleCommand(getStringExtra("type")!!, this)
}
return super.onStartCommand(intent, flags, startId)
}
- private fun start() {
-
+ private fun handleCommand(type: String, intent: Intent) {
+ when (type) {
+ "nota" -> {
+ virtualQueue.add(Nota(Json.decodeFromString(intent.getStringExtra("nota")!!)))
+// virtualQueue.first.prepare(player)
+ virtualQueue.last.prepare(player)
+ player.prepare()
+ player.play()
+ Log.d("nya", virtualQueue.last.mediaSource.toString())
+ }
+ "pause" -> player.pause()
+ "play" -> player.play()
+ }
}
override fun onDestroy() {
- player?.release()
- mediaSession?.release()
- player = null
- mediaSession = null
- Log.d("meow", "owowowow")
+ player.release()
+ mediaSession.release()
super.onDestroy()
}
diff --git a/app/src/test/java/usr/empty/player/ExampleUnitTest.kt b/app/src/test/java/usr/empty/player/ExampleUnitTest.kt
deleted file mode 100644
index 1de8dd7..0000000
--- a/app/src/test/java/usr/empty/player/ExampleUnitTest.kt
+++ /dev/null
@@ -1,17 +0,0 @@
-package usr.empty.player
-
-import org.junit.Test
-
-import org.junit.Assert.*
-
-/**
- * Example local unit test, which will execute on the development machine (host).
- *
- * See [testing documentation](http://d.android.com/tools/testing).
- */
-class ExampleUnitTest {
- @Test
- fun addition_isCorrect() {
- assertEquals(4, 2 + 2)
- }
-}
\ No newline at end of file
diff --git a/gradle.properties b/gradle.properties
index 20e2a01..316a8ed 100644
--- a/gradle.properties
+++ b/gradle.properties
@@ -20,4 +20,5 @@ kotlin.code.style=official
# Enables namespacing of each library's R class so that its R class includes only the
# resources declared in the library itself and none from the library's dependencies,
# thereby reducing the size of the R class for that library
-android.nonTransitiveRClass=true
\ No newline at end of file
+android.nonTransitiveRClass=true
+org.gradle.configuration-cache=true
\ No newline at end of file
diff --git a/gradle/libs.versions.toml b/gradle/libs.versions.toml
index 1ee673b..031b62f 100644
--- a/gradle/libs.versions.toml
+++ b/gradle/libs.versions.toml
@@ -1,28 +1,19 @@
[versions]
-agp = "8.6.0"
-core = "1.6.1"
-kotlin = "1.9.0"
+agp = "8.6.1"
+kotlin = "2.0.0"
coreKtx = "1.13.1"
-junit = "4.13.2"
-junitVersion = "1.2.1"
-espressoCore = "3.6.1"
-kotlinxSerializationJson = "1.7.1"
-lifecycleRuntimeKtx = "2.6.1"
+kotlinxSerializationJson = "1.7.3"
+lifecycleRuntimeKtx = "2.8.6"
activityCompose = "1.9.2"
-composeBom = "2024.04.01"
+composeBom = "2024.09.02"
media3Exoplayer = "1.4.1"
-junitJupiter = "5.8.1"
[libraries]
-androidx-core = { module = "androidx.test:core", version.ref = "core" }
androidx-core-ktx = { group = "androidx.core", name = "core-ktx", version.ref = "coreKtx" }
androidx-media3-common = { module = "androidx.media3:media3-common", version.ref = "media3Exoplayer" }
androidx-media3-exoplayer = { module = "androidx.media3:media3-exoplayer", version.ref = "media3Exoplayer" }
androidx-media3-session = { module = "androidx.media3:media3-session", version.ref = "media3Exoplayer" }
androidx-media3-ui = { module = "androidx.media3:media3-ui", version.ref = "media3Exoplayer" }
-junit = { group = "junit", name = "junit", version.ref = "junit" }
-androidx-junit = { group = "androidx.test.ext", name = "junit", version.ref = "junitVersion" }
-androidx-espresso-core = { group = "androidx.test.espresso", name = "espresso-core", version.ref = "espressoCore" }
androidx-lifecycle-runtime-ktx = { group = "androidx.lifecycle", name = "lifecycle-runtime-ktx", version.ref = "lifecycleRuntimeKtx" }
androidx-activity-compose = { group = "androidx.activity", name = "activity-compose", version.ref = "activityCompose" }
androidx-compose-bom = { group = "androidx.compose", name = "compose-bom", version.ref = "composeBom" }
@@ -31,15 +22,11 @@ androidx-ui-graphics = { group = "androidx.compose.ui", name = "ui-graphics" }
androidx-ui-tooling = { group = "androidx.compose.ui", name = "ui-tooling" }
androidx-ui-tooling-preview = { group = "androidx.compose.ui", name = "ui-tooling-preview" }
androidx-ui-test-manifest = { group = "androidx.compose.ui", name = "ui-test-manifest" }
-androidx-ui-test-junit4 = { group = "androidx.compose.ui", name = "ui-test-junit4" }
androidx-material3 = { group = "androidx.compose.material3", name = "material3" }
kotlinx-serialization-json = { module = "org.jetbrains.kotlinx:kotlinx-serialization-json", version.ref = "kotlinxSerializationJson" }
-junit-jupiter = { group = "org.junit.jupiter", name = "junit-jupiter", version.ref = "junitJupiter" }
-mockito-core = { module = "org.mockito:mockito-core", version = "5.10.0" }
-mockito-kotlin = { module = "org.mockito.kotlin:mockito-kotlin", version = "5.4.0" }
-mockk = { module = "io.mockk:mockk", version = "1.13.10" }
[plugins]
android-application = { id = "com.android.application", version.ref = "agp" }
kotlin-android = { id = "org.jetbrains.kotlin.android", version.ref = "kotlin" }
+compose-compiler = { id = "org.jetbrains.kotlin.plugin.compose", version.ref = "kotlin" }