Android Open Source - api-ai-android-sdk Google Recognition Service Impl






From Project

Back to project page api-ai-android-sdk.

License

The source code is released under:

Apache License

If you think the Android project api-ai-android-sdk listed in this page is inappropriate, such as containing malicious code/tools or violating the copyright, please email info at java2s dot com, thanks.

Java Source Code

package ai.api;
/*ww w  .j  av a 2 s. c  o m*/
/***********************************************************************************************************************
 *
 * API.AI Android SDK - client-side libraries for API.AI
 * =================================================
 *
 * Copyright (C) 2014 by Speaktoit, Inc. (https://www.speaktoit.com)
 * https://www.api.ai
 *
 ***********************************************************************************************************************
 *
 * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with
 * the License. You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on
 * an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the
 * specific language governing permissions and limitations under the License.
 *
 ***********************************************************************************************************************/

import android.annotation.TargetApi;
import android.content.ComponentName;
import android.content.Context;
import android.content.Intent;
import android.os.AsyncTask;
import android.os.Build;
import android.os.Bundle;
import android.os.Handler;
import android.speech.RecognitionListener;
import android.speech.RecognizerIntent;
import android.speech.SpeechRecognizer;
import android.util.Log;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import ai.api.model.AIContext;
import ai.api.model.AIError;
import ai.api.model.AIRequest;
import ai.api.model.AIResponse;
import ai.api.util.RecognizerChecker;

public class GoogleRecognitionServiceImpl extends AIService {

    private static final String TAG = GoogleRecognitionServiceImpl.class.getName();

    private SpeechRecognizer speechRecognizer;
    private final Object speechRecognizerLock = new Object();

    private volatile boolean recognitionActive = false;

    private final Handler handler;

    private final Map<Integer, String> errorMessages = new HashMap<>();

    {
        errorMessages.put(1, "Network operation timed out.");
        errorMessages.put(2, "Other network related errors.");
        errorMessages.put(3, "Audio recording error.");
        errorMessages.put(4, "Server sends error status.");
        errorMessages.put(5, "Other client side errors.");
        errorMessages.put(6, "No speech input.");
        errorMessages.put(7, "No recognition result matched.");
        errorMessages.put(8, "RecognitionService busy.");
        errorMessages.put(9, "Insufficient permissions.");
    }

    private List<AIContext> contexts;

    protected GoogleRecognitionServiceImpl(final Context context, final AIConfiguration config) {
        super(config, context);

        final ComponentName googleRecognizerComponent = RecognizerChecker.findGoogleRecognizer(context);
        if (googleRecognizerComponent == null) {
            Log.w(TAG, "Google Recognizer application not found on device. Quality of the recognition may be low. Please check if Google Search application installed and enabled.");
        }

        handler = new Handler(context.getMainLooper());
    }

    protected void initializeRecognizer() {
        synchronized (speechRecognizerLock) {
            if (speechRecognizer != null) {
                speechRecognizer.destroy();
                speechRecognizer = null;
            }

            final ComponentName googleRecognizerComponent = RecognizerChecker.findGoogleRecognizer(context);

            if (googleRecognizerComponent == null) {
                speechRecognizer = SpeechRecognizer.createSpeechRecognizer(context);
            } else {
                speechRecognizer = SpeechRecognizer.createSpeechRecognizer(context, googleRecognizerComponent);
            }

            speechRecognizer.setRecognitionListener(new InternalRecognitionListener());
        }
    }

    protected void clearRecognizer() {
        if (speechRecognizer != null) {
            synchronized (speechRecognizerLock) {
                if (speechRecognizer != null) {
                    speechRecognizer.destroy();
                    speechRecognizer = null;
                }
            }
        }
    }

    private void sendRequest(final AIRequest aiRequest) {

        if (aiRequest == null) {
            throw new IllegalArgumentException("aiRequest must be not null");
        }

        final AsyncTask<AIRequest, Integer, AIResponse> task = new AsyncTask<AIRequest, Integer, AIResponse>() {

            private AIError aiError;

            @Override
            protected AIResponse doInBackground(final AIRequest... params) {
                final AIRequest request = params[0];
                try {
                    final AIResponse response = aiDataService.request(request);
                    return response;
                } catch (final AIServiceException e) {
                    aiError = new AIError(e);
                    return null;
                }
            }

            @Override
            protected void onPostExecute(final AIResponse response) {
                if (response != null) {
                    onResult(response);
                } else {
                    onError(aiError);
                }
            }
        };

        task.execute(aiRequest);
    }

    @Override
    public void startListening() {
        startListening(null);
    }

    @Override
    public void startListening(final List<AIContext> contexts) {
        if (!recognitionActive) {
            this.contexts = contexts;

            final Intent sttIntent = new Intent(RecognizerIntent.ACTION_RECOGNIZE_SPEECH);
            sttIntent.putExtra(RecognizerIntent.EXTRA_LANGUAGE_MODEL,
                    RecognizerIntent.LANGUAGE_MODEL_FREE_FORM);
            sttIntent.putExtra(RecognizerIntent.EXTRA_LANGUAGE, config.getLanguage());
            sttIntent.putExtra(RecognizerIntent.EXTRA_LANGUAGE_PREFERENCE, config.getLanguage());

            // WORKAROUND for https://code.google.com/p/android/issues/detail?id=75347
            // TODO Must be removed after fix in Android
            sttIntent.putExtra("android.speech.extra.EXTRA_ADDITIONAL_LANGUAGES", new String[]{});

            runInUiThread(new Runnable() {
                @Override
                public void run() {
                    initializeRecognizer();

                    speechRecognizer.startListening(sttIntent);
                    recognitionActive = true;
                }
            });

        } else {
            Log.w(TAG, "Trying to start recognition while another recognition active");
        }
    }

    @Override
    public void stopListening() {
        if (recognitionActive) {
            runInUiThread(new Runnable() {
                @Override
                public void run() {
                    synchronized (speechRecognizerLock) {
                        if (recognitionActive) {
                            speechRecognizer.stopListening();
                            recognitionActive = false;
                        }
                    }
                }
            });
        } else {
            Log.w(TAG, "Trying to stop listening while not active recognition");
        }
    }

    @Override
    public void cancel() {
        if (recognitionActive) {
            runInUiThread(new Runnable() {
                @Override
                public void run() {
                    synchronized (speechRecognizerLock) {
                        if (recognitionActive) {
                            speechRecognizer.cancel();
                            recognitionActive = false;
                        }
                    }
                }
            });

        }
    }

    /**
     * This method must be called from UI thread
     */
    @Override
    public void pause() {
        super.pause();

        clearRecognizer();
    }

    /**
     * This method must be called from UI thread
     */
    @Override
    public void resume() {
        super.resume();
    }

    private void runInUiThread(final Runnable runnable) {
        handler.post(runnable);
    }

    private class InternalRecognitionListener implements RecognitionListener {

        @Override
        public void onReadyForSpeech(final Bundle params) {
            GoogleRecognitionServiceImpl.this.onListeningStarted();
        }

        @Override
        public void onBeginningOfSpeech() {

        }

        @Override
        public void onRmsChanged(final float rmsdB) {
            GoogleRecognitionServiceImpl.this.onAudioLevelChanged(rmsdB);
        }

        @Override
        public void onBufferReceived(final byte[] buffer) {

        }

        @Override
        public void onEndOfSpeech() {
            GoogleRecognitionServiceImpl.this.onListeningFinished();
        }

        @Override
        public void onError(final int error) {
            recognitionActive = false;

            final AIError aiError;

            if (errorMessages.containsKey(error)) {
                final String description = errorMessages.get(error);
                aiError = new AIError("Speech recognition engine error: " + description);
            } else {
                aiError = new AIError("Speech recognition engine error: " + error);
            }
            GoogleRecognitionServiceImpl.this.onError(aiError);
        }

        @TargetApi(14)
        @Override
        public void onResults(final Bundle results) {
            if (recognitionActive) {
                recognitionActive = false;

                final ArrayList<String> recognitionResults = results
                        .getStringArrayList(SpeechRecognizer.RESULTS_RECOGNITION);

                float[] rates = null;

                if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.ICE_CREAM_SANDWICH) {
                    rates = results.getFloatArray(SpeechRecognizer.CONFIDENCE_SCORES);
                }

                if (recognitionResults == null || recognitionResults.size() == 0) {
                    // empty response
                    GoogleRecognitionServiceImpl.this.onResult(new AIResponse());
                } else {
                    final AIRequest aiRequest = new AIRequest();
                    if (rates != null) {
                        aiRequest.setQuery(recognitionResults.toArray(new String[recognitionResults.size()]), rates);
                    } else {
                        aiRequest.setQuery(recognitionResults.get(0));
                    }

                    if (contexts != null) {
                        aiRequest.setContexts(contexts);
                    }

                    GoogleRecognitionServiceImpl.this.sendRequest(aiRequest);

                    clearRecognizer();
                }
            }
        }

        @Override
        public void onPartialResults(final Bundle partialResults) {

        }

        @Override
        public void onEvent(final int eventType, final Bundle params) {

        }
    }


}




Java Source Code List

ai.api.AIConfiguration.java
ai.api.AIDataService.java
ai.api.AIListener.java
ai.api.AIServiceException.java
ai.api.AIService.java
ai.api.AudioRequestTask.java
ai.api.AudioRequest.java
ai.api.GoogleRecognitionServiceImpl.java
ai.api.GsonFactory.java
ai.api.RecognitionEngine.java
ai.api.RequestTask.java
ai.api.SpeaktoitRecognitionServiceImpl.java
ai.api.http.HttpClient.java
ai.api.model.AIContext.java
ai.api.model.AIError.java
ai.api.model.AIRequest.java
ai.api.model.AIResponse.java
ai.api.model.Constants.java
ai.api.model.Metadata.java
ai.api.model.QuestionMetadata.java
ai.api.model.Result.java
ai.api.model.Status.java
ai.api.sample.AIButtonSampleActivity.java
ai.api.sample.AIServiceSampleActivity.java
ai.api.sample.Config.java
ai.api.sample.MainActivity.java
ai.api.ui.AIButton.java
ai.api.ui.MaskedColorView.java
ai.api.ui.SoundLevelButton.java
ai.api.ui.SoundLevelCircleDrawable.java
ai.api.util.RecognizerChecker.java
ai.api.util.VoiceActivityDetector.java