Skip to content

Commit cdd81b7

Browse files
author
Maximilian Häming
authored
Merge pull request #5 from StudyProject-NLI/lara
refactoring, basic TTS and STT functionalities
2 parents 635fa84 + 7576efa commit cdd81b7

24 files changed

Lines changed: 1228 additions & 377 deletions

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

Lines changed: 137 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,9 @@
11
package com.nlinterface.activities
22

3+
import android.content.Intent
34
import android.os.Bundle
5+
import android.speech.tts.TextToSpeech
6+
import android.speech.tts.TextToSpeech.OnInitListener
47
import android.util.Log
58
import android.view.View
69
import android.view.WindowManager
@@ -9,71 +12,84 @@ import android.widget.EditText
912
import android.widget.ImageButton
1013
import androidx.appcompat.app.AlertDialog
1114
import androidx.appcompat.app.AppCompatActivity
12-
import androidx.constraintlayout.widget.ConstraintLayout
15+
import androidx.lifecycle.Observer
1316
import androidx.lifecycle.ViewModelProvider
1417
import androidx.recyclerview.widget.ItemTouchHelper
1518
import androidx.recyclerview.widget.LinearLayoutManager
1619
import androidx.recyclerview.widget.RecyclerView
1720
import com.google.android.material.dialog.MaterialAlertDialogBuilder
18-
import com.google.android.material.dialog.MaterialDialogs
1921
import com.nlinterface.R
2022
import com.nlinterface.adapters.GroceryListAdapter
2123
import com.nlinterface.databinding.ActivityGroceryListBinding
2224
import com.nlinterface.dataclasses.GroceryItem
2325
import com.nlinterface.interfaces.GroceryListCallback
26+
import com.nlinterface.utility.ActivityType
2427
import com.nlinterface.utility.GlobalParameters
28+
import com.nlinterface.utility.TextToSpeechUtility
2529
import com.nlinterface.utility.setViewRelativeSize
2630
import com.nlinterface.viewmodels.GroceryListViewModel
31+
import java.util.Locale
2732

2833

2934
class GroceryListActivity : AppCompatActivity(), GroceryListCallback {
3035

3136
private lateinit var binding: ActivityGroceryListBinding
3237
private lateinit var groceryItemList: ArrayList<GroceryItem>
33-
private lateinit var layout: ConstraintLayout
3438
private lateinit var adapter: GroceryListAdapter
3539
private lateinit var viewModel: GroceryListViewModel
36-
3740
private lateinit var voiceActivationButton: ImageButton
3841

3942
override fun onCreate(savedInstanceState: Bundle?) {
4043
super.onCreate(savedInstanceState)
4144

45+
binding = ActivityGroceryListBinding.inflate(layoutInflater)
46+
setContentView(binding.root)
47+
48+
viewModel = ViewModelProvider(this)[GroceryListViewModel::class.java]
49+
50+
viewModel.fetchGroceryList()
51+
4252
// process keep screen on settings
4353
if (GlobalParameters.instance!!.keepScreenOnSwitch == GlobalParameters.KeepScreenOn.YES) {
4454
window.addFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON)
4555
} else {
4656
window.clearFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON)
4757
}
4858

49-
viewModel = ViewModelProvider(this)[GroceryListViewModel::class.java]
50-
viewModel.fetchGroceryList()
51-
52-
binding = ActivityGroceryListBinding.inflate(layoutInflater)
53-
setContentView(binding.root)
54-
this.layout = findViewById(R.id.activity_grocery_list_cl)
55-
56-
// RecyclerView
57-
val rvGroceryList = findViewById<View>(R.id.grocery_list_rv) as RecyclerView
58-
groceryItemList = viewModel.groceryList
59+
configureUI()
60+
configureTTS()
61+
configureSTT()
62+
}
5963

60-
adapter = GroceryListAdapter(groceryItemList, this)
61-
rvGroceryList.adapter = adapter
62-
rvGroceryList.layoutManager = LinearLayoutManager(this)
64+
private fun configureUI() {
6365

64-
// Add Item Button Listener
66+
// set up add item button listener
6567
val addItemButton: Button = findViewById<View>(R.id.add_item_bt) as Button
6668
addItemButton.setOnClickListener {
6769
onAddItemButtonClick()
6870
}
6971

70-
val voiceActivationButton = findViewById<View>(R.id.voice_activation_bt) as ImageButton
71-
setViewRelativeSize(voiceActivationButton, 1.0, 0.33)
72-
72+
// set up voice activation button listener
73+
voiceActivationButton = findViewById<View>(R.id.voice_activation_bt) as ImageButton
7374
voiceActivationButton.setOnClickListener {
74-
onAddVoiceActivationButtonClick()
75+
onVoiceActivationButtonClick()
7576
}
7677

78+
// resize Voice Activation Button to 1/3 of display size
79+
setViewRelativeSize(voiceActivationButton, 1.0, 0.33)
80+
81+
configureRecyclerView()
82+
}
83+
84+
private fun configureRecyclerView() {
85+
// RecyclerView
86+
val rvGroceryList = findViewById<View>(R.id.grocery_list_rv) as RecyclerView
87+
groceryItemList = viewModel.groceryList
88+
89+
adapter = GroceryListAdapter(groceryItemList, this)
90+
rvGroceryList.adapter = adapter
91+
rvGroceryList.layoutManager = LinearLayoutManager(this)
92+
7793
ItemTouchHelper(object : ItemTouchHelper.SimpleCallback(
7894
0, ItemTouchHelper.LEFT
7995
) {
@@ -92,6 +108,8 @@ class GroceryListActivity : AppCompatActivity(), GroceryListCallback {
92108
viewModel.deleteGroceryItem(groceryItem)
93109

94110
adapter.notifyItemRemoved(index)
111+
112+
viewModel.say(resources.getString(R.string.deleted_ITEMNAME_from_grocery_list, groceryItem.itemName))
95113
}
96114
}).attachToRecyclerView(rvGroceryList)
97115

@@ -113,6 +131,8 @@ class GroceryListActivity : AppCompatActivity(), GroceryListCallback {
113131
viewModel.deleteGroceryItem(groceryItem)
114132

115133
adapter.notifyItemRemoved(index)
134+
135+
viewModel.say(resources.getString(R.string.deleted_ITEMNAME_from_grocery_list, groceryItem.itemName))
116136
}
117137
}).attachToRecyclerView(rvGroceryList)
118138
}
@@ -122,8 +142,84 @@ class GroceryListActivity : AppCompatActivity(), GroceryListCallback {
122142
viewModel.storeGroceryList()
123143
}
124144

125-
private fun onAddVoiceActivationButtonClick() {
126-
Log.println(Log.ASSERT, "GroceryListActivity: onAddVoiceActivationButtonClick", "Button CLicked")
145+
private fun configureTTS() {
146+
147+
viewModel.initTTS()
148+
149+
val ttsInitializedObserver = Observer<Boolean> { _ ->
150+
viewModel.say(resources.getString(R.string.grocery_list))
151+
}
152+
153+
viewModel.ttsInitialized.observe(this, ttsInitializedObserver)
154+
155+
}
156+
157+
private fun configureSTT() {
158+
159+
viewModel.initSTT()
160+
161+
val sttIsListeningObserver = Observer<Boolean> { isListening ->
162+
if (isListening) {
163+
voiceActivationButton.setImageResource(R.drawable.ic_mic_green)
164+
} else {
165+
voiceActivationButton.setImageResource(R.drawable.ic_mic_white)
166+
}
167+
}
168+
169+
viewModel.isListening.observe(this, sttIsListeningObserver)
170+
171+
val commandObserver = Observer<ArrayList<String>> {command ->
172+
executeCommand(command)
173+
}
174+
175+
viewModel.command.observe(this, commandObserver)
176+
177+
}
178+
179+
private fun executeCommand(command: ArrayList<String>?) {
180+
181+
if (command != null && command.size == 3) {
182+
if (command[0] == "GOTO") {
183+
navToActivity(command[1])
184+
} else {
185+
viewModel.say(resources.getString(R.string.choose_activity_to_navigate_to))
186+
}
187+
}
188+
189+
}
190+
191+
private fun navToActivity(activity: String) {
192+
193+
Log.println(Log.DEBUG, "navToActivity", activity)
194+
195+
when (activity) {
196+
197+
ActivityType.GROCERYLIST.toString() -> {
198+
viewModel.say(resources.getString(R.string.grocery_list))
199+
}
200+
201+
ActivityType.MAIN.toString() -> {
202+
val intent = Intent(this, MainActivity::class.java)
203+
this.startActivity(intent)
204+
}
205+
ActivityType.PLACEDETAILS.toString() -> {
206+
val intent = Intent(this, PlaceDetailsActivity::class.java)
207+
this.startActivity(intent)
208+
}
209+
ActivityType.SETTINGS.toString() -> {
210+
val intent = Intent(this, SettingsActivity::class.java)
211+
this.startActivity(intent)
212+
}
213+
214+
}
215+
}
216+
217+
private fun onVoiceActivationButtonClick() {
218+
if (viewModel.isListening.value == false) {
219+
viewModel.handleSpeechBegin()
220+
} else {
221+
viewModel.cancelListening()
222+
}
127223
}
128224

129225
private fun onAddItemButtonClick() {
@@ -142,9 +238,13 @@ class GroceryListActivity : AppCompatActivity(), GroceryListCallback {
142238

143239
viewModel.addGroceryItem(newItemName)
144240
adapter.notifyItemInserted(groceryItemList.size - 1)
241+
242+
viewModel.say(resources.getString(R.string.added_ITEMNAME_to_list, newItemName))
145243
}
146244

147-
setNegativeButton(R.string.cancel) { _, _ -> }
245+
setNegativeButton(R.string.cancel) { _, _ ->
246+
viewModel.say(resources.getString(R.string.cancelled_adding_item))
247+
}
148248
}
149249
// Set other dialog properties
150250
builder.setTitle(R.string.add_new_grocery_item)
@@ -153,14 +253,23 @@ class GroceryListActivity : AppCompatActivity(), GroceryListCallback {
153253
}
154254
alertDialog.window?.setSoftInputMode(WindowManager.LayoutParams.SOFT_INPUT_STATE_VISIBLE);
155255
alertDialog.show()
256+
viewModel.say(resources.getString(R.string.enter_item_to_add))
156257
}
157258

158-
159-
160259
override fun onLongClick(item: GroceryItem) {
161260
val index = groceryItemList.indexOf(item)
162-
viewModel.placeGroceryItemInCart(item)
261+
val inCart = viewModel.placeGroceryItemInCart(item)
163262
adapter.notifyItemChanged(index)
263+
264+
if (inCart) {
265+
viewModel.say(resources.getString(R.string.placed_ITEMNAME_into_cart, item.itemName))
266+
} else {
267+
viewModel.say(resources.getString(R.string.removed_ITEMNAME_from_cart, item.itemName))
268+
}
269+
}
270+
271+
override fun onClick(item: GroceryItem) {
272+
viewModel.say(item.itemName)
164273
}
165274

166275
}

0 commit comments

Comments
 (0)