Skip to content

Commit 42648e0

Browse files
committed
complete voice control functionality for Settings
Changing Screen Settings is still buggy
1 parent cd2b53e commit 42648e0

3 files changed

Lines changed: 257 additions & 34 deletions

File tree

app/src/main/java/com/nlinterface/activities/SettingsActivity.kt

Lines changed: 177 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -14,8 +14,13 @@ import com.nlinterface.R
1414
import com.nlinterface.databinding.ActivitySettingsBinding
1515
import com.nlinterface.utility.ActivityType
1616
import com.nlinterface.utility.GlobalParameters
17+
import com.nlinterface.utility.STTInputType
1718
import com.nlinterface.utility.setViewRelativeSize
1819
import com.nlinterface.viewmodels.SettingsViewModel
20+
import kotlinx.coroutines.CoroutineScope
21+
import kotlinx.coroutines.Dispatchers
22+
import kotlinx.coroutines.Job
23+
import kotlinx.coroutines.launch
1924

2025
/**
2126
* The SettingsActivity handles user interaction in Settings Menu.
@@ -49,6 +54,9 @@ class SettingsActivity : AppCompatActivity() {
4954
private lateinit var themeButton: Button
5055

5156
private lateinit var voiceActivationButton: ImageButton
57+
58+
private lateinit var lastCommand: String
59+
private lateinit var lastResponse: String
5260

5361
/**
5462
* The onCreate Function initializes the view by binding the Activity and the Layout,
@@ -100,7 +108,7 @@ class SettingsActivity : AppCompatActivity() {
100108

101109
keepScreenOnButton = findViewById(R.id.settings_keep_screen_on)
102110
keepScreenOnButton.text =
103-
keepScreenOnOptions[GlobalParameters.instance!!.keepScreenOnSwitch.ordinal]
111+
keepScreenOnOptions[GlobalParameters.instance!!.keepScreenOn.ordinal]
104112

105113
keepScreenOnButton.setOnClickListener {
106114
onKeepScreenOnButtonClick()
@@ -137,19 +145,19 @@ class SettingsActivity : AppCompatActivity() {
137145
private fun onKeepScreenOnButtonClick() {
138146

139147
if (
140-
GlobalParameters.instance!!.keepScreenOnSwitch.ordinal ==
148+
GlobalParameters.instance!!.keepScreenOn.ordinal ==
141149
GlobalParameters.KeepScreenOn.values().size - 1
142150
) {
143-
GlobalParameters.instance!!.keepScreenOnSwitch =
151+
GlobalParameters.instance!!.keepScreenOn =
144152
GlobalParameters.KeepScreenOn.values()[0]
145153
} else {
146-
GlobalParameters.instance!!.keepScreenOnSwitch =
154+
GlobalParameters.instance!!.keepScreenOn =
147155
GlobalParameters.KeepScreenOn.values()[
148-
GlobalParameters.instance!!.keepScreenOnSwitch.ordinal + 1
156+
GlobalParameters.instance!!.keepScreenOn.ordinal + 1
149157
]
150158
}
151159
keepScreenOnButton.text =
152-
keepScreenOnOptions[GlobalParameters.instance!!.keepScreenOnSwitch.ordinal]
160+
keepScreenOnOptions[GlobalParameters.instance!!.keepScreenOn.ordinal]
153161

154162
viewModel.say(resources.getString(R.string.new_screen_setting, keepScreenOnButton.text))
155163
}
@@ -167,7 +175,7 @@ class SettingsActivity : AppCompatActivity() {
167175
with(sharedPref.edit()) {
168176
putString(
169177
getString(R.string.settings_keep_screen_on_key),
170-
GlobalParameters.instance!!.keepScreenOnSwitch.toString()
178+
GlobalParameters.instance!!.keepScreenOn.toString()
171179
)
172180
putString(
173181
getString(R.string.settings_theme_key),
@@ -184,6 +192,7 @@ class SettingsActivity : AppCompatActivity() {
184192
*/
185193
private fun onVoiceActivationButtonClick() {
186194
if (viewModel.isListening.value == false) {
195+
viewModel.setSpeechRecognitionListener(STTInputType.COMMAND)
187196
viewModel.handleSpeechBegin()
188197
} else {
189198
viewModel.cancelListening()
@@ -232,12 +241,22 @@ class SettingsActivity : AppCompatActivity() {
232241
viewModel.isListening.observe(this, sttIsListeningObserver)
233242

234243
// if a command is successfully generated, process and execute it
235-
val commandObserver = Observer<ArrayList<String>> { command ->
244+
val commandObserver = Observer<String> { command ->
245+
lastCommand = command
236246
executeCommand(command)
237247
}
238248

239249
// observe LiveData change to be notified when the STT returns a command
240250
viewModel.command.observe(this, commandObserver)
251+
252+
// if a response is successfully generated, process and execute it
253+
val responseObserver = Observer<String> { response ->
254+
lastResponse = response
255+
executeSettingsCommand(lastCommand, lastResponse)
256+
}
257+
258+
// observe LiveData change to be notified when the STT returns a response
259+
viewModel.response.observe(this, responseObserver)
241260

242261
}
243262

@@ -249,18 +268,152 @@ class SettingsActivity : AppCompatActivity() {
249268
*
250269
* TODO: streamline processing and command structure
251270
*/
252-
private fun executeCommand(command: ArrayList<String>?) {
253-
254-
/*
255-
if ((command != null) && (command.size == 3)) {
256-
if (command[0] == "GOTO") {
257-
navToActivity(command[1])
258-
} else {
259-
viewModel.say(resources.getString(R.string.choose_activity_to_navigate_to))
271+
private fun executeCommand(command: String) {
272+
273+
if (command.contains("go to")) {
274+
executeNavigationCommand(command)
275+
276+
} else if (command == resources.getString(R.string.change_theme)) {
277+
278+
val scope = CoroutineScope(Job() + Dispatchers.Main)
279+
scope.launch {
280+
requestResponse(
281+
resources.getString(R.string.light_theme) + " " +
282+
resources.getString(R.string.dark_theme) +
283+
" or " + resources.getString(R.string.default_theme))
284+
}
285+
286+
} else if (command == resources.getString(R.string.change_screen_settings)) {
287+
288+
val scope = CoroutineScope(Job() + Dispatchers.Main)
289+
scope.launch {
290+
requestResponse(
291+
resources.getString(R.string.keep_screen_always_on) +
292+
" or " + resources.getString(R.string.dim_screen_after_a_while))
260293
}
294+
295+
} else if (command == resources.getString(R.string.tell_me_my_options)) {
296+
297+
viewModel.say(
298+
"${resources.getString(R.string.your_options_are)} " +
299+
"${resources.getString(R.string.add_an_item)}," +
300+
"${resources.getString(R.string.remove_an_item)}," +
301+
"${resources.getString(R.string.add_an_item_to_the_cart)}," +
302+
"${resources.getString(R.string.remove_an_item_from_the_cart)}," +
303+
"${resources.getString(R.string.check_if_an_item_is_on_the_list)}," +
304+
"${resources.getString(R.string.list_all_grocery_items)}," +
305+
"${resources.getString(R.string.list_all_items_not_in_cart)}," +
306+
"${resources.getString(R.string.list_all_items_in_cart)}," +
307+
"${resources.getString(R.string.navigate_to_grocery_list)}," +
308+
"${resources.getString(R.string.navigate_to_place_details)} and" +
309+
"${resources.getString(R.string.navigate_to_settings)}."
310+
)
311+
312+
} else {
313+
viewModel.say(resources.getString(R.string.invalid_command))
261314
}
262-
*/
263-
315+
316+
}
317+
318+
private fun executeSettingsCommand(command: String, response: String) {
319+
320+
if (response != resources.getString(R.string.cancel)) {
321+
322+
when (command) {
323+
324+
resources.getString(R.string.change_theme) -> {
325+
changeTheme(response)
326+
}
327+
328+
resources.getString(R.string.change_screen_settings) -> {
329+
changeScreenSettings(response)
330+
}
331+
332+
}
333+
334+
}
335+
336+
}
337+
338+
private fun changeTheme(response: String) {
339+
340+
when (response) {
341+
342+
resources.getString(R.string.default_theme) -> {
343+
viewModel.setTheme(GlobalParameters.ThemeChoice.SYSTEM_DEFAULT)
344+
viewModel.say(
345+
resources.getString(R.string.new_theme_setting, " default")
346+
)
347+
}
348+
349+
resources.getString(R.string.light_theme) -> {
350+
viewModel.setTheme(GlobalParameters.ThemeChoice.LIGHT)
351+
viewModel.say(
352+
resources.getString(R.string.new_theme_setting, " light theme")
353+
)
354+
}
355+
356+
resources.getString(R.string.dark_theme) -> {
357+
viewModel.setTheme(GlobalParameters.ThemeChoice.DARK)
358+
viewModel.say(
359+
resources.getString(R.string.new_theme_setting, " dark theme")
360+
)
361+
}
362+
363+
}
364+
365+
}
366+
367+
private fun changeScreenSettings(response: String) {
368+
369+
when (response) {
370+
371+
resources.getString(R.string.keep_screen_always_on) -> {
372+
viewModel.setScreenSettings(GlobalParameters.KeepScreenOn.YES)
373+
viewModel.say(
374+
resources.getString(R.string.new_screen_setting,
375+
" keep screen always on")
376+
)
377+
}
378+
379+
resources.getString(R.string.dim_screen_after_a_while) -> {
380+
viewModel.setScreenSettings(GlobalParameters.KeepScreenOn.NO)
381+
viewModel.say(
382+
resources.getString(R.string.new_screen_setting,
383+
" dim screen after a while")
384+
)
385+
}
386+
387+
}
388+
389+
}
390+
391+
/**
392+
* Handles Navigation commands of the format "go to X". If the command is valid, navigate to
393+
* the desired activity.
394+
*
395+
* @param command: String, the command to be executed
396+
*/
397+
private fun executeNavigationCommand(command: String) {
398+
399+
if ((command == resources.getString(R.string.navigate_to_grocery_list))) {
400+
navToActivity(ActivityType.GROCERYLIST)
401+
} else if ((command == resources.getString(R.string.navigate_to_place_details))) {
402+
navToActivity(ActivityType.PLACEDETAILS)
403+
} else if ((command == resources.getString(R.string.navigate_to_settings))) {
404+
navToActivity(ActivityType.SETTINGS)
405+
} else if ((command == resources.getString(R.string.navigate_to_main_menu))) {
406+
navToActivity(ActivityType.MAIN)
407+
} else {
408+
viewModel.say(resources.getString(R.string.invalid_command))
409+
}
410+
411+
}
412+
413+
private suspend fun requestResponse(question: String) {
414+
viewModel.sayAndAwait(question)
415+
viewModel.setSpeechRecognitionListener(STTInputType.ANSWER)
416+
viewModel.handleSpeechBegin()
264417
}
265418

266419
/**
@@ -269,27 +422,27 @@ class SettingsActivity : AppCompatActivity() {
269422
*
270423
* @param activity: ActivityType, Enum specifying the activity
271424
*/
272-
private fun navToActivity(activity: String) {
425+
private fun navToActivity(activity: ActivityType) {
273426

274-
Log.println(Log.DEBUG, "navToActivity", activity)
427+
Log.println(Log.DEBUG, "navToActivity", activity.toString())
275428

276429
when (activity) {
277430

278-
ActivityType.SETTINGS.toString() -> {
431+
ActivityType.SETTINGS -> {
279432
viewModel.say(resources.getString(R.string.settings))
280433
}
281434

282-
ActivityType.MAIN.toString() -> {
435+
ActivityType.MAIN -> {
283436
val intent = Intent(this, MainActivity::class.java)
284437
this.startActivity(intent)
285438
}
286439

287-
ActivityType.GROCERYLIST.toString() -> {
440+
ActivityType.GROCERYLIST -> {
288441
val intent = Intent(this, GroceryListActivity::class.java)
289442
this.startActivity(intent)
290443
}
291444

292-
ActivityType.PLACEDETAILS.toString() -> {
445+
ActivityType.PLACEDETAILS -> {
293446
val intent = Intent(this, PlaceDetailsActivity::class.java)
294447
this.startActivity(intent)
295448
}

0 commit comments

Comments
 (0)