/** * Analyzes response from Amazon Lex service. Returns a {@link Runnable} with the next step, which * is usually a callback method in the {@link InteractionListener} object. * * @param handler {@link Handler}, to interact with app components in the main thread. * @param result {@link PostContentResult}, response from the Amazon Lex service. * @param client {@link InteractionClient}, reference to this object. * @param responseMode {@link ResponseType}, current response type. */ private void processResponse( final Handler handler, final PostContentResult result, final InteractionClient client, final ResponseType responseMode, final ResponseType requestMode) { Runnable response; try { setBusyState(NOT_BUSY); final Response serviceResponse = new Response(result); if (DialogState.Failed.toString().equals(result.getDialogState())) { // Amazon Lex service reported an error. response = new Runnable() { @Override public void run() { interactionListener.onInteractionError( serviceResponse, new DialogFailedException("Failed to fulfill current request.")); } }; } else if (DialogState.ReadyForFulfillment.equals(result.getDialogState())) { // The current dlalog is ready for fulfilled by the client. response = new Runnable() { @Override public void run() { interactionListener.onReadyForFulfillment(new Response(result)); } }; } else if (DialogState.Fulfilled.toString().equals(result.getDialogState())) { // Request was successfully fulfilled, no further action required. response = new Runnable() { @Override public void run() { interactionListener.promptUserToRespond(serviceResponse, null); } }; } else { // User's response is required to continue. final LexServiceContinuation continuation = new LexServiceContinuation(client, responseMode, requestMode); // set the session attributes on the continuation continuation.setSessionAttributes(serviceResponse.getSessionAttributes()); response = new Runnable() { @Override public void run() { interactionListener.promptUserToRespond(serviceResponse, continuation); } }; } } catch (final Exception e) { response = new Runnable() { @Override public void run() { interactionListener.onInteractionError(null, e); } }; } finally { setBusyState(NOT_BUSY); } handler.post(response); }
/** * Invokes the Android {@link MediaPlayer} to playback audio if audio playback was requested, and * continues to analyze the response. If the response does not contain audio stream or if audio * playback was not requested, continues to analyze the response. * * @param handler {@link Handler}, to interact with app components in the main thread. * @param result {@link PostContentResult}, response from the Amazon Lex service. * @param client {@link InteractionClient}, reference to this object. * @param responseMode {@link ResponseType}, current response type. */ private void processResponseAudioPlayback( final Handler handler, final PostContentResult result, final InteractionClient client, final ResponseType responseMode, final ResponseType requestType) { // Check if response is audio and audio playback is requested. if (ResponseType.AUDIO_MPEG.equals(responseMode) && interactionConfig.isEnableAudioPlayback()) { this.lMediaPlayer = new MediaPlayer(); this.lMediaPlayer.setAudioStreamType(AudioManager.STREAM_MUSIC); try { setAudioPlaybackState(BUSY); File tempAudioFile = File.createTempFile("lex_temp_response", "mp3", context.getFilesDir()); tempAudioFile.deleteOnExit(); // Media player listeners. lMediaPlayer.setOnErrorListener( new MediaPlayer.OnErrorListener() { @Override public boolean onError(final MediaPlayer mp, final int what, final int extra) { if (interactionListener != null) { final Runnable appCallback = new Runnable() { @Override public void run() { audioPlaybackListener.onAudioPlaybackError( new AudioPlaybackException( String.format( Locale.US, "MediaPlayer error: \"what\": %d, \"extra\":%d", what, extra))); } }; handler.post(appCallback); } return false; } }); lMediaPlayer.setOnPreparedListener( new MediaPlayer.OnPreparedListener() { @Override public void onPrepared(MediaPlayer mp) { if (audioPlaybackListener != null) { final Runnable appCallback = new Runnable() { @Override public void run() { audioPlaybackListener.onAudioPlaybackStarted(); } }; handler.post(appCallback); } mp.start(); } }); lMediaPlayer.setOnCompletionListener( new MediaPlayer.OnCompletionListener() { @Override public void onCompletion(MediaPlayer mp) { setAudioPlaybackState(NOT_BUSY); if (audioPlaybackListener != null) { final Runnable appCallback = new Runnable() { @Override public void run() { audioPlaybackListener.onAudioPlayBackCompleted(); } }; handler.post(appCallback); } try { if (lMediaPlayer.isPlaying() || lMediaPlayer.isLooping()) { lMediaPlayer.stop(); } lMediaPlayer.release(); } catch (final Exception e) { Log.e(TAG, "InteractionClient: Error while releasing MediaPlayer", e); } finally { lMediaPlayer = null; } } }); final InputStream audioStream = result.getAudioStream(); tempAudioFile = File.createTempFile("lex_temp_response", "dat", context.getFilesDir()); tempAudioFile.deleteOnExit(); final FileOutputStream audioOut = new FileOutputStream(tempAudioFile); final byte buffer[] = new byte[16384]; int length; while ((length = audioStream.read(buffer)) != -1) { audioOut.write(buffer, 0, length); } audioOut.close(); final FileInputStream audioIn = new FileInputStream(tempAudioFile); lMediaPlayer.setDataSource(audioIn.getFD()); lMediaPlayer.prepare(); processResponse(handler, result, client, responseMode, requestType); } catch (final Exception e) { // Playback failed. if (audioPlaybackListener != null) { final Runnable appCallback = new Runnable() { @Override public void run() { audioPlaybackListener.onAudioPlaybackError( new LexClientException("Audio playback failed", e)); } }; handler.post(appCallback); } try { if (lMediaPlayer.isPlaying() || lMediaPlayer.isLooping()) { lMediaPlayer.stop(); } lMediaPlayer.release(); lMediaPlayer = null; } catch (final Exception exp) { Log.e(TAG, "InteractionClient: Error while releasing MediaPlayer", exp); } processResponse(handler, result, client, responseMode, requestType); } finally { setAudioPlaybackState(NOT_BUSY); } } else { processResponse(handler, result, client, responseMode, requestType); } }