You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.06 09:59:52