瀏覽代碼

added slider for alarm volume

yattoz 4 年之前
父節點
當前提交
0b7b5dd2f1

+ 2 - 2
app/build.gradle 查看文件

@@ -29,8 +29,8 @@ android {
29 29
         applicationId "fr.forum_thalie.tsumugi"
30 30
         minSdkVersion 16
31 31
         targetSdkVersion 30
32
-        versionCode 115
33
-        versionName "1.1.5"
32
+        versionCode 116
33
+        versionName "1.1.6"
34 34
         testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
35 35
         vectorDrawables.useSupportLibrary = true
36 36
     }

+ 9 - 6
app/src/main/java/fr/forum_thalie/tsumugi/RadioService.kt 查看文件

@@ -454,12 +454,13 @@ class RadioService : MediaBrowserServiceCompat() {
454 454
     // this function is playing the stream if available, or a default sound if there's a problem.
455 455
     private fun beginPlayingOrFallback()
456 456
     {
457
-        PlayerStore.instance.volume.value = 100 // we set the max volume for exoPlayer to be sure it rings correctly.
457
+        PlayerStore.instance.volume.value = PreferenceManager.getDefaultSharedPreferences(this).getInt("alarmVolume", 100)
458
+                // we set the max volume for exoPlayer to be sure it rings correctly.
458 459
         beginPlaying(isRinging = true, isFallback = false)
459 460
         val wait: (Any?) -> Any = {
460 461
             /*
461 462
             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!!)
462
-            If the player stops the alarm (by calling an intent), the isAlarmStopped flag will be raised.
463
+            If the user stops the alarm (by calling an intent), the isAlarmStopped flag will be raised.
463 464
              */
464 465
             isAlarmStopped = false // reset the flag
465 466
             var i = 0
@@ -513,8 +514,11 @@ class RadioService : MediaBrowserServiceCompat() {
513 514
             return
514 515
         }
515 516
 
516
-        if (mediaSession.controller.playbackState.state == PlaybackStateCompat.STATE_PLAYING && !isRinging)
517
-            return // nothing to do here
517
+        // TODO: Remove this
518
+        if (mediaSession.controller.playbackState.state == PlaybackStateCompat.STATE_PLAYING && !isRinging && isAlarmStopped)
519
+             return // nothing to do here
520
+        isAlarmStopped = true
521
+
518 522
         PlayerStore.instance.playbackState.value = PlaybackStateCompat.STATE_PLAYING
519 523
 
520 524
         // Reinitialize media player. Otherwise the playback doesn't resume when beginPlaying. Dunno why.
@@ -554,8 +558,7 @@ class RadioService : MediaBrowserServiceCompat() {
554 558
         if (mediaSession.controller.playbackState.state == PlaybackStateCompat.STATE_STOPPED)
555 559
             return // nothing to do here
556 560
 
557
-        if (PlayerStore.instance.playbackState.value == PlaybackStateCompat.STATE_PLAYING)
558
-            isAlarmStopped = true
561
+        isAlarmStopped = true
559 562
 
560 563
         PlayerStore.instance.playbackState.value = PlaybackStateCompat.STATE_STOPPED
561 564
 

+ 0 - 33
app/src/main/java/fr/forum_thalie/tsumugi/alarm/RadioAlarmExtensions.kt 查看文件

@@ -1,33 +0,0 @@
1
-package fr.forum_thalie.tsumugi.alarm
2
-
3
-import android.content.Context
4
-import android.content.Intent
5
-import fr.forum_thalie.tsumugi.Actions
6
-import fr.forum_thalie.tsumugi.RadioService
7
-
8
-
9
-fun playOnFallback(c: Context) {
10
-    val a = Actions.PLAY_OR_FALLBACK
11
-    val i = Intent(c, RadioService::class.java)
12
-    i.putExtra("action", a.name)
13
-    c.startService(i)
14
-}
15
-
16
-fun resume(c: Context)
17
-{
18
-
19
-}
20
-
21
-fun resumeStop(c: Context) {
22
-    val a = Actions.PLAY
23
-    val i = Intent(c, RadioService::class.java)
24
-    i.putExtra("action", a.name)
25
-    c.startService(i)
26
-}
27
-
28
-fun resumePlay(c: Context) {
29
-    val a = Actions.PLAY
30
-    val i = Intent(c, RadioService::class.java)
31
-    i.putExtra("action", a.name)
32
-    c.startService(i)
33
-}

+ 129 - 0
app/src/main/java/fr/forum_thalie/tsumugi/preferences/AlarmAdjustVolumeFragment.kt 查看文件

@@ -0,0 +1,129 @@
1
+package fr.forum_thalie.tsumugi.preferences
2
+
3
+import android.content.Context
4
+import android.content.Intent
5
+import android.media.AudioManager
6
+import android.os.Bundle
7
+import android.view.KeyEvent
8
+import android.view.LayoutInflater
9
+import android.view.View
10
+import android.view.ViewGroup
11
+import androidx.appcompat.app.AlertDialog
12
+import androidx.appcompat.app.AppCompatActivity
13
+import androidx.preference.PreferenceFragmentCompat
14
+import androidx.preference.PreferenceManager
15
+import androidx.preference.SeekBarPreference
16
+import androidx.preference.SwitchPreferenceCompat
17
+import fr.forum_thalie.tsumugi.Actions
18
+import fr.forum_thalie.tsumugi.R
19
+import fr.forum_thalie.tsumugi.RadioService
20
+import fr.forum_thalie.tsumugi.playerstore.PlayerStore
21
+import kotlinx.coroutines.*
22
+import kotlin.coroutines.CoroutineContext
23
+import kotlin.math.max
24
+import kotlin.math.min
25
+
26
+
27
+class AlarmAdjustVolumeFragment : PreferenceFragmentCompat() {
28
+    override fun onAttach(context: Context) {
29
+        (activity as AppCompatActivity).supportActionBar?.title = context.getString(R.string.test_alarm_volume)
30
+        super.onAttach(context)
31
+    }
32
+
33
+    // get previous state: if it's playing, we'll resume playing as multimedia; if it was stopped, we'll stop
34
+    private var isPlayingMultimedia: Boolean = PlayerStore.instance.isPlaying.value ?: false
35
+
36
+    override fun onStop() {
37
+        if (isPlayingMultimedia)
38
+        {
39
+            actionOnService(Actions.PLAY)
40
+        } else {
41
+            actionOnService(Actions.PAUSE)
42
+        }
43
+        PlayerStore.instance.volume.value = PreferenceManager.getDefaultSharedPreferences(requireContext()).getInt("volume", 100)
44
+        super.onStop()
45
+    }
46
+
47
+    override fun onResume() {
48
+
49
+        isPlayingMultimedia = PlayerStore.instance.isPlaying.value ?: false
50
+        // start as alarm
51
+        actionOnService(Actions.PLAY_OR_FALLBACK)
52
+        super.onResume()
53
+    }
54
+
55
+    override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
56
+        super.onViewCreated(view, savedInstanceState)
57
+
58
+        fun <T> debounce(delayMs: Long = 500L,
59
+                         coroutineContext: CoroutineContext,
60
+                         f: (T) -> Unit): (T) -> Unit {
61
+            var debounceJob: Job? = null
62
+            return { param: T ->
63
+                if (debounceJob?.isCompleted != false) {
64
+                    debounceJob = CoroutineScope(coroutineContext).launch {
65
+                        delay(delayMs)
66
+                        f(param)
67
+                    }
68
+                }
69
+            }
70
+        }
71
+
72
+        val adjustAlarmVolume: (Int) -> Unit = debounce<Int>(50, GlobalScope.coroutineContext) {
73
+            android.util.Log.d(tag, "button $it pushed")
74
+            val keyCode = it
75
+            val audioManager = requireContext().getSystemService(Context.AUDIO_SERVICE) as AudioManager
76
+            audioManager.apply {
77
+                val currentVolume = this.getStreamVolume(AudioManager.STREAM_ALARM)
78
+                val minVolume = 0 // audioManager.getStreamMinVolume(AudioManager.STREAM_ALARM) <- require API28+
79
+                val maxVolume = this.getStreamMaxVolume(AudioManager.STREAM_ALARM)
80
+                if (keyCode == KeyEvent.KEYCODE_VOLUME_DOWN) {
81
+                    this.setStreamVolume(AudioManager.STREAM_ALARM, max(currentVolume - 1, minVolume), AudioManager.FLAG_SHOW_UI)
82
+
83
+                } else if (keyCode == KeyEvent.KEYCODE_VOLUME_UP){
84
+                    this.setStreamVolume(AudioManager.STREAM_ALARM, min(currentVolume + 1, maxVolume), AudioManager.FLAG_SHOW_UI)
85
+                } else {
86
+
87
+                }
88
+            }
89
+
90
+        }
91
+        view.isFocusableInTouchMode = true;
92
+        view.requestFocus();
93
+        view.setOnKeyListener { _, i, event ->
94
+            if (i == KeyEvent.KEYCODE_VOLUME_DOWN || i == KeyEvent.KEYCODE_VOLUME_UP) {
95
+                adjustAlarmVolume(i)
96
+                true
97
+            } else {
98
+                false
99
+            }
100
+        }
101
+    }
102
+
103
+    override fun onCreatePreferences(savedInstanceState: Bundle?, rootKey: String?) {
104
+        setPreferencesFromResource(R.xml.alarm_adjust_volume_preferences, rootKey)
105
+
106
+        val alarmVolumeSeekBar = findPreference<SeekBarPreference>("alarmVolume")
107
+        alarmVolumeSeekBar?.apply {
108
+            min = 0
109
+            max = 100
110
+            updatesContinuously = true
111
+            setOnPreferenceChangeListener { _, newValue ->
112
+                actionOnService(Actions.VOLUME, newValue as Int)
113
+                true
114
+            }
115
+        }
116
+
117
+    }
118
+
119
+
120
+    private fun actionOnService(a: Actions, v: Int = 0)
121
+    {
122
+        val i = Intent(requireContext(), RadioService::class.java)
123
+        i.putExtra("action", a.name)
124
+        i.putExtra("value", v)
125
+        //[REMOVE LOG CALLS]Log.d(tag, "Sending intent ${a.name}")
126
+        requireContext().startService(i)
127
+    }
128
+
129
+}

+ 0 - 78
app/src/main/java/fr/forum_thalie/tsumugi/preferences/AlarmFragment.kt 查看文件

@@ -143,88 +143,10 @@ class AlarmFragment : PreferenceFragmentCompat() {
143 143
             true
144 144
         }
145 145
 
146
-
147
-        val testAlarmVolume: Preference? = findPreference("testAlarmVolume")
148
-        testAlarmVolume!!.onPreferenceClickListener = Preference.OnPreferenceClickListener {
149
-
150
-            // get previous state: if it's playing, we'll resume playing as multimedia; if it was stopped, we'll stop
151
-            val isPlayingMultimedia: Boolean = PlayerStore.instance.isPlaying.value ?: false
152
-
153
-            val builder1 = AlertDialog.Builder(requireContext())
154
-            builder1.setTitle(R.string.test_alarm_volume)
155
-            builder1.setMessage(R.string.popupTestAlarmVolume)
156
-            builder1.setCancelable(false)
157
-            builder1.setPositiveButton(
158
-                getString(R.string.finished)
159
-            ) { dialog, _ ->
160
-                // put the radio back to media sound, or off if it was off.
161
-                if (isPlayingMultimedia)
162
-                {
163
-                    actionOnService(Actions.PLAY)
164
-                } else {
165
-                    actionOnService(Actions.STOP)
166
-                }
167
-                dialog.cancel()
168
-            }
169
-
170
-            val adjustAlarmVolume: (Int) -> Unit = debounce<Int>(50, coroutineContext) {
171
-                val keyCode = it
172
-
173
-                val audioManager = requireContext().getSystemService(Context.AUDIO_SERVICE) as AudioManager
174
-                val currentVolume = audioManager.getStreamVolume(AudioManager.STREAM_ALARM)
175
-                val minVolume = 0 // audioManager.getStreamMinVolume(AudioManager.STREAM_ALARM) <- require API28+
176
-                val maxVolume = audioManager.getStreamMaxVolume(AudioManager.STREAM_ALARM)
177
-                Log.d(tag, "current, max = $currentVolume, $maxVolume")
178
-                if (keyCode == KeyEvent.KEYCODE_VOLUME_DOWN) {
179
-                    audioManager.setStreamVolume(AudioManager.STREAM_ALARM, max(currentVolume - 1, minVolume), AudioManager.FLAG_SHOW_UI)
180
-
181
-                } else if (keyCode == KeyEvent.KEYCODE_VOLUME_UP){
182
-                    audioManager.setStreamVolume(AudioManager.STREAM_ALARM, min(currentVolume + 1, maxVolume), AudioManager.FLAG_SHOW_UI)
183
-                }
184
-
185
-            }
186
-
187
-            builder1.setOnKeyListener { dialogInterface, i, event ->
188
-                adjustAlarmVolume(i)
189
-                true
190
-            }
191
-
192
-            val alert11 = builder1.create()
193
-
194
-            // start as alarm
195
-            actionOnService(Actions.PLAY_OR_FALLBACK)
196
-
197
-            alert11.show()
198
-
199
-            true
200
-        }
201
-
202 146
         alarmDays?.isEnabled = isWakingUp?.isChecked ?: false
203 147
         timeSet?.isEnabled = isWakingUp?.isChecked ?: false
204 148
         snoozeDuration?.isEnabled = isWakingUp?.isChecked ?: false
205 149
 
206 150
     }
207 151
 
208
-    private fun actionOnService (a: Actions) {
209
-        // start as alarm
210
-        val i = Intent(requireContext(), RadioService::class.java)
211
-        i.putExtra("action", a.name)
212
-        requireContext().startService(i)
213
-    }
214
-
215
-    private fun <T> debounce(delayMs: Long = 500L,
216
-                             coroutineContext: CoroutineContext,
217
-                             f: (T) -> Unit): (T) -> Unit {
218
-        var debounceJob: Job? = null
219
-        return { param: T ->
220
-            if (debounceJob?.isCompleted != false) {
221
-                debounceJob = CoroutineScope(coroutineContext).launch {
222
-                    delay(delayMs)
223
-                    f(param)
224
-                }
225
-            }
226
-        }
227
-    }
228
-
229
-
230 152
 }

+ 3 - 3
app/src/main/java/fr/forum_thalie/tsumugi/ui/nowplaying/NowPlayingFragment.kt 查看文件

@@ -166,10 +166,10 @@ class NowPlayingFragment : Fragment() {
166 166
             }
167 167
         })
168 168
 
169
-
170
-        seekBarVolume.setOnSeekBarChangeListener(nowPlayingViewModel.seekBarChangeListener)
171 169
         seekBarVolume.progress = PlayerStore.instance.volume.value!!
172
-        progressBar.max = 1000
170
+        seekBarVolume.setOnSeekBarChangeListener(nowPlayingViewModel.seekBarChangeListener)
171
+
172
+        progressBar.max = 100
173 173
         progressBar.progress = 0
174 174
 
175 175
         syncPlayPauseButtonImage(root)

+ 5 - 1
app/src/main/res/values-fr/strings.xml 查看文件

@@ -58,7 +58,11 @@
58 58
     <string name="settings">Paramètres</string>
59 59
     <string name="test_alarm_volume">Tester et ajuster le volume de l\'alarme</string>
60 60
     <string name="test_alarm_volume_summary">Touchez pour écouter et régler le volume</string>
61
-    <string name="popupTestAlarmVolume">La radio est à présent lancée en mode alarme. Ajustez le volume avec les boutons de volume de votre appareil.</string>
61
+    <string name="popupTestAlarmVolume">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.</string>
62 62
     <string name="finished">Terminé</string>
63
+    <string name="alarmVolumeSeekBar">Ajuster le volume de l\'alarme</string>
64
+    <string name="setupAlarmClockVolume">Régler le volume de l\'alarme</string>
65
+    <string name="alarm_volume">Volume de l\'alarme</string>
66
+
63 67
 
64 68
 </resources>

+ 4 - 1
app/src/main/res/values/strings.xml 查看文件

@@ -78,7 +78,10 @@
78 78
     <string name="settings">Settings</string>
79 79
     <string name="test_alarm_volume">Test and change alarm volume</string>
80 80
     <string name="test_alarm_volume_summary">Touch this to listen to the alarm volume and set it up</string>
81
-    <string name="popupTestAlarmVolume">The radio stream is now started in alarm mode. Adjust the volume with the volume buttons on your device.</string>
81
+    <string name="popupTestAlarmVolume">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.</string>
82 82
     <string name="finished">Done</string>
83
+    <string name="alarmVolumeSeekBar">Adjust alarm volume</string>
84
+    <string name="setupAlarmClockVolume">Set up alarm volume</string>
85
+    <string name="alarm_volume">Alarm volume</string>
83 86
 
84 87
 </resources>

+ 23 - 0
app/src/main/res/xml/alarm_adjust_volume_preferences.xml 查看文件

@@ -0,0 +1,23 @@
1
+<?xml version="1.0" encoding="utf-8"?>
2
+<PreferenceScreen xmlns:android="http://schemas.android.com/apk/res/android"
3
+    xmlns:app="http://schemas.android.com/apk/res-auto">
4
+
5
+    <Preference
6
+        app:key="alarmAdjustText"
7
+        app:iconSpaceReserved="false"
8
+        app:title=""
9
+        android:selectable="false"
10
+        android:persistent="false"
11
+        app:summary="@string/popupTestAlarmVolume"
12
+        app:singleLineTitle="false"
13
+        />
14
+
15
+    <SeekBarPreference
16
+        app:key="alarmVolume"
17
+        app:iconSpaceReserved="false"
18
+        app:title="@string/alarm_volume"
19
+        app:defaultValue="100"
20
+        app:showSeekBarValue="true"
21
+        />
22
+
23
+</PreferenceScreen>

+ 5 - 2
app/src/main/res/xml/alarm_preferences.xml 查看文件

@@ -38,9 +38,12 @@
38 38
         />
39 39
 
40 40
     <Preference
41
-        app:iconSpaceReserved="false"
41
+        app:iconSpaceReserved="true"
42 42
         android:key="testAlarmVolume"
43 43
         android:title="@string/test_alarm_volume"
44
-        android:summary="@string/test_alarm_volume_summary" />
44
+        android:summary="@string/test_alarm_volume_summary"
45
+        app:icon="@drawable/ic_volume_high"
46
+        app:fragment="fr.forum_thalie.tsumugi.preferences.AlarmAdjustVolumeFragment"
47
+        />
45 48
 
46 49
 </PreferenceScreen>