Compare commits

..

7 Commits

Author SHA1 Message Date
pi
82276868c4 drehen und weiterspielen funktioniert jetzt
fixes #1
closes #1
resolves #1
2025-11-29 16:23:27 +01:00
pi
d14ec42a92 fade out now exponential and optional when minutes set 2025-11-03 18:17:10 +01:00
pi
0d5561feaf fade out enabled for set minutes and added volumen bar in ui 2025-11-03 18:07:44 +01:00
pi
fa671d6fc4 integrated start/stop button to ready or stopped button 2025-11-03 17:44:37 +01:00
pi
a16fd1e995 added colors 2025-10-29 14:02:00 +01:00
pi
1ca9f10658 changed to start/stopp 2025-10-29 13:47:08 +01:00
pi
6c3a36efe3 added stop button and info to put in minutes 2025-10-29 13:20:31 +01:00
4 changed files with 145 additions and 17 deletions

1
.idea/gradle.xml generated
View File

@@ -1,5 +1,6 @@
<?xml version="1.0" encoding="UTF-8"?> <?xml version="1.0" encoding="UTF-8"?>
<project version="4"> <project version="4">
<component name="GradleMigrationSettings" migrationVersion="1" />
<component name="GradleSettings"> <component name="GradleSettings">
<option name="linkedExternalProjectsSettings"> <option name="linkedExternalProjectsSettings">
<GradleProjectSettings> <GradleProjectSettings>

View File

@@ -8,9 +8,10 @@
android:supportsRtl="true" android:supportsRtl="true"
android:theme="@android:style/Theme.Light.NoTitleBar"> android:theme="@android:style/Theme.Light.NoTitleBar">
<activity android:name=".MainActivity" <activity android:name=".MainActivity"
android:exported="true"> android:exported="true"
android:configChanges="orientation|screenSize|keyboardHidden"
>
<intent-filter> <intent-filter>
<action android:name="android.intent.action.MAIN"/> <action android:name="android.intent.action.MAIN"/>
<category android:name="android.intent.category.LAUNCHER"/> <category android:name="android.intent.category.LAUNCHER"/>

View File

@@ -1,25 +1,38 @@
package com.example.hairdryer package com.example.hairdryer
import android.app.Activity import android.app.Activity
import android.graphics.Color
import android.media.AudioAttributes import android.media.AudioAttributes
import android.media.SoundPool import android.media.SoundPool
import android.os.Bundle import android.os.Bundle
import android.os.Handler import android.os.Handler
import android.widget.Button
import android.widget.EditText import android.widget.EditText
import android.widget.ProgressBar
import android.widget.TextView
import kotlin.math.pow
import kotlin.math.max
class MainActivity : Activity() { class MainActivity : Activity() {
private lateinit var soundPool: SoundPool private lateinit var soundPool: SoundPool
private var soundId = 0 private var soundId = 0
private var streamId = 0 private var streamId = 0
private val handler = Handler() 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?) { override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState) super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main) setContentView(R.layout.activity_main)
val status = findViewById<TextView>(R.id.statusText)
val input = findViewById<EditText>(R.id.timerInput) val input = findViewById<EditText>(R.id.timerInput)
val btn = findViewById<Button>(R.id.startBtn) val fadeToggle = findViewById<TextView>(R.id.fadeToggle)
val volumeBar = findViewById<ProgressBar>(R.id.volumeBar)
val attrs = AudioAttributes.Builder() val attrs = AudioAttributes.Builder()
.setUsage(AudioAttributes.USAGE_MEDIA) .setUsage(AudioAttributes.USAGE_MEDIA)
@@ -33,23 +46,98 @@ class MainActivity : Activity() {
soundId = soundPool.load(this, R.raw.sound, 1) soundId = soundPool.load(this, R.raw.sound, 1)
btn.setOnClickListener { updateUI(status, volumeBar, "Bereit", Color.LTGRAY, 1f)
val min = input.text.toString().toIntOrNull() ?: 0 fadeToggle.setOnClickListener {
startLoopingSound(min) 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 startLoopingSound(minutes: Int) { private fun startSound(minutes: Int, status: TextView, volumeBar: ProgressBar) {
// Starte Sound in Schleife stopSound(status, volumeBar)
streamId = soundPool.play(soundId, 1f, 1f, 1, -1, 1f) // -1 = loop unendlich streamId = soundPool.play(soundId, 1f, 1f, 1, -1, 1f)
isPlaying = true
startTime = System.currentTimeMillis()
if (minutes > 0) { if (minutes > 0) {
handler.postDelayed({ totalMillis = minutes * 60_000L
soundPool.stop(streamId) updateCountdown(minutes * 60, status)
}, minutes * 60_000L) // 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() { override fun onDestroy() {
super.onDestroy() super.onDestroy()
soundPool.release() soundPool.release()

View File

@@ -6,17 +6,55 @@
android:orientation="vertical" android:orientation="vertical"
android:padding="20dp"> android:padding="20dp">
<TextView
android:id="@+id/parentDeviceTitle"
android:gravity="center_horizontal"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_gravity="top|center_vertical"
android:text="Dunstabzugshaube/Hairdryer"
android:textSize="25dp" />
<Space
android:layout_width="match_parent"
android:layout_height="50dp" />
<TextView
android:id="@+id/statusText"
android:text="Bereit"
android:textSize="26sp"
android:gravity="center"
android:textColor="#000000"
android:padding="24dp"
android:background="#CCCCCC"
android:layout_width="match_parent"
android:layout_height="wrap_content" />
<EditText <EditText
android:id="@+id/timerInput" android:id="@+id/timerInput"
android:hint="Sleep Timer (Minuten)" android:hint="Sleep Timer (Minuten)"
android:inputType="number" android:inputType="number"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="wrap_content"/> android:layout_height="wrap_content"
android:layout_marginTop="20dp"/>
<Button <TextView
android:id="@+id/startBtn" android:id="@+id/fadeToggle"
android:text="Start" android:text="Fade-Out: OFF"
android:gravity="center"
android:padding="12dp"
android:layout_marginTop="20dp"
android:background="#AAAAAA"
android:textColor="#000000"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="wrap_content"/> android:layout_height="wrap_content"/>
<ProgressBar
android:id="@+id/volumeBar"
style="@android:style/Widget.ProgressBar.Horizontal"
android:layout_width="match_parent"
android:layout_height="24dp"
android:layout_marginTop="20dp"
android:max="100"
android:progress="100"/>
</LinearLayout> </LinearLayout>