Android平台Pepper应用:向QiChatbot传入EditText用户输入文本的实现
Android平台Pepper应用:EditText输入无法传入QiChatbot的解决方法
我正在开发一款基于Android平台的Pepper应用,用QiChatbot和用户交流矿物相关内容。为适配听障/言语障碍用户,搭建了类似Facebook Messenger的UI,目前能获取并展示Pepper的回复,但无法将EditText中的用户输入字符串传入QiChatbot。
我尝试过以下两种代码,均未成功:
Future<ReplyReaction> replyToFuture = chatbot.async().replyTo(userPhrase, localeEN);
Future<Void> acknowledgeHeardFuture = chatbot.async().acknowledgeHeard(userPhrase,localeEN);
Chat与QiChatbot初始化代码
private QiChatbot buildQiChatbot() { Topic lexicon = TopicBuilder .with(qiContext) .withResource(R.raw.lexicon) .build(); Topic topic_minerals = TopicBuilder .with(qiContext) .withResource(R.raw.topic_minerals) .build(); Topic test = TopicBuilder .with(qiContext) .withResource(R.raw.test_topic) .build(); List<Topic> topicList = new LinkedList<Topic>(); topicList.add(test); //topicList.add(lexicon); //topicList.add(topic_minerals); chatbot = QiChatbotBuilder .with(qiContext) .withTopics(topicList) .withLocale(localeEN) .build(); chatbot.addOnBookmarkReachedListener(bookmark -> { Log.i(TAG, "Bookmark " + bookmark.getName() + " reached."); }); chatbot.addOnEndedListener(endReason -> { Log.i(TAG, "Chatbot ended for reason: " + endReason); chatFuture.requestCancellation(); }); return chatbot; } private Chat buildChat(QiChatbot chatbot) { chat = ChatBuilder .with(qiContext) .withChatbot(chatbot) .build(); chat.addOnStartedListener(() -> { Log.i(TAG, "[CHAT] Chat started."); }); chat.addOnListeningChangedListener(listening -> { if (listening) { Log.i(TAG, "[CHAT] Listening START."); } else { Log.i(TAG, "[CHAT] Listening END."); } }); chat.addOnHeardListener(heardPhrase -> { Log.i(TAG, "[CHAT] Heard phrase: " + heardPhrase.getText()); }); chat.addOnNormalReplyFoundForListener(input -> { Log.i(TAG, "[CHAT] Reply found for user message: " + input.getText()); }); chat.addOnNoPhraseRecognizedListener(() -> { Log.i(TAG, "[CHAT] No phrase recognized."); }); chat.addOnSayingChangedListener(sayingPhrase -> { if (!sayingPhrase.getText().isEmpty()) { Log.i(TAG, "[CHAT] Pepper Reply: " + sayingPhrase.getText()); messageItemList.add(new MessageItem(LayoutRobot, R.drawable.icons8_user_100, sayingPhrase.getText())); messageAdapter.notifyItemInserted(messageItemList.size()); } }); chat.addOnFallbackReplyFoundForListener(input -> { Log.i(TAG, "[CHAT] Fallback Reply found for user message: " + input.getText()); }); chat.addOnNoReplyFoundForListener(input -> { Log.i(TAG, "[CHAT] NO Reply found for user message: " + input.getText()); }); return chat; }
调试尝试1
调整replyTo调用方式后,代码无报错,但输入不在Chatbot Topic中时会捕获错误;若输入能被识别,代码执行但Chatbot未触发任何逻辑(如书签监听):
Future<ReplyReaction> replyFuture = chatbot.async().replyTo(userPhrase, localeEN); replyFuture.thenConsume(future -> { if (future.hasError()) { Log.e(TAG, "Reply Future [ERROR]: " + future.getErrorMessage()); } else { Log.i(TAG, "Reply Future [SUCCESS]: "); ReplyReaction replyReaction = future.get(); ChatbotReaction chatbotReaction = replyReaction.getChatbotReaction(); chatbotReaction.runWith(speechEngine); } });
调试尝试2
链式调用所有操作查看Future状态,日志显示所有Future均已完成,但Chatbot内部仍无响应:
Future<ReplyReaction> replyFuture = chatbot.async().replyTo(userPhrase, localeEN); replyFuture.thenConsume(future -> { if (future.hasError()) { Log.e(TAG, "Reply Reaction Future [ERROR]: " + future.getErrorMessage()); } else if(future.isCancelled()) { Log.i(TAG, "Reply Reaction Future [CANCELED]: "); } else if(future.isDone()) { Log.i(TAG, "Reply Reaction Future [DONE]: "); func1(future); } else if(future.isSuccess()) { Log.i(TAG, "Reply Reaction Future [SUCCESS]: "); func1(future); } });
private void func1(Future<ReplyReaction> replyReactionFuture) throws ExecutionException { ReplyReaction replyReaction = replyReactionFuture.get(); Future<ChatbotReaction> chatbotReactionFuture = replyReaction.async().getChatbotReaction(); chatbotReactionFuture.thenConsume(future -> { if (future.hasError()){ Log.e(TAG, "Chatbot Reaction Future [ERROR]: " + future.getErrorMessage()); } else if(future.isCancelled()) { Log.i(TAG, "Chatbot Reaction Future [CANCELED]: "); } else if(future.isDone()) { Log.i(TAG, "Chatbot Reaction Future [DONE]: "); func2(future); } else if(future.isSuccess()) { Log.i(TAG, "Chatbot Reaction Future [SUCCESS]: "); func2(future); } }); } private void func2(Future<ChatbotReaction> chatbotReactionFuture) throws ExecutionException { ChatbotReaction chatbotReaction = chatbotReactionFuture.get(); Future<Void> runWithFuture = chatbotReaction.async().runWith(speechEngine); runWithFuture.thenConsume(future -> { if (future.hasError()){ Log.e(TAG, "runWith Future [ERROR]: " + future.getErrorMessage()); } else if(future.isDone()) { Log.i(TAG, "runWith Future [DONE]: "); } else if(future.isCancelled()) { Log.i(TAG, "runWith Future [CANCELED]: "); } else if(future.isSuccess()) { Log.i(TAG, "runWith Future [SUCCESS]: "); } }); }
日志输出:
2023-11-17 21:34:56.035 10000-10031/? I/Main Activity: Reply Reaction Future [DONE]: 2023-11-17 21:34:56.044 10000-10030/? I/Main Activity: Chatbot Reaction Future [DONE]: 2023-11-17 21:34:56.068 10000-10031/? I/Main Activity: runWith Future [DONE]:
解决方案
在执行replyTo前先取消当前Chat,执行完成后重新启动Chat即可正常工作。以下是点击事件中的完整代码:
chatFuture.requestCancellation(); Future<ReplyReaction> replyToFuture = chatbot.async().replyTo(userPhrase, localeEN); replyToFuture.thenConsume(replyReactionFuture -> { if (replyReactionFuture.hasError()) { Log.e(TAG, "Reply Reaction Future [ERROR]: " + replyReactionFuture.getErrorMessage()); } else { ReplyReaction replyReaction = replyReactionFuture.get(); Future<ChatbotReaction> getChatbotReactionFuture = replyReaction.async().getChatbotReaction(); getChatbotReactionFuture.thenConsume(chatbotReactionFuture -> { if (chatbotReactionFuture.hasError()){ Log.e(TAG, "Chatbot Reaction Future [ERROR]: " + chatbotReactionFuture.getErrorMessage()); } else { ChatbotReaction chatbotReaction = chatbotReactionFuture.get(); Future<Void> runWithFuture = chatbotReaction.async().runWith(speechEngine); runWithFuture.thenConsume(future -> { if (future.hasError()){ Log.e(TAG, "runWith Future [ERROR]: " + future.getErrorMessage()); } else { chat = buildChat(chatbot); chatFuture = chat.async().run(); chatFuture.thenConsume(future1 -> { if (future1.hasError()) { Log.e(TAG, "Chat finished with error: " + future1.getErrorMessage()); } else { Log.e(TAG, "Chat finished: " + future1.get().toString()); } }); } }); } }); } });
另外,为了在Chat未运行时获取Chatbot的回复,需要在创建SpeechEngine后添加监听:
speechEngine = conversation.makeSpeechEngine(robotContext); speechEngine.addOnSayingChangedListener(phrase -> { String sayingText = phrase.getText(); if (!sayingText.isEmpty()) { Log.i(TAG, "[SPEECH ENGINE] Pepper Reply: " + sayingText); messageItemList.add(new MessageItem(LayoutRobot, R.drawable.ic_pepper_w, sayingText)); runOnUiThread(() -> { messageAdapter.notifyItemInserted(messageAdapter .getItemCount() - 1); recyclerView.scrollToPosition(messageItemList.size() - 1); }); } });
内容的提问来源于stack exchange,提问作者George Karageorgiou
相关产品推荐
相关产品推荐

