소스 검색

Merge branch 'devel'

yattoz 2 년 전
부모
커밋
7ea4d6ed67

+ 0 - 3
.idea/codeStyles/Project.xml 파일 보기

1
 <component name="ProjectCodeStyleConfiguration">
1
 <component name="ProjectCodeStyleConfiguration">
2
   <code_scheme name="Project" version="173">
2
   <code_scheme name="Project" version="173">
3
-    <AndroidXmlCodeStyleSettings>
4
-      <option name="ARRANGEMENT_SETTINGS_MIGRATED_TO_191" value="true" />
5
-    </AndroidXmlCodeStyleSettings>
6
     <JetCodeStyleSettings>
3
     <JetCodeStyleSettings>
7
       <option name="CODE_STYLE_DEFAULTS" value="KOTLIN_OFFICIAL" />
4
       <option name="CODE_STYLE_DEFAULTS" value="KOTLIN_OFFICIAL" />
8
     </JetCodeStyleSettings>
5
     </JetCodeStyleSettings>

+ 0 - 12
.idea/runConfigurations.xml 파일 보기

1
-<?xml version="1.0" encoding="UTF-8"?>
2
-<project version="4">
3
-  <component name="RunConfigurationProducerService">
4
-    <option name="ignoredProducers">
5
-      <set>
6
-        <option value="org.jetbrains.plugins.gradle.execution.test.runner.AllInPackageGradleConfigurationProducer" />
7
-        <option value="org.jetbrains.plugins.gradle.execution.test.runner.TestClassGradleConfigurationProducer" />
8
-        <option value="org.jetbrains.plugins.gradle.execution.test.runner.TestMethodGradleConfigurationProducer" />
9
-      </set>
10
-    </option>
11
-  </component>
12
-</project>

+ 5 - 5
app/build.gradle 파일 보기

16
 }
16
 }
17
 
17
 
18
 android {
18
 android {
19
-    compileSdkVersion 29
20
-    buildToolsVersion "29.0.2"
19
+    compileSdkVersion 30
20
+    buildToolsVersion "30.0.1"
21
     compileOptions {
21
     compileOptions {
22
         sourceCompatibility JavaVersion.VERSION_1_8
22
         sourceCompatibility JavaVersion.VERSION_1_8
23
         targetCompatibility JavaVersion.VERSION_1_8
23
         targetCompatibility JavaVersion.VERSION_1_8
28
     defaultConfig {
28
     defaultConfig {
29
         applicationId "fr.forum_thalie.tsumugi"
29
         applicationId "fr.forum_thalie.tsumugi"
30
         minSdkVersion 16
30
         minSdkVersion 16
31
-        targetSdkVersion 29
32
-        versionCode 115
33
-        versionName "1.1.5"
31
+        targetSdkVersion 30
32
+        versionCode 120
33
+        versionName "1.2.0"
34
         testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
34
         testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
35
         vectorDrawables.useSupportLibrary = true
35
         vectorDrawables.useSupportLibrary = true
36
     }
36
     }

+ 3 - 2
app/src/main/AndroidManifest.xml 파일 보기

13
     <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
13
     <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
14
     <uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
14
     <uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
15
     <uses-permission android:name="android.permission.SET_ALARM"/>
15
     <uses-permission android:name="android.permission.SET_ALARM"/>
16
+    <uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED"/>
16
 
17
 
17
     <application
18
     <application
18
         android:allowBackup="true"
19
         android:allowBackup="true"
26
         <service
27
         <service
27
             android:name=".RadioService"
28
             android:name=".RadioService"
28
             android:enabled="true"
29
             android:enabled="true"
29
-            android:exported="true">
30
+            android:exported="false">
30
             <intent-filter>
31
             <intent-filter>
31
                 <action android:name="android.media.browse.MediaBrowserService" />
32
                 <action android:name="android.media.browse.MediaBrowserService" />
32
             </intent-filter>
33
             </intent-filter>
60
             android:configChanges="orientation|screenSize"
61
             android:configChanges="orientation|screenSize"
61
             android:launchMode="singleTask"
62
             android:launchMode="singleTask"
62
             android:parentActivityName=".MainActivity"
63
             android:parentActivityName=".MainActivity"
63
-            android:screenOrientation="fullSensor" />
64
+            android:screenOrientation="fullUser" />
64
 
65
 
65
         <receiver android:name="androidx.media.session.MediaButtonReceiver">
66
         <receiver android:name="androidx.media.session.MediaButtonReceiver">
66
             <intent-filter>
67
             <intent-filter>

+ 1 - 1
app/src/main/assets/planning_example.json 파일 보기

1
 {
1
 {
2
   "planning": [
2
   "planning": [
3
     {
3
     {
4
-      "title": "Musique Classique",
4
+      "title": "Le Classique du Matin",
5
       "periodicity": "1111111",
5
       "periodicity": "1111111",
6
       "hour_begin": "6:00",
6
       "hour_begin": "6:00",
7
       "hour_end": "7:00"
7
       "hour_end": "7:00"

+ 1 - 1
app/src/main/java/fr/forum_thalie/tsumugi/MainActivity.kt 파일 보기

117
         }
117
         }
118
     }
118
     }
119
 
119
 
120
-    override fun onRestoreInstanceState(savedInstanceState: Bundle?) {
120
+    override fun onRestoreInstanceState(savedInstanceState: Bundle) {
121
         super.onRestoreInstanceState(savedInstanceState ?: Bundle())
121
         super.onRestoreInstanceState(savedInstanceState ?: Bundle())
122
         // Now that BottomNavigationBar has restored its instance state
122
         // Now that BottomNavigationBar has restored its instance state
123
         // and its selectedItemId, we can proceed with setting up the
123
         // and its selectedItemId, we can proceed with setting up the

+ 6 - 6
app/src/main/java/fr/forum_thalie/tsumugi/RadioService.kt 파일 보기

454
     // this function is playing the stream if available, or a default sound if there's a problem.
454
     // this function is playing the stream if available, or a default sound if there's a problem.
455
     private fun beginPlayingOrFallback()
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
         beginPlaying(isRinging = true, isFallback = false)
459
         beginPlaying(isRinging = true, isFallback = false)
459
         val wait: (Any?) -> Any = {
460
         val wait: (Any?) -> Any = {
460
             /*
461
             /*
461
             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
             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
             isAlarmStopped = false // reset the flag
465
             isAlarmStopped = false // reset the flag
465
             var i = 0
466
             var i = 0
498
                 .setUsage(C.USAGE_ALARM)
499
                 .setUsage(C.USAGE_ALARM)
499
                 .build()
500
                 .build()
500
         } else {
501
         } else {
502
+            isAlarmStopped = true // if we're not ringing and it tries playing, it means the user opened the app somehow
501
             audioAttributes.setUsage(AudioAttributesCompat.USAGE_MEDIA)
503
             audioAttributes.setUsage(AudioAttributesCompat.USAGE_MEDIA)
502
             audioFocusRequestBuilder.setAudioAttributes(audioAttributes.build())
504
             audioFocusRequestBuilder.setAudioAttributes(audioAttributes.build())
503
             audioFocusRequest = audioFocusRequestBuilder.build()
505
             audioFocusRequest = audioFocusRequestBuilder.build()
513
             return
515
             return
514
         }
516
         }
515
 
517
 
516
-        if (mediaSession.controller.playbackState.state == PlaybackStateCompat.STATE_PLAYING && !isRinging)
517
-            return // nothing to do here
518
         PlayerStore.instance.playbackState.value = PlaybackStateCompat.STATE_PLAYING
518
         PlayerStore.instance.playbackState.value = PlaybackStateCompat.STATE_PLAYING
519
 
519
 
520
         // Reinitialize media player. Otherwise the playback doesn't resume when beginPlaying. Dunno why.
520
         // Reinitialize media player. Otherwise the playback doesn't resume when beginPlaying. Dunno why.
530
         }
530
         }
531
 
531
 
532
         // START PLAYBACK, LET'S ROCK
532
         // START PLAYBACK, LET'S ROCK
533
-        player.playWhenReady = true
534
         nowPlayingNotification.update(this, isUpdatingNotificationButton =  true, isRinging = isRinging)
533
         nowPlayingNotification.update(this, isUpdatingNotificationButton =  true, isRinging = isRinging)
535
 
534
 
536
         playbackStateBuilder.setState(
535
         playbackStateBuilder.setState(
540
             SystemClock.elapsedRealtime()
539
             SystemClock.elapsedRealtime()
541
         )
540
         )
542
         mediaSession.setPlaybackState(playbackStateBuilder.build())
541
         mediaSession.setPlaybackState(playbackStateBuilder.build())
542
+        player.playWhenReady = true
543
+
543
         //[REMOVE LOG CALLS]Log.d(tag, radioTag + "begin playing")
544
         //[REMOVE LOG CALLS]Log.d(tag, radioTag + "begin playing")
544
     }
545
     }
545
 
546
 
553
     {
554
     {
554
         if (mediaSession.controller.playbackState.state == PlaybackStateCompat.STATE_STOPPED)
555
         if (mediaSession.controller.playbackState.state == PlaybackStateCompat.STATE_STOPPED)
555
             return // nothing to do here
556
             return // nothing to do here
556
-
557
         if (PlayerStore.instance.playbackState.value == PlaybackStateCompat.STATE_PLAYING)
557
         if (PlayerStore.instance.playbackState.value == PlaybackStateCompat.STATE_PLAYING)
558
             isAlarmStopped = true
558
             isAlarmStopped = true
559
 
559
 

+ 129 - 0
app/src/main/java/fr/forum_thalie/tsumugi/preferences/AlarmAdjustVolumeFragment.kt 파일 보기

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
+}

+ 14 - 2
app/src/main/java/fr/forum_thalie/tsumugi/preferences/AlarmFragment.kt 파일 보기

2
 
2
 
3
 import android.app.TimePickerDialog
3
 import android.app.TimePickerDialog
4
 import android.content.Context
4
 import android.content.Context
5
+import android.content.Intent
6
+import android.media.AudioManager
5
 import android.os.Bundle
7
 import android.os.Bundle
6
 import android.util.Log
8
 import android.util.Log
9
+import android.view.KeyEvent
10
+import androidx.appcompat.app.AlertDialog
7
 import androidx.appcompat.app.AppCompatActivity
11
 import androidx.appcompat.app.AppCompatActivity
8
 import androidx.core.content.edit
12
 import androidx.core.content.edit
9
 import androidx.preference.*
13
 import androidx.preference.*
10
 import fr.forum_thalie.tsumugi.*
14
 import fr.forum_thalie.tsumugi.*
11
 import fr.forum_thalie.tsumugi.R
15
 import fr.forum_thalie.tsumugi.R
12
 import fr.forum_thalie.tsumugi.alarm.RadioAlarm
16
 import fr.forum_thalie.tsumugi.alarm.RadioAlarm
17
+import fr.forum_thalie.tsumugi.playerstore.PlayerStore
18
+import kotlinx.coroutines.CoroutineScope
19
+import kotlinx.coroutines.GlobalScope.coroutineContext
20
+import kotlinx.coroutines.Job
21
+import kotlinx.coroutines.delay
22
+import kotlinx.coroutines.launch
13
 import java.util.*
23
 import java.util.*
24
+import kotlin.coroutines.CoroutineContext
25
+import kotlin.math.max
26
+import kotlin.math.min
27
+
14
 
28
 
15
 class AlarmFragment : PreferenceFragmentCompat() {
29
 class AlarmFragment : PreferenceFragmentCompat() {
16
 
30
 
129
             true
143
             true
130
         }
144
         }
131
 
145
 
132
-
133
         alarmDays?.isEnabled = isWakingUp?.isChecked ?: false
146
         alarmDays?.isEnabled = isWakingUp?.isChecked ?: false
134
         timeSet?.isEnabled = isWakingUp?.isChecked ?: false
147
         timeSet?.isEnabled = isWakingUp?.isChecked ?: false
135
         snoozeDuration?.isEnabled = isWakingUp?.isChecked ?: false
148
         snoozeDuration?.isEnabled = isWakingUp?.isChecked ?: false
136
 
149
 
137
     }
150
     }
138
 
151
 
139
-
140
 }
152
 }

+ 3 - 3
app/src/main/java/fr/forum_thalie/tsumugi/ui/nowplaying/NowPlayingFragment.kt 파일 보기

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

+ 4 - 0
app/src/main/res/drawable/none.xml 파일 보기

1
+<?xml version="1.0" encoding="utf-8"?>
2
+<selector xmlns:android="http://schemas.android.com/apk/res/android">
3
+
4
+</selector>

+ 8 - 0
app/src/main/res/values-fr/strings.xml 파일 보기

56
     <string name="action_refresh">Raffraîchir les données</string>
56
     <string name="action_refresh">Raffraîchir les données</string>
57
     <string name="autoPlay">\"Play\" au branchement de la prise casque</string>
57
     <string name="autoPlay">\"Play\" au branchement de la prise casque</string>
58
     <string name="settings">Paramètres</string>
58
     <string name="settings">Paramètres</string>
59
+    <string name="test_alarm_volume">Tester et ajuster le volume de l\'alarme</string>
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. Vous pouvez faire un réglage plus fin du volume avec la réglette ci-dessous.</string>
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
+
59
 
67
 
60
 </resources>
68
 </resources>

+ 7 - 0
app/src/main/res/values/strings.xml 파일 보기

76
     <string name="action_refresh">Refresh data</string>
76
     <string name="action_refresh">Refresh data</string>
77
     <string name="autoPlay">Auto play when plugging headphones</string>
77
     <string name="autoPlay">Auto play when plugging headphones</string>
78
     <string name="settings">Settings</string>
78
     <string name="settings">Settings</string>
79
+    <string name="test_alarm_volume">Test and change alarm volume</string>
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. You can make a finer adjustment of the volume with the slider below.</string>
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>
79
 
86
 
80
 </resources>
87
 </resources>

+ 8 - 2
app/src/main/res/values/styles.xml 파일 보기

11
         <item name="android:colorBackground">@color/colorPrimaryDark</item>
11
         <item name="android:colorBackground">@color/colorPrimaryDark</item>
12
     </style>
12
     </style>
13
 
13
 
14
-    <style name="AppTheme.Parameters" parent="AppTheme">
15
-        <item name="icon"/>
14
+    <style name="AppTheme.Parameters" parent="Theme.AppCompat.NoActionBar">
15
+        <!-- Customize your theme here. -->
16
+        <item name="colorPrimary">@color/colorPrimary</item>
17
+        <item name="colorPrimaryDark">@color/colorPrimaryDark</item>
18
+        <item name="colorAccent">@color/colorAccent</item>
19
+        <item name="android:textColorHighlight">@color/rblue</item>
20
+        <item name="android:colorBackground">@color/colorPrimaryDark</item>
21
+        <item name="icon">@drawable/none</item>
16
     </style>
22
     </style>
17
 
23
 
18
     <style name="AppTheme.BottomBar" parent="AppTheme">
24
     <style name="AppTheme.BottomBar" parent="AppTheme">

+ 23 - 0
app/src/main/res/xml/alarm_adjust_volume_preferences.xml 파일 보기

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>

+ 9 - 0
app/src/main/res/xml/alarm_preferences.xml 파일 보기

37
         android:summary="%s"
37
         android:summary="%s"
38
         />
38
         />
39
 
39
 
40
+    <Preference
41
+        app:iconSpaceReserved="true"
42
+        android:key="testAlarmVolume"
43
+        android:title="@string/test_alarm_volume"
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
+        />
48
+
40
 </PreferenceScreen>
49
 </PreferenceScreen>

+ 2 - 3
app/src/main/res/xml/preferences.xml 파일 보기

1
 <?xml version="1.0" encoding="utf-8"?>
1
 <?xml version="1.0" encoding="utf-8"?>
2
-<PreferenceScreen
3
-    xmlns:app="http://schemas.android.com/apk/res-auto"
4
-    >
2
+<PreferenceScreen xmlns:app="http://schemas.android.com/apk/res-auto"
3
+    xmlns:android="http://schemas.android.com/apk/res/android">
5
 
4
 
6
     <Preference
5
     <Preference
7
         app:icon="@drawable/ic_alarm"
6
         app:icon="@drawable/ic_alarm"

+ 2 - 2
build.gradle 파일 보기

1
 // Top-level build file where you can add configuration options common to all sub-projects/modules.
1
 // Top-level build file where you can add configuration options common to all sub-projects/modules.
2
 
2
 
3
 buildscript {
3
 buildscript {
4
-    ext.kotlin_version = '1.3.61'
4
+    ext.kotlin_version = '1.3.72'
5
     repositories {
5
     repositories {
6
         google()
6
         google()
7
         jcenter()
7
         jcenter()
8
     }
8
     }
9
     dependencies {
9
     dependencies {
10
-        classpath 'com.android.tools.build:gradle:3.5.3'
10
+        classpath 'com.android.tools.build:gradle:4.0.1'
11
         classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version"
11
         classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version"
12
         // NOTE: Do not place your application dependencies here; they belong
12
         // NOTE: Do not place your application dependencies here; they belong
13
         // in the individual module build.gradle files
13
         // in the individual module build.gradle files

+ 2 - 2
gradle/wrapper/gradle-wrapper.properties 파일 보기

1
-#Sun Oct 13 11:20:35 CEST 2019
1
+#Sat Aug 08 18:44:30 CEST 2020
2
 distributionBase=GRADLE_USER_HOME
2
 distributionBase=GRADLE_USER_HOME
3
 distributionPath=wrapper/dists
3
 distributionPath=wrapper/dists
4
 zipStoreBase=GRADLE_USER_HOME
4
 zipStoreBase=GRADLE_USER_HOME
5
 zipStorePath=wrapper/dists
5
 zipStorePath=wrapper/dists
6
-distributionUrl=https\://services.gradle.org/distributions/gradle-5.4.1-all.zip
6
+distributionUrl=https\://services.gradle.org/distributions/gradle-6.1.1-all.zip