diff --git a/app/build.gradle b/app/build.gradle index 4a6df77..3a24669 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -29,8 +29,8 @@ android { applicationId "fr.forum_thalie.tsumugi" minSdkVersion 16 targetSdkVersion 30 - versionCode 115 - versionName "1.1.5" + versionCode 116 + versionName "1.1.6" testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner" vectorDrawables.useSupportLibrary = true } diff --git a/app/src/main/java/fr/forum_thalie/tsumugi/RadioService.kt b/app/src/main/java/fr/forum_thalie/tsumugi/RadioService.kt index c98f641..ccbb25a 100644 --- a/app/src/main/java/fr/forum_thalie/tsumugi/RadioService.kt +++ b/app/src/main/java/fr/forum_thalie/tsumugi/RadioService.kt @@ -454,12 +454,13 @@ class RadioService : MediaBrowserServiceCompat() { // this function is playing the stream if available, or a default sound if there's a problem. private fun beginPlayingOrFallback() { - PlayerStore.instance.volume.value = 100 // we set the max volume for exoPlayer to be sure it rings correctly. + PlayerStore.instance.volume.value = PreferenceManager.getDefaultSharedPreferences(this).getInt("alarmVolume", 100) + // we set the max volume for exoPlayer to be sure it rings correctly. beginPlaying(isRinging = true, isFallback = false) val wait: (Any?) -> Any = { /* Here we lower the isAlarmStopped flag and we wait for 17s. (seems like 12 could be a bit too short since I increased the buffer!!) - If the player stops the alarm (by calling an intent), the isAlarmStopped flag will be raised. + If the user stops the alarm (by calling an intent), the isAlarmStopped flag will be raised. */ isAlarmStopped = false // reset the flag var i = 0 @@ -513,8 +514,11 @@ class RadioService : MediaBrowserServiceCompat() { return } - if (mediaSession.controller.playbackState.state == PlaybackStateCompat.STATE_PLAYING && !isRinging) - return // nothing to do here + // TODO: Remove this + if (mediaSession.controller.playbackState.state == PlaybackStateCompat.STATE_PLAYING && !isRinging && isAlarmStopped) + return // nothing to do here + isAlarmStopped = true + PlayerStore.instance.playbackState.value = PlaybackStateCompat.STATE_PLAYING // Reinitialize media player. Otherwise the playback doesn't resume when beginPlaying. Dunno why. @@ -554,8 +558,7 @@ class RadioService : MediaBrowserServiceCompat() { if (mediaSession.controller.playbackState.state == PlaybackStateCompat.STATE_STOPPED) return // nothing to do here - if (PlayerStore.instance.playbackState.value == PlaybackStateCompat.STATE_PLAYING) - isAlarmStopped = true + isAlarmStopped = true PlayerStore.instance.playbackState.value = PlaybackStateCompat.STATE_STOPPED diff --git a/app/src/main/java/fr/forum_thalie/tsumugi/alarm/RadioAlarmExtensions.kt b/app/src/main/java/fr/forum_thalie/tsumugi/alarm/RadioAlarmExtensions.kt deleted file mode 100644 index 23131df..0000000 --- a/app/src/main/java/fr/forum_thalie/tsumugi/alarm/RadioAlarmExtensions.kt +++ /dev/null @@ -1,33 +0,0 @@ -package fr.forum_thalie.tsumugi.alarm - -import android.content.Context -import android.content.Intent -import fr.forum_thalie.tsumugi.Actions -import fr.forum_thalie.tsumugi.RadioService - - -fun playOnFallback(c: Context) { - val a = Actions.PLAY_OR_FALLBACK - val i = Intent(c, RadioService::class.java) - i.putExtra("action", a.name) - c.startService(i) -} - -fun resume(c: Context) -{ - -} - -fun resumeStop(c: Context) { - val a = Actions.PLAY - val i = Intent(c, RadioService::class.java) - i.putExtra("action", a.name) - c.startService(i) -} - -fun resumePlay(c: Context) { - val a = Actions.PLAY - val i = Intent(c, RadioService::class.java) - i.putExtra("action", a.name) - c.startService(i) -} \ No newline at end of file diff --git a/app/src/main/java/fr/forum_thalie/tsumugi/preferences/AlarmAdjustVolumeFragment.kt b/app/src/main/java/fr/forum_thalie/tsumugi/preferences/AlarmAdjustVolumeFragment.kt new file mode 100644 index 0000000..aba0b8a --- /dev/null +++ b/app/src/main/java/fr/forum_thalie/tsumugi/preferences/AlarmAdjustVolumeFragment.kt @@ -0,0 +1,129 @@ +package fr.forum_thalie.tsumugi.preferences + +import android.content.Context +import android.content.Intent +import android.media.AudioManager +import android.os.Bundle +import android.view.KeyEvent +import android.view.LayoutInflater +import android.view.View +import android.view.ViewGroup +import androidx.appcompat.app.AlertDialog +import androidx.appcompat.app.AppCompatActivity +import androidx.preference.PreferenceFragmentCompat +import androidx.preference.PreferenceManager +import androidx.preference.SeekBarPreference +import androidx.preference.SwitchPreferenceCompat +import fr.forum_thalie.tsumugi.Actions +import fr.forum_thalie.tsumugi.R +import fr.forum_thalie.tsumugi.RadioService +import fr.forum_thalie.tsumugi.playerstore.PlayerStore +import kotlinx.coroutines.* +import kotlin.coroutines.CoroutineContext +import kotlin.math.max +import kotlin.math.min + + +class AlarmAdjustVolumeFragment : PreferenceFragmentCompat() { + override fun onAttach(context: Context) { + (activity as AppCompatActivity).supportActionBar?.title = context.getString(R.string.test_alarm_volume) + super.onAttach(context) + } + + // get previous state: if it's playing, we'll resume playing as multimedia; if it was stopped, we'll stop + private var isPlayingMultimedia: Boolean = PlayerStore.instance.isPlaying.value ?: false + + override fun onStop() { + if (isPlayingMultimedia) + { + actionOnService(Actions.PLAY) + } else { + actionOnService(Actions.PAUSE) + } + PlayerStore.instance.volume.value = PreferenceManager.getDefaultSharedPreferences(requireContext()).getInt("volume", 100) + super.onStop() + } + + override fun onResume() { + + isPlayingMultimedia = PlayerStore.instance.isPlaying.value ?: false + // start as alarm + actionOnService(Actions.PLAY_OR_FALLBACK) + super.onResume() + } + + override fun onViewCreated(view: View, savedInstanceState: Bundle?) { + super.onViewCreated(view, savedInstanceState) + + fun debounce(delayMs: Long = 500L, + coroutineContext: CoroutineContext, + f: (T) -> Unit): (T) -> Unit { + var debounceJob: Job? = null + return { param: T -> + if (debounceJob?.isCompleted != false) { + debounceJob = CoroutineScope(coroutineContext).launch { + delay(delayMs) + f(param) + } + } + } + } + + val adjustAlarmVolume: (Int) -> Unit = debounce(50, GlobalScope.coroutineContext) { + android.util.Log.d(tag, "button $it pushed") + val keyCode = it + val audioManager = requireContext().getSystemService(Context.AUDIO_SERVICE) as AudioManager + audioManager.apply { + val currentVolume = this.getStreamVolume(AudioManager.STREAM_ALARM) + val minVolume = 0 // audioManager.getStreamMinVolume(AudioManager.STREAM_ALARM) <- require API28+ + val maxVolume = this.getStreamMaxVolume(AudioManager.STREAM_ALARM) + if (keyCode == KeyEvent.KEYCODE_VOLUME_DOWN) { + this.setStreamVolume(AudioManager.STREAM_ALARM, max(currentVolume - 1, minVolume), AudioManager.FLAG_SHOW_UI) + + } else if (keyCode == KeyEvent.KEYCODE_VOLUME_UP){ + this.setStreamVolume(AudioManager.STREAM_ALARM, min(currentVolume + 1, maxVolume), AudioManager.FLAG_SHOW_UI) + } else { + + } + } + + } + view.isFocusableInTouchMode = true; + view.requestFocus(); + view.setOnKeyListener { _, i, event -> + if (i == KeyEvent.KEYCODE_VOLUME_DOWN || i == KeyEvent.KEYCODE_VOLUME_UP) { + adjustAlarmVolume(i) + true + } else { + false + } + } + } + + override fun onCreatePreferences(savedInstanceState: Bundle?, rootKey: String?) { + setPreferencesFromResource(R.xml.alarm_adjust_volume_preferences, rootKey) + + val alarmVolumeSeekBar = findPreference("alarmVolume") + alarmVolumeSeekBar?.apply { + min = 0 + max = 100 + updatesContinuously = true + setOnPreferenceChangeListener { _, newValue -> + actionOnService(Actions.VOLUME, newValue as Int) + true + } + } + + } + + + private fun actionOnService(a: Actions, v: Int = 0) + { + val i = Intent(requireContext(), RadioService::class.java) + i.putExtra("action", a.name) + i.putExtra("value", v) + //[REMOVE LOG CALLS]Log.d(tag, "Sending intent ${a.name}") + requireContext().startService(i) + } + +} \ No newline at end of file diff --git a/app/src/main/java/fr/forum_thalie/tsumugi/preferences/AlarmFragment.kt b/app/src/main/java/fr/forum_thalie/tsumugi/preferences/AlarmFragment.kt index cfd55cc..ceb2a38 100644 --- a/app/src/main/java/fr/forum_thalie/tsumugi/preferences/AlarmFragment.kt +++ b/app/src/main/java/fr/forum_thalie/tsumugi/preferences/AlarmFragment.kt @@ -143,88 +143,10 @@ class AlarmFragment : PreferenceFragmentCompat() { true } - - val testAlarmVolume: Preference? = findPreference("testAlarmVolume") - testAlarmVolume!!.onPreferenceClickListener = Preference.OnPreferenceClickListener { - - // get previous state: if it's playing, we'll resume playing as multimedia; if it was stopped, we'll stop - val isPlayingMultimedia: Boolean = PlayerStore.instance.isPlaying.value ?: false - - val builder1 = AlertDialog.Builder(requireContext()) - builder1.setTitle(R.string.test_alarm_volume) - builder1.setMessage(R.string.popupTestAlarmVolume) - builder1.setCancelable(false) - builder1.setPositiveButton( - getString(R.string.finished) - ) { dialog, _ -> - // put the radio back to media sound, or off if it was off. - if (isPlayingMultimedia) - { - actionOnService(Actions.PLAY) - } else { - actionOnService(Actions.STOP) - } - dialog.cancel() - } - - val adjustAlarmVolume: (Int) -> Unit = debounce(50, coroutineContext) { - val keyCode = it - - val audioManager = requireContext().getSystemService(Context.AUDIO_SERVICE) as AudioManager - val currentVolume = audioManager.getStreamVolume(AudioManager.STREAM_ALARM) - val minVolume = 0 // audioManager.getStreamMinVolume(AudioManager.STREAM_ALARM) <- require API28+ - val maxVolume = audioManager.getStreamMaxVolume(AudioManager.STREAM_ALARM) - Log.d(tag, "current, max = $currentVolume, $maxVolume") - if (keyCode == KeyEvent.KEYCODE_VOLUME_DOWN) { - audioManager.setStreamVolume(AudioManager.STREAM_ALARM, max(currentVolume - 1, minVolume), AudioManager.FLAG_SHOW_UI) - - } else if (keyCode == KeyEvent.KEYCODE_VOLUME_UP){ - audioManager.setStreamVolume(AudioManager.STREAM_ALARM, min(currentVolume + 1, maxVolume), AudioManager.FLAG_SHOW_UI) - } - - } - - builder1.setOnKeyListener { dialogInterface, i, event -> - adjustAlarmVolume(i) - true - } - - val alert11 = builder1.create() - - // start as alarm - actionOnService(Actions.PLAY_OR_FALLBACK) - - alert11.show() - - true - } - alarmDays?.isEnabled = isWakingUp?.isChecked ?: false timeSet?.isEnabled = isWakingUp?.isChecked ?: false snoozeDuration?.isEnabled = isWakingUp?.isChecked ?: false } - private fun actionOnService (a: Actions) { - // start as alarm - val i = Intent(requireContext(), RadioService::class.java) - i.putExtra("action", a.name) - requireContext().startService(i) - } - - private fun debounce(delayMs: Long = 500L, - coroutineContext: CoroutineContext, - f: (T) -> Unit): (T) -> Unit { - var debounceJob: Job? = null - return { param: T -> - if (debounceJob?.isCompleted != false) { - debounceJob = CoroutineScope(coroutineContext).launch { - delay(delayMs) - f(param) - } - } - } - } - - } \ No newline at end of file diff --git a/app/src/main/java/fr/forum_thalie/tsumugi/ui/nowplaying/NowPlayingFragment.kt b/app/src/main/java/fr/forum_thalie/tsumugi/ui/nowplaying/NowPlayingFragment.kt index 1e306ac..fdb24c1 100644 --- a/app/src/main/java/fr/forum_thalie/tsumugi/ui/nowplaying/NowPlayingFragment.kt +++ b/app/src/main/java/fr/forum_thalie/tsumugi/ui/nowplaying/NowPlayingFragment.kt @@ -166,10 +166,10 @@ class NowPlayingFragment : Fragment() { } }) - - seekBarVolume.setOnSeekBarChangeListener(nowPlayingViewModel.seekBarChangeListener) seekBarVolume.progress = PlayerStore.instance.volume.value!! - progressBar.max = 1000 + seekBarVolume.setOnSeekBarChangeListener(nowPlayingViewModel.seekBarChangeListener) + + progressBar.max = 100 progressBar.progress = 0 syncPlayPauseButtonImage(root) diff --git a/app/src/main/res/values-fr/strings.xml b/app/src/main/res/values-fr/strings.xml index 9e99285..6650dd4 100644 --- a/app/src/main/res/values-fr/strings.xml +++ b/app/src/main/res/values-fr/strings.xml @@ -58,7 +58,11 @@ Paramètres Tester et ajuster le volume de l\'alarme Touchez pour écouter et régler le volume - La radio est à présent lancée en mode alarme. Ajustez le volume avec les boutons de volume de votre appareil. + La radio est à présent lancée en mode alarme. Ajustez le volume avec les boutons de volume de votre appareil. Vous pouvez faire un réglage plus fin du volume avec la réglette ci-dessous. Terminé + Ajuster le volume de l\'alarme + Régler le volume de l\'alarme + Volume de l\'alarme + diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index ee12429..8fcad32 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -78,7 +78,10 @@ Settings Test and change alarm volume Touch this to listen to the alarm volume and set it up - The radio stream is now started in alarm mode. Adjust the volume with the volume buttons on your device. + The radio stream is now started in alarm mode. Adjust the volume with the volume buttons on your device. You can make a finer adjustment of the volume with the slider below. Done + Adjust alarm volume + Set up alarm volume + Alarm volume diff --git a/app/src/main/res/xml/alarm_adjust_volume_preferences.xml b/app/src/main/res/xml/alarm_adjust_volume_preferences.xml new file mode 100644 index 0000000..7e336af --- /dev/null +++ b/app/src/main/res/xml/alarm_adjust_volume_preferences.xml @@ -0,0 +1,23 @@ + + + + + + + + \ No newline at end of file diff --git a/app/src/main/res/xml/alarm_preferences.xml b/app/src/main/res/xml/alarm_preferences.xml index 75c5abf..cfd50d6 100644 --- a/app/src/main/res/xml/alarm_preferences.xml +++ b/app/src/main/res/xml/alarm_preferences.xml @@ -38,9 +38,12 @@ /> + android:summary="@string/test_alarm_volume_summary" + app:icon="@drawable/ic_volume_high" + app:fragment="fr.forum_thalie.tsumugi.preferences.AlarmAdjustVolumeFragment" + /> \ No newline at end of file