146 lines
5.1 KiB
Kotlin
146 lines
5.1 KiB
Kotlin
package com.example.hairdryer
|
|
|
|
import android.app.Activity
|
|
import android.graphics.Color
|
|
import android.media.AudioAttributes
|
|
import android.media.SoundPool
|
|
import android.os.Bundle
|
|
import android.os.Handler
|
|
import android.widget.EditText
|
|
import android.widget.ProgressBar
|
|
import android.widget.TextView
|
|
import kotlin.math.pow
|
|
import kotlin.math.max
|
|
|
|
class MainActivity : Activity() {
|
|
|
|
private lateinit var soundPool: SoundPool
|
|
private var soundId = 0
|
|
private var streamId = 0
|
|
private val handler = Handler()
|
|
private var isPlaying = false
|
|
private var fadeEnabled = false
|
|
private var totalMillis: Long = 0
|
|
private var startTime: Long = 0
|
|
private var fadeRunnable: Runnable? = null
|
|
private var countdownRunnable: Runnable? = null
|
|
|
|
override fun onCreate(savedInstanceState: Bundle?) {
|
|
super.onCreate(savedInstanceState)
|
|
setContentView(R.layout.activity_main)
|
|
|
|
val status = findViewById<TextView>(R.id.statusText)
|
|
val input = findViewById<EditText>(R.id.timerInput)
|
|
val fadeToggle = findViewById<TextView>(R.id.fadeToggle)
|
|
val volumeBar = findViewById<ProgressBar>(R.id.volumeBar)
|
|
|
|
val attrs = AudioAttributes.Builder()
|
|
.setUsage(AudioAttributes.USAGE_MEDIA)
|
|
.setContentType(AudioAttributes.CONTENT_TYPE_MUSIC)
|
|
.build()
|
|
|
|
soundPool = SoundPool.Builder()
|
|
.setMaxStreams(1)
|
|
.setAudioAttributes(attrs)
|
|
.build()
|
|
|
|
soundId = soundPool.load(this, R.raw.sound, 1)
|
|
|
|
updateUI(status, volumeBar, "Bereit", Color.LTGRAY, 1f)
|
|
fadeToggle.setOnClickListener {
|
|
fadeEnabled = !fadeEnabled
|
|
fadeToggle.text = "Fade-Out: " + if (fadeEnabled) "ON" else "OFF"
|
|
}
|
|
|
|
status.setOnClickListener {
|
|
if (isPlaying) {
|
|
stopSound(status, volumeBar)
|
|
} else {
|
|
val minutes = input.text.toString().toIntOrNull() ?: 0
|
|
startSound(minutes, status, volumeBar)
|
|
}
|
|
}
|
|
}
|
|
|
|
private fun startSound(minutes: Int, status: TextView, volumeBar: ProgressBar) {
|
|
stopSound(status, volumeBar)
|
|
streamId = soundPool.play(soundId, 1f, 1f, 1, -1, 1f)
|
|
isPlaying = true
|
|
startTime = System.currentTimeMillis()
|
|
|
|
if (minutes > 0) {
|
|
totalMillis = minutes * 60_000L
|
|
updateCountdown(minutes * 60, status)
|
|
// Countdown jede Sekunde
|
|
countdownRunnable = object : Runnable {
|
|
override fun run() {
|
|
val elapsedSec = ((System.currentTimeMillis() - startTime) / 1000).toInt()
|
|
val remainingSec = max(minutes * 60 - elapsedSec, 0)
|
|
updateCountdown(remainingSec, status)
|
|
if (remainingSec > 0) {
|
|
handler.postDelayed(this, 1000L)
|
|
} else {
|
|
stopSound(status, volumeBar)
|
|
}
|
|
}
|
|
}
|
|
handler.postDelayed(countdownRunnable!!, 1000L)
|
|
|
|
// Fade-Out (optional)
|
|
if (fadeEnabled) {
|
|
fadeRunnable = object : Runnable {
|
|
override fun run() {
|
|
if (!isPlaying) return
|
|
val elapsed = System.currentTimeMillis() - startTime
|
|
val progress = (elapsed.toFloat() / totalMillis).coerceIn(0f, 1f)
|
|
val volume = (1 - progress).pow(2) // exponentielles Fade
|
|
soundPool.setVolume(streamId, volume, volume)
|
|
volumeBar.progress = (volume * 100).toInt()
|
|
if (progress < 1f) {
|
|
handler.postDelayed(this, 200L)
|
|
}
|
|
}
|
|
}
|
|
handler.postDelayed(fadeRunnable!!, 200L)
|
|
} else {
|
|
volumeBar.progress = 100
|
|
}
|
|
} else {
|
|
// unendlich
|
|
updateUI(status, volumeBar, "Läuft: ∞", Color.GREEN, 1f)
|
|
volumeBar.progress = 100
|
|
}
|
|
}
|
|
|
|
private fun updateCountdown(remainingSec: Int, status: TextView) {
|
|
val minutes = remainingSec / 60
|
|
val seconds = remainingSec % 60
|
|
status.text = String.format("Läuft: %02d:%02d", minutes, seconds)
|
|
status.setBackgroundColor(Color.GREEN)
|
|
status.setTextColor(Color.BLACK)
|
|
}
|
|
|
|
private fun stopSound(status: TextView, volumeBar: ProgressBar) {
|
|
if (isPlaying) {
|
|
soundPool.stop(streamId)
|
|
isPlaying = false
|
|
}
|
|
handler.removeCallbacks(countdownRunnable ?: Runnable {})
|
|
handler.removeCallbacks(fadeRunnable ?: Runnable {})
|
|
updateUI(status, volumeBar, "Gestoppt", Color.RED, 0f)
|
|
volumeBar.progress = 0
|
|
}
|
|
|
|
private fun updateUI(view: TextView, bar: ProgressBar, text: String, color: Int, volume: Float) {
|
|
view.text = text
|
|
view.setBackgroundColor(color)
|
|
view.setTextColor(Color.BLACK)
|
|
bar.progress = (volume * 100).toInt()
|
|
}
|
|
|
|
override fun onDestroy() {
|
|
super.onDestroy()
|
|
soundPool.release()
|
|
}
|
|
}
|