diff --git a/.github/copilot-instructions.md b/.github/copilot-instructions.md new file mode 100644 index 00000000..b38bbf8f --- /dev/null +++ b/.github/copilot-instructions.md @@ -0,0 +1,70 @@ +--- +applyTo: "sdk/src/main/aidl/com/robotemi/sdk/ISdkService.aidl,sdk/src/main/aidl/com/robotemi/sdk/ISdkServiceCallback.aidl" +--- + +# AIDL Interface Compatibility Rules + +### For `sdk/src/main/aidl/com/robotemi/sdk/ISdkService.aidl` and `sdk/src/main/aidl/com/robotemi/sdk/ISdkServiceCallback.aidl` + +**CRITICAL COMPATIBILITY REQUIREMENTS:** + +1. **Adding New Interface Methods:** + - ⚠️ **ALWAYS add new methods at the END of the interface** + - ❌ **NEVER insert methods in the middle of existing methods** + - This maintains binary compatibility with existing implementations + +2. **Extending Existing Method Parameters:** + - ⚠️ **ALWAYS add new parameters at the END of the method signature** + - ❌ **NEVER insert parameters in the middle of existing parameters** + - This ensures backward compatibility with existing callers + +3. **Default Values for New Parameters:** + - `int` parameters: default value is `0` + - `String` parameters: default value is `null` + - `boolean` parameters: default value is `false` + - Always consider the impact of these defaults on existing functionality + +### Examples: + +✅ **CORRECT - Adding new method at the end:** +```aidl +interface ISdkService { + // ... existing methods ... + + // NEW METHOD - added at the end + void newMethod(in String parameter); +} +``` + +❌ **INCORRECT - Adding method in the middle:** +```aidl +interface ISdkService { + void existingMethod1(); + void newMethod(in String parameter); // ❌ BREAKS COMPATIBILITY + void existingMethod2(); +} +``` + +✅ **CORRECT - Extending method parameters at the end:** +```aidl +// Before +void goTo(in String location, int backwards, int noBypass); + +// After - new parameter added at the end +void goTo(in String location, int backwards, int noBypass, in String newParameter); +``` + +❌ **INCORRECT - Adding parameter in the middle:** +```aidl +// ❌ BREAKS COMPATIBILITY +void goTo(in String location, in String newParameter, int backwards, int noBypass); +``` + +### When Making Changes: + +1. Always review the current method order before adding new methods +2. Consider the impact of default values on existing implementations +3. Test compatibility with existing applications +4. Document any breaking changes in release notes + +These rules are essential for maintaining backward compatibility with existing Temi robot applications. diff --git a/gradle.properties b/gradle.properties index 6eb556c4..24cc2a77 100644 --- a/gradle.properties +++ b/gradle.properties @@ -25,7 +25,7 @@ android.defaults.buildfeatures.buildconfig=true android.nonFinalResIds=false GROUP=com.robotemi -VERSION_NAME=1.136.0 +VERSION_NAME=1.137.0.10-SNAPSHOT POM_URL=https://github.com/robotemi/sdk/ POM_SCM_URL=https://github.com/robotemi/sdk/ POM_SCM_CONNECTION=scm:git:git://github.com/robotemi/sdk.git diff --git a/sample/build.gradle b/sample/build.gradle index 26ef3dea..50d1e728 100644 --- a/sample/build.gradle +++ b/sample/build.gradle @@ -6,6 +6,9 @@ repositories { maven { url 'https://oss.sonatype.org/content/repositories/snapshots/' } + maven { + url 'https://central.sonatype.com/repository/maven-snapshots/' + } } android { @@ -63,4 +66,5 @@ dependencies { implementation project(':sdk') // implementation 'com.robotemi:sdk:1.134.1' implementation 'com.google.code.gson:gson:2.9.0' + implementation 'androidx.core:core-ktx:1.8.0' } diff --git a/sample/src/main/java/com/robotemi/sdk/sample/EditDialog.kt b/sample/src/main/java/com/robotemi/sdk/sample/EditDialog.kt new file mode 100644 index 00000000..017d5697 --- /dev/null +++ b/sample/src/main/java/com/robotemi/sdk/sample/EditDialog.kt @@ -0,0 +1,74 @@ +package com.robotemi.sdk.sample + +import android.app.Dialog +import android.content.Context +import android.os.Bundle +import android.view.LayoutInflater +import android.view.View +import android.view.ViewGroup +import android.view.inputmethod.InputMethodManager +import android.widget.BaseAdapter +import android.widget.Button +import android.widget.EditText +import android.widget.ListView +import androidx.core.widget.doAfterTextChanged + +class EditDialog( + context: Context, private val locations: MutableList, + private val editorActionListener: EditorActionListener +) : Dialog(context) { + private lateinit var listView: ListView + private lateinit var confirmBtn: Button + override fun onCreate(savedInstanceState: Bundle?) { + super.onCreate(savedInstanceState) + setContentView(R.layout.dialog_edit_locations) + listView = findViewById(R.id.listView) + val adapter = EditableListAdapter( + context, + locations + ) + listView.adapter = adapter + confirmBtn = findViewById(R.id.confirmBtn) + confirmBtn.setOnClickListener { + editorActionListener.editCompleted(this, adapter.oldText, adapter.newText) + } + } + + override fun dismiss() { + val view = currentFocus + if (view is EditText) { + val imm = context.getSystemService(Context.INPUT_METHOD_SERVICE) as InputMethodManager + imm.hideSoftInputFromWindow(view.windowToken, 0) + } + super.dismiss() + } + class EditableListAdapter( + private val context: Context, + private val dataList: MutableList + ) : BaseAdapter() { + var newText: String = "" + var oldText: String = "" + + override fun getCount(): Int = dataList.size + override fun getItem(position: Int): Any = dataList[position] + override fun getItemId(position: Int): Long = position.toLong() + + override fun getView(position: Int, convertView: View?, parent: ViewGroup): View { + val view = convertView ?: LayoutInflater.from(context) + .inflate(R.layout.item_editable_dialog_row, parent, false) + + val editText = view.findViewById(R.id.name) + editText.setText(dataList[position]) + + editText.doAfterTextChanged { + oldText = dataList[position] + newText = it.toString() + } + return view + } + } + + interface EditorActionListener { + fun editCompleted(editDialog: EditDialog, oldName: String, newName: String) + } +} \ No newline at end of file diff --git a/sample/src/main/java/com/robotemi/sdk/sample/MainActivity.kt b/sample/src/main/java/com/robotemi/sdk/sample/MainActivity.kt index 14ba09fe..004f750e 100644 --- a/sample/src/main/java/com/robotemi/sdk/sample/MainActivity.kt +++ b/sample/src/main/java/com/robotemi/sdk/sample/MainActivity.kt @@ -29,6 +29,9 @@ import android.view.inputmethod.InputMethodManager import android.widget.AdapterView import android.widget.AdapterView.OnItemClickListener import android.widget.ArrayAdapter +import android.widget.Button +import android.widget.EditText +import android.widget.ProgressBar import android.widget.SeekBar import android.widget.SeekBar.OnSeekBarChangeListener import android.widget.Toast @@ -82,6 +85,12 @@ import java.io.IOException import java.util.* import java.util.concurrent.Executors import kotlin.concurrent.thread +import androidx.core.view.isVisible +import androidx.lifecycle.lifecycleScope +import com.robotemi.sdk.map.Layer +import kotlinx.coroutines.Dispatchers +import kotlinx.coroutines.launch +import kotlinx.coroutines.withContext class MainActivity : AppCompatActivity(), NlpListener, OnRobotReadyListener, @@ -98,7 +107,8 @@ class MainActivity : AppCompatActivity(), NlpListener, OnRobotReadyListener, OnMovementVelocityChangedListener, OnMovementStatusChangedListener, OnContinuousFaceRecognizedListener, ITtsService, OnGreetModeStateChangedListener, TextToSpeech.OnInitListener, OnLoadFloorStatusChangedListener, - OnDistanceToDestinationChangedListener, OnSdkExceptionListener, OnRobotDragStateChangedListener, OnMapStatusChangedListener, + OnDistanceToDestinationChangedListener, OnSdkExceptionListener, OnRobotDragStateChangedListener, + OnMapStatusChangedListener, OnButtonStatusChangedListener { private lateinit var robot: Robot @@ -158,7 +168,10 @@ class MainActivity : AppCompatActivity(), NlpListener, OnRobotReadyListener, debugReceiver = TemiBroadcastReceiver() registerReceiver(debugReceiver, IntentFilter(TemiBroadcastReceiver.ACTION_DEBUG)) - registerReceiver(assistantReceiver, IntentFilter(AssistantChangeReceiver.ACTION_ASSISTANT_SELECTION)) + registerReceiver( + assistantReceiver, + IntentFilter(AssistantChangeReceiver.ACTION_ASSISTANT_SELECTION) + ) } /** @@ -442,14 +455,14 @@ class MainActivity : AppCompatActivity(), NlpListener, OnRobotReadyListener, btnGetMapElements.setOnClickListener { if (robot.checkSelfPermission(Permission.MAP) == Permission.GRANTED) { printLog("map elements: ${robot.getMapElements()}") - } else { + } else { printLog("Map permission not granted") } } btnGetMapImage.setOnClickListener { if (robot.checkSelfPermission(Permission.MAP) == Permission.GRANTED) { printLog("map image: ${robot.getMapImage()}") - } else { + } else { printLog("Map permission not granted") } @@ -478,6 +491,24 @@ class MainActivity : AppCompatActivity(), NlpListener, OnRobotReadyListener, btnGetCurrentFloor.setOnClickListener { getCurrentFloor() } + btnNewFloor.setOnClickListener { + showInputDialog("newFloor") + } + btnDeleteFloor.setOnClickListener { + showInputDialog("deleteFloor") + } + btnRenameFloor.setOnClickListener { + showInputDialog("renameFloor") + } + btnGetFloorData.setOnClickListener { + showInputDialog("getFloorData") + } + btnUpdateLocationOnFloor.setOnClickListener { + showInputDialog("updateLocationOnFloor") + } + btnDeleteLocationOnFloor.setOnClickListener { + showInputDialog("deleteLocationOnFloor") + } } groupSettingsAndStatus.apply { btnBatteryInfo.setOnClickListener { getBatteryData() } @@ -541,7 +572,11 @@ class MainActivity : AppCompatActivity(), NlpListener, OnRobotReadyListener, return@setOnClickListener } if (robot.minimumObstacleDistance == -1) { - Toast.makeText(this@MainActivity, "Minimum Obstacle Distance settings is not supported on your robot.", Toast.LENGTH_SHORT).show() + Toast.makeText( + this@MainActivity, + "Minimum Obstacle Distance settings is not supported on your robot.", + Toast.LENGTH_SHORT + ).show() return@setOnClickListener } @@ -551,7 +586,8 @@ class MainActivity : AppCompatActivity(), NlpListener, OnRobotReadyListener, val distance = robot.minimumObstacleDistance textMinimumObstacleDistance.text = "$distance" seekbarMinimumObstacleDistance.progress = distance.coerceIn(0, 100) - seekbarMinimumObstacleDistance.setOnSeekBarChangeListener(object : OnSeekBarChangeListener { + seekbarMinimumObstacleDistance.setOnSeekBarChangeListener(object : + OnSeekBarChangeListener { override fun onProgressChanged( seekBar: SeekBar?, progress: Int, @@ -585,7 +621,10 @@ class MainActivity : AppCompatActivity(), NlpListener, OnRobotReadyListener, printLog("Emergency Stop button status $status") } val eStopListener = object : OnButtonStatusChangedListener { - override fun onButtonStatusChanged(hardButton: HardButton, status: HardButton.Status) { + override fun onButtonStatusChanged( + hardButton: HardButton, + status: HardButton.Status + ) { if (hardButton == HardButton.EMERGENCY_STOP) { printLog("Emergency Stop button status changed: $status") } @@ -710,10 +749,20 @@ class MainActivity : AppCompatActivity(), NlpListener, OnRobotReadyListener, } btnStartPage.setOnClickListener { startPage() } btnGetMembersStatus.setOnClickListener { getMembersStatus() } - btnSerial.setOnClickListener { startActivity(Intent(this@MainActivity, SerialActivity::class.java)) } + btnSerial.setOnClickListener { + startActivity( + Intent( + this@MainActivity, + SerialActivity::class.java + ) + ) + } btnWebpage.setOnClickListener { val intent = - Intent().setClassName("com.robotemi.browser", "com.robotemi.browser.MainActivity") + Intent().setClassName( + "com.robotemi.browser", + "com.robotemi.browser.MainActivity" + ) intent.putExtra("url", "https://github.com") intent.putExtra("source", "intent") intent.putExtra("navBar", "SHOW") @@ -757,6 +806,30 @@ class MainActivity : AppCompatActivity(), NlpListener, OnRobotReadyListener, printLog(robot.getCurrentFloor()?.toString() ?: "Get current floor failed") } + private fun newFloor(name: String) { + printLog(robot.newFloor(name, true)?.toString() ?: "create new floor failed") + } + + private fun deleteFloor(floorId: Int) { + printLog(robot.deleteFloor(floorId)?.toString() ?: "delete floor failed") + } + + private fun renameFloor(floorId: Int, name: String) { + printLog(robot.renameFloor(floorId, name)?.toString() ?: "rename floor failed") + } + + private fun getFloorData(floorId: Int) { + printLog(robot.getFloorAndMapData(floorId)?.toString() ?: "get floor data failed") + } + + private fun updateLocationOnFloor(floorId: Int, oldLocationName: String, newLocationName: String, layer: Layer?) { + printLog(robot.renameLocationOnFloor(floorId, oldLocationName, newLocationName, layer)?.toString() ?: "updateLocationOnFloor floor failed") + } + + private fun deleteLocationOnFloor(floorId: Int, locationName: String) { + printLog(robot.deleteLocationOnFloor(floorId, locationName)?.toString() ?: "deleteLocationOnFloor floor failed") + } + private fun loadFloorAtElevator() { if (floorList.isEmpty()) { getAllFloors() @@ -1048,11 +1121,11 @@ class MainActivity : AppCompatActivity(), NlpListener, OnRobotReadyListener, /** * Have the robot speak while displaying what is being said. */ - private fun speak(askQuestion : Boolean = false) { + private fun speak(askQuestion: Boolean = false) { val text = binding.etSpeak.text.toString() val languages = ArrayList() - TtsRequest.Language.values().forEach { - language -> languages.add(language) + TtsRequest.Language.values().forEach { language -> + languages.add(language) } val adapter = ArrayAdapter(this, R.layout.item_dialog_row, R.id.name, languages) val dialog = AlertDialog.Builder(this) @@ -1066,7 +1139,8 @@ class MainActivity : AppCompatActivity(), NlpListener, OnRobotReadyListener, if (text == "queue") { // A demonstration of using TTS queue - val request = TtsRequest.create("白日依山尽\n", language = TtsRequest.Language.ZH_CN) + val request = + TtsRequest.create("白日依山尽\n", language = TtsRequest.Language.ZH_CN) with(TtsRequest.Language.ZH_CN) { val request1 = request.copy(speech = "黄河入海流\n") val request2 = request.copy(speech = "欲穷千里目\n") @@ -1078,7 +1152,10 @@ class MainActivity : AppCompatActivity(), NlpListener, OnRobotReadyListener, } with(TtsRequest.Language.JA_JP) { - val request1 = request.copy(speech = "古池や\n", language = TtsRequest.Language.JA_JP.value) + val request1 = request.copy( + speech = "古池や\n", + language = TtsRequest.Language.JA_JP.value + ) val request2 = request1.copy(speech = "蛙飛び込む\n") val request3 = request1.copy(speech = "水の音\n") robot.speak(request1) @@ -1087,10 +1164,14 @@ class MainActivity : AppCompatActivity(), NlpListener, OnRobotReadyListener, } with(TtsRequest.Language.EN_US) { - val request1 = request.copy(speech = "It is just as I feared!\n", language = TtsRequest.Language.EN_US.value) + val request1 = request.copy( + speech = "It is just as I feared!\n", + language = TtsRequest.Language.EN_US.value + ) val request2 = request1.copy(speech = "Two Owls and a Hen\n") val request3 = request1.copy(speech = "Four Larks and a Wren\n") - val request4 = request1.copy(speech = "Have all built their nests in my beard.\n") + val request4 = + request1.copy(speech = "Have all built their nests in my beard.\n") robot.speak(request1) robot.speak(request2) robot.speak(request3) @@ -1302,7 +1383,7 @@ class MainActivity : AppCompatActivity(), NlpListener, OnRobotReadyListener, override fun onNlpCompleted(nlpResult: NlpResult) { //do something with nlp result. Base the action specified in the AndroidManifest.xml Toast.makeText(this@MainActivity, nlpResult.action, Toast.LENGTH_SHORT).show() - printLog("NlpCompleted: $nlpResult" ) + printLog("NlpCompleted: $nlpResult") when (nlpResult.action) { ACTION_HOME_WELCOME -> robot.tiltAngle(23) ACTION_HOME_DANCE -> { @@ -1312,6 +1393,7 @@ class MainActivity : AppCompatActivity(), NlpListener, OnRobotReadyListener, robot.skidJoy(0f, 1f) } } + ACTION_HOME_SLEEP -> robot.goTo(HOME_BASE_LOCATION) } } @@ -1436,7 +1518,8 @@ class MainActivity : AppCompatActivity(), NlpListener, OnRobotReadyListener, if (!robot.isSelectedKioskApp()) { return } - val ret = robot.setAsrLanguages(listOf(SttLanguage.SYSTEM, SttLanguage.ZH_HK, SttLanguage.KO_KR)) + val ret = + robot.setAsrLanguages(listOf(SttLanguage.SYSTEM, SttLanguage.ZH_HK, SttLanguage.KO_KR)) printLog("setAsrLanguages: $ret") } @@ -1499,24 +1582,29 @@ class MainActivity : AppCompatActivity(), NlpListener, OnRobotReadyListener, asrResult.equals("Hello", ignoreCase = true) -> { robot.askQuestion("Hello, I'm temi, what can I do for you?") } + asrResult.equals("Play music", ignoreCase = true) -> { robot.finishConversation() robot.speak(create("Okay, please enjoy.", false)) playMusic() } + asrResult.equals("Play movie", ignoreCase = true) -> { robot.finishConversation() robot.speak(create("Okay, please enjoy.", false)) playMovie() } + asrResult.lowercase().contains("follow me") -> { robot.finishConversation() robot.beWithMe() } + asrResult.lowercase().contains("go to home base") -> { robot.finishConversation() robot.goTo("home base") } + else -> { robot.askQuestion("Sorry I can't understand you, could you please ask something else?") } @@ -1585,31 +1673,39 @@ class MainActivity : AppCompatActivity(), NlpListener, OnRobotReadyListener, } else if (requestCode == REQUEST_CODE_FACE_STOP) { robot.stopFaceRecognition() } + Permission.SEQUENCE -> when (requestCode) { REQUEST_CODE_SEQUENCE_FETCH_ALL -> { getAllSequences() } + REQUEST_CODE_SEQUENCE_PLAY -> { playFirstSequence(true) } + REQUEST_CODE_SEQUENCE_PLAY_WITHOUT_PLAYER -> { playFirstSequence(false) } } + Permission.MAP -> when (requestCode) { REQUEST_CODE_MAP -> { getMap() } + REQUEST_CODE_GET_MAP_LIST -> { getMapList() } + REQUEST_CODE_GET_ALL_FLOORS -> { getAllFloors() } } + Permission.SETTINGS -> if (requestCode == REQUEST_CODE_START_DETECTION_WITH_DISTANCE) { startDetectionWithDistance() } + else -> { // no-op } @@ -1699,9 +1795,11 @@ class MainActivity : AppCompatActivity(), NlpListener, OnRobotReadyListener, } printLog("Current go to speed ${robot.goToSpeed}") val speedLevels: MutableList = ArrayList() + speedLevels.add(SpeedLevel.VERY_HIGH.value) speedLevels.add(SpeedLevel.HIGH.value) speedLevels.add(SpeedLevel.MEDIUM.value) speedLevels.add(SpeedLevel.SLOW.value) + speedLevels.add(SpeedLevel.VERY_SLOW.value) val adapter = ArrayAdapter(this, R.layout.item_dialog_row, R.id.name, speedLevels) val dialog = AlertDialog.Builder(this) .setTitle("Select Go To Speed Level") @@ -1807,6 +1905,11 @@ class MainActivity : AppCompatActivity(), NlpListener, OnRobotReadyListener, dialog.listView.onItemClickListener = OnItemClickListener { _: AdapterView<*>?, _: View?, position: Int, _: Long -> robot.volume = adapter.getItem(position)!!.toInt() + +// robot.setVolume(adapter.getItem(position)!!.toInt()) + +// robot.setVolume(adapter.getItem(position)!!.toInt(),true) + printLog("Set volume to ${adapter.getItem(position)}") dialog.dismiss() } @@ -1827,7 +1930,11 @@ class MainActivity : AppCompatActivity(), NlpListener, OnRobotReadyListener, dialog.listView.onItemClickListener = OnItemClickListener { _: AdapterView<*>?, _: View?, position: Int, _: Long -> val result = robot.setMicGainLevel(adapter.getItem(position)!!.toInt()) - printLog("Set Microphone Gain Level to X${adapter.getItem(position)!!.toInt()} with result $result") + printLog( + "Set Microphone Gain Level to X${ + adapter.getItem(position)!!.toInt() + } with result $result" + ) dialog.dismiss() } dialog.show() @@ -1885,6 +1992,14 @@ class MainActivity : AppCompatActivity(), NlpListener, OnRobotReadyListener, } } + override fun onSequenceStepChanged( + sequenceId: String, + stepIndex: Int, + totalSteps: Int + ) { + printLog("onSequenceStepChanged sequenceId: $sequenceId, stepIndex: $stepIndex, totalSteps: $totalSteps") + } + override fun onRobotLifted(isLifted: Boolean, reason: String) { printLog("onRobotLifted: isLifted: $isLifted, reason: $reason") } @@ -2044,6 +2159,7 @@ class MainActivity : AppCompatActivity(), NlpListener, OnRobotReadyListener, 0, 1 -> { printLog("onFaceRecognized: ${contactModel.firstName} ${contactModel.lastName}") } + 2 -> { Log.d( "SAMPLE_DEBUG", @@ -2051,6 +2167,7 @@ class MainActivity : AppCompatActivity(), NlpListener, OnRobotReadyListener, ) printLog("onFaceRecognized: VISITOR ${contactModel.userId} ${contactModel.similarity}") } + 3 -> { Log.d( "SAMPLE_DEBUG", @@ -2058,6 +2175,7 @@ class MainActivity : AppCompatActivity(), NlpListener, OnRobotReadyListener, ) printLog("onFaceRecognized: SDK Face ${contactModel.userId}, ${contactModel.firstName}, similarity ${contactModel.similarity}, age ${contactModel.age}, gender ${contactModel.gender}, faceRect ${contactModel.faceRect}") } + -1 -> { printLog("onFaceRecognized: Unknown face, faceId ${contactModel.userId}, age ${contactModel.age}, gender ${contactModel.gender}, faceRect ${contactModel.faceRect}") } @@ -2090,6 +2208,7 @@ class MainActivity : AppCompatActivity(), NlpListener, OnRobotReadyListener, 0, 1 -> { "$blinker ${contactModel.firstName} ${contactModel.lastName}\n" } + 2 -> { Log.d( "SAMPLE_DEBUG", @@ -2097,6 +2216,7 @@ class MainActivity : AppCompatActivity(), NlpListener, OnRobotReadyListener, ) "$blinker VISITOR ${contactModel.userId} similarity ${contactModel.similarity}\n" } + 3 -> { Log.d( "SAMPLE_DEBUG", @@ -2104,6 +2224,7 @@ class MainActivity : AppCompatActivity(), NlpListener, OnRobotReadyListener, ) "$blinker SDK Face ${contactModel.userId} -> ${contactModel.firstName}, similarity ${contactModel.similarity}\n" } + else -> { "$blinker Unknown face, faceId ${contactModel.userId}, age ${contactModel.age}, gender ${contactModel.gender}, faceRect ${contactModel.faceRect}\n" } @@ -2214,10 +2335,12 @@ class MainActivity : AppCompatActivity(), NlpListener, OnRobotReadyListener, printLog("target is null.") return } - val resp = robot.startMeeting(listOf( - Participant(target.userId, Platform.MOBILE), - Participant(target.userId, Platform.TEMI_CENTER), - ), firstParticipantJoinedAsHost = true) + val resp = robot.startMeeting( + listOf( + Participant(target.userId, Platform.MOBILE), + Participant(target.userId, Platform.TEMI_CENTER), + ), firstParticipantJoinedAsHost = true + ) Log.d("MainActivity", "startMeeting result $resp") } @@ -2629,7 +2752,8 @@ class MainActivity : AppCompatActivity(), NlpListener, OnRobotReadyListener, @SuppressLint("SetTextI18n") override fun onGreetModeStateChanged(state: Int) { - binding.tvGreetMode.text = "Greet Mode -> ${OnGreetModeStateChangedListener.State.fromValue(state)}" + binding.tvGreetMode.text = + "Greet Mode -> ${OnGreetModeStateChangedListener.State.fromValue(state)}" } override fun onLoadFloorStatusChanged(status: Int) { @@ -2651,4 +2775,95 @@ class MainActivity : AppCompatActivity(), NlpListener, OnRobotReadyListener, override fun onButtonStatusChanged(hardButton: HardButton, status: HardButton.Status) { Log.d("onButtonStatusChanged", "hardButton: $hardButton, status: $status") } + + + private fun showInputDialog(type: String) { + val dialogView = layoutInflater.inflate(R.layout.dialog_input_loading, null) + val builder = AlertDialog.Builder(this) + builder.setView(dialogView) + val dialog = builder.create() + val editTextInput = dialogView.findViewById(R.id.editTextInput) + val btnConfirm = dialogView.findViewById