在android中使用对话框流程获得对语音输入和文本输入的不同响应

时间:2018-03-11 13:12:59

标签: java android chatbot dialogflow

我正在使用谷歌的对话框流程(API.AI)创建一个Android应用程序聊天机器人。问题是,如果我正在为我的意图发送文本输入,它正在给出正确的响应,而如果我使用语音输入发送相同的内容,则会得到错误的响应。我无法理解问题所在。 这是我的代码: -

public class MyChatActivity extends AppCompatActivity implements View.OnClickListener, AIListener {

    public String TAG = this.getClass().getSimpleName();
    private List<ChatMessageBean> chatList = new ArrayList<>();

    private String CLIENT_ACCESS_TOKEN = "My dialog flow agent's client access token";

    AIConfiguration config;
    AIService aiService;
    AIRequest aiRequest;
    AIDataService aiDataService;

    TextToSpeech textToSpeech;

    RecyclerView chatRecyclerView,menuRecyclerView;
    ChatMessageListAdapter chatMessageListAdapter;
    FloatingActionButton  sendMessageButton,recordMessageButton;
    EditText enterMessage;


    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.my_chat_activity);
        Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar);
        setSupportActionBar(toolbar);
        initializeVariables();
        setListeners();
    }

    public void initializeVariables() {
        config = new AIConfiguration(CLIENT_ACCESS_TOKEN, AIConfiguration.SupportedLanguages.English, AIConfiguration.RecognitionEngine.System);
        aiService = AIService.getService(getApplicationContext(), config);
        aiRequest = new AIRequest();
        aiDataService = new AIDataService(getApplicationContext(), config);
        chatRecyclerView = (RecyclerView) findViewById(R.id.chat_list_recycler_view);
        setMenuRecyclerView();
        enterMessage = (EditText) findViewById(R.id.enter_text_message);
        sendMessageButton = (FloatingActionButton) findViewById(R.id.send_message_button);
        recordMessageButton =(FloatingActionButton) findViewById(R.id.record_message_button);

        textToSpeech = new TextToSpeech(getApplicationContext(),new TextToSpeech.OnInitListener(){
            @Override
            public void onInit(int status) {
                if(status != TextToSpeech.ERROR) {
                    textToSpeech.setLanguage(Locale.US);
                }
            }
        });
    }

    public void setListeners() {
        sendMessageButton.setOnClickListener(this);
        aiService.setListener(this);
    }

    @Override
    public void onClick(View v) {
        switch (v.getId()) {
            case R.id.record_message_button:
                aiService.startListening();
                break;
            case R.id.send_message_button:
                String message = enterMessage.getText().toString().trim();
                enterMessage.setText("");
                sendMessage(message);//sending message with text input
                break;
        }
    }

    private boolean validateMessage(String message) {
        if ((message.equals("")) || (message.isEmpty()) || (message.length() == 0))
            return false;
        return true;
    }

    public void sendMessage(String message) {
        // In this method i am sending the message to dialog flow
        if (validateMessage(message)) {

            ChatMessageBean chatMessageBean = new ChatMessageBean(message); // this is the bean I am using for chatbot app's messages
            chatList.add(chatMessageBean);
            chatMessageListAdapter = new ChatMessageListAdapter(chatList);// this is the adapter for recycler view that I am using for app's messages
            chatRecyclerView.setAdapter(chatMessageListAdapter);
            chatRecyclerView.setLayoutManager(new LinearLayoutManager(this));
            aiRequest.setQuery(message);

            new AsyncTask<AIRequest, Void, AIResponse>() {

                @Override
                protected AIResponse doInBackground(AIRequest... aiRequests) {
                    final AIRequest request = aiRequests[0];
                    try {
                        final AIResponse response = aiDataService.request(aiRequest);
                        return response;
                    } catch (AIServiceException e) {

                    }
                    return null;
                }

                @Override
                protected void onPostExecute(AIResponse response) {
                    if (response != null) {

                        Result result = response.getResult();
                        String reply = result.getFulfillment().getSpeech();
                        ChatMessageBean chatMessageBean = new ChatMessageBean(reply.trim());
                        chatList.add(chatMessageBean);
                        chatMessageListAdapter = new ChatMessageListAdapter(chatList);
                        chatRecyclerView.setLayoutManager(new LinearLayoutManager(PersonaAssistantChatActivity.this));
                        chatRecyclerView.setAdapter(chatMessageListAdapter);

                        textToSpeech.speak(reply,TextToSpeech.QUEUE_FLUSH,null);

                        if(reply.trim().equalsIgnoreCase(API_ACCESS_STRING)){ //API_ACCESS_STRING is the string after which I have to get response from my own defined intents. So I am cheking if the reply is equal to API_ACCESS_STRING

                            String intentName=result.getMetadata().getIntentName();
                            switch(intentName){
                                case "AvailableEmployees":
                                     Log.d(TAG, "CallIntents: AvailableEmployees:"+intentName);
                                    String jobName=result.getStringParameter("JobName");
                                    String date = result.getStringParameter("Date");
                                    Log.d(TAG,"JobName:"+jobName+"date: "+date);  // When I send voice input here I get jobName="AvailableEmployees" automatically, and dialog flow doesnot ask for jobName, where as with text input I get everything right.

                            }
                        }

                    }
                }
            }.execute(aiRequest);
        } else {
            Toast.makeText(getApplicationContext(), "Please enter some text first or record your message", Toast.LENGTH_LONG).show();
        }
    }


    @Override
    public void onResult(AIResponse result) {
        String message= result.getResult().getResolvedQuery().toString().trim();
        sendMessage(message);//sending message with voice input

    }

    @Override
    public void onError(AIError error) {
        Log.i(TAG, ": onError" + error);
    }

    @Override
    public void onAudioLevel(float level) {
        Log.i(TAG, ": onAudioLevel:" + level);
    }

    @Override
    public void onListeningStarted() {
        Log.i(TAG, ": onListeningStarted");

    }

    @Override
    public void onListeningCanceled() {
        Log.i(TAG, ": onListeningCanceled");
    }

    @Override
    public void onListeningFinished() {
        Log.i(TAG, ": onListeningFinished");

    }
}

1 个答案:

答案 0 :(得分:0)

您无法在sendMessage(message);//sending message with voice input方法中致电onResult。当aiService完成侦听并且已经向Dialogflow发送请求并获得响应时,将调用此方法。当您调用aiService.startListening();时,服务会检测用户说的内容并将其发送到Dialogflow。

如果你想知道文字&#34; aiService&#34;发送到Dialogflow你必须使用PartialResultsListener并实现它:

@Override
public void onPartialResults(final List<String> partialResults) {
    if (!partialResults.isEmpty()) {
        String partialResult = partialResults.get(0);
    }
}

通过这种方式,您将获得用户所说的内容,但请注意,该方法将在onListeningFinished()结束前调用。

祝你好运Handler.postDelayed():)