Skip to content

Commit

Permalink
🐛 Fix MediaPlayer crash
Browse files Browse the repository at this point in the history
  • Loading branch information
Théophile Delmas authored and Théophile Delmas committed Dec 31, 2023
1 parent dcfa6f3 commit 2437b52
Showing 1 changed file with 70 additions and 46 deletions.
116 changes: 70 additions & 46 deletions app/src/main/java/com/rooster/rooster/AlarmActivity.kt
Original file line number Diff line number Diff line change
Expand Up @@ -19,17 +19,21 @@ import android.widget.SeekBar
import android.widget.TextView
import androidx.appcompat.app.AppCompatActivity
import androidx.fragment.app.FragmentActivity
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.delay
import kotlinx.coroutines.launch
import java.util.Calendar
import java.util.Date
import kotlin.concurrent.fixedRateTimer

class AlarmActivity : FragmentActivity() {
private var alarmIsRunning = false
private var isVibrating = false

private val wakeLock: PowerManager.WakeLock by lazy {
(getSystemService(Context.POWER_SERVICE) as PowerManager).newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, "alarm")
}

private var alarmIsRunning = false
private var vibrator: Vibrator? = null
private var mediaPlayer: MediaPlayer? = null
private var wakeLock: PowerManager.WakeLock? = null

override fun onCreate(savedInstanceState: Bundle?) {
Log.e("Alarm", "Activity Start")
Expand Down Expand Up @@ -95,46 +99,63 @@ class AlarmActivity : FragmentActivity() {
// Wake Phone
val powerManager: PowerManager = getSystemService(Context.POWER_SERVICE) as PowerManager
window.addFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON)
@Suppress("DEPRECATION") val wakeLock = powerManager.newWakeLock(PowerManager.ACQUIRE_CAUSES_WAKEUP or PowerManager.ON_AFTER_RELEASE or PowerManager.SCREEN_BRIGHT_WAKE_LOCK, "rooster:wakelock")
wakeLock.acquire()

val vibrator = applicationContext.getSystemService(Context.VIBRATOR_SERVICE) as Vibrator
wakeLock = powerManager.newWakeLock(
PowerManager.ACQUIRE_CAUSES_WAKEUP or
PowerManager.ON_AFTER_RELEASE or
PowerManager.SCREEN_BRIGHT_WAKE_LOCK, "rooster:wakelock"
)
wakeLock?.acquire()

vibrator = applicationContext.getSystemService(Context.VIBRATOR_SERVICE) as Vibrator
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
val gentlePattern = createWaveformVibrationPattern(longArrayOf(0, 1000, 2000, 3000), repeat = -1)

var vibrationEffect1 = VibrationEffect.createWaveform(gentlePattern, 3)

// it is safe to cancel other vibrations currently taking place
vibrator.cancel()
val soundUri = Uri.parse("android.resource://${applicationContext.packageName}/raw/alarmclock")
val mediaPlayer = MediaPlayer().apply {
vibrator!!.cancel()
val soundUri =
Uri.parse("android.resource://${applicationContext.packageName}/raw/alarmclock")

mediaPlayer = MediaPlayer().apply {
setDataSource(applicationContext, soundUri)
setAudioAttributes(
AudioAttributes.Builder()
.setUsage(AudioAttributes.USAGE_ALARM)
.setContentType(AudioAttributes.CONTENT_TYPE_MUSIC)
.build()
)
prepare()
setOnCompletionListener {
// Release MediaPlayer resources after completion
it?.release()
}
prepareAsync()
setOnPreparedListener { player ->
// Start playback when prepared
player.start()
startAlarmLoop()
}
isLooping = true
}
// Start a loop that checks a SharedPreferences for a flag to stop the vibration
Thread {
vibrator.vibrate(vibrationEffect1)
while (true) {
Log.w("Rooster Alarm", "Ring")
if (alarmIsRunning) {
mediaPlayer.start()
Thread.sleep(500)
} else {
vibrator.cancel()
mediaPlayer.stop()
mediaPlayer.release()
wakeLock.release()
break
}
Thread.sleep(1000)
}
}
private fun startAlarmLoop() {
// Start a loop that checks a SharedPreferences for a flag to stop the vibration
val vibesPattern = createWaveformVibrationPattern(longArrayOf(0, 1000, 2000, 3000), repeat = -1)
var vibrationEffect1 = VibrationEffect.createWaveform(vibesPattern, 3)
CoroutineScope(Dispatchers.Default).launch {
isVibrating = true
vibrator?.vibrate(vibrationEffect1)
if (alarmIsRunning) {
mediaPlayer?.start()
}
while (isVibrating) {
Log.w("Rooster Alarm", "Ring")
// Check for alarmIsRunning flag to control MediaPlayer and vibration
if (alarmIsRunning) {
delay(500)
} else {
isVibrating = false
break
}
}.start()
delay(1000)
}
}
}

Expand Down Expand Up @@ -169,32 +190,35 @@ class AlarmActivity : FragmentActivity() {
}

fun stopAlarm(view: View) {
val mediaPlayer = MediaPlayer()
val vibrator = getSystemService(Context.VIBRATOR_SERVICE) as Vibrator

alarmIsRunning = false
wakeLock.release()
mediaPlayer.stop()
vibrator.cancel()
releaseResources()
supportFragmentManager.popBackStackImmediate()
finish()
}

override fun onResume() {
super.onResume()
wakeLock.acquire()
wakeLock?.acquire()

if (!alarmIsRunning) {
//alarmIsRunning = true
}
}

override fun onPause() {
val mediaPlayer = MediaPlayer()
val vibrator = getSystemService(Context.VIBRATOR_SERVICE) as Vibrator
super.onPause()
alarmIsRunning = false
mediaPlayer.stop()
vibrator.cancel()
/*alarmIsRunning = false
mediaPlayer?.stop()
vibrator?.cancel()*/
}

private fun releaseResources() {
mediaPlayer?.stop()
mediaPlayer?.reset()
mediaPlayer?.release()
mediaPlayer = null

wakeLock?.release()
wakeLock = null
}
}

0 comments on commit 2437b52

Please sign in to comment.