/*
* Copyright 2011 Greg Milette and Adam Stroud
*
* 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.
*/
package root.gast.speech;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import android.app.Activity;
import android.content.Context;
import android.content.Intent;
import android.content.pm.PackageManager;
import android.content.pm.ResolveInfo;
import android.os.Bundle;
import android.speech.RecognitionListener;
import android.speech.RecognizerIntent;
import android.speech.SpeechRecognizer;
/**
* A utility class to perform common speech recognition functions
* @author Greg Milette <<a href="mailto:gregorym@gmail.com">gregorym@gmail.com</a>>
*/
public class SpeechRecognitionUtil
{
private static final String TAG = "SpeechRecognitionUtil";
//Note: Google seems to send back these values
//use at your own risk
public static final String UNSUPPORTED_GOOGLE_RESULTS_CONFIDENCE = "com.google.android.voicesearch.UNSUPPORTED_PARTIAL_RESULTS_CONFIDENCE";
public static final String UNSUPPORTED_GOOGLE_RESULTS = "com.google.android.voicesearch.UNSUPPORTED_PARTIAL_RESULTS";
/**
* checks if the device supports speech recognition
* at all
*/
public static boolean isSpeechAvailable(Context context)
{
PackageManager pm = context.getPackageManager();
List<ResolveInfo> activities = pm.queryIntentActivities(
new Intent(RecognizerIntent.ACTION_RECOGNIZE_SPEECH), 0);
boolean available = true;
if (activities.size() == 0)
{
available = false;
}
return available;
//also works, but it is checking something slightly different
//it checks for the recognizer service. so we use the above check
//instead since it directly answers the question of whether or not
//the app can service the intent the app will send
// return SpeechRecognizer.isRecognitionAvailable(context);
}
/**
* collects language details and returns result to andThen
*/
public static void getLanguageDetails(Context context,
OnLanguageDetailsListener andThen)
{
Intent detailsIntent = new Intent(
RecognizerIntent.ACTION_GET_LANGUAGE_DETAILS);
LanguageDetailsChecker checker = new LanguageDetailsChecker(andThen);
context.sendOrderedBroadcast(detailsIntent, null, checker, null,
Activity.RESULT_OK, null, null);
//also works
// Intent detailsIntent = RecognizerIntent.getVoiceDetailsIntent(this);
}
public static List<String> getHeardFromDirect(Bundle bundle)
{
List<String> results = new ArrayList<String>();
if ((bundle != null)
&& bundle.containsKey(SpeechRecognizer.RESULTS_RECOGNITION))
{
results =
bundle.getStringArrayList(SpeechRecognizer.RESULTS_RECOGNITION);
}
return results;
}
public static float[] getConfidenceFromDirect(Bundle bundle)
{
float [] scores = null;
if ((bundle != null)
&& bundle.containsKey(SpeechRecognizer.RESULTS_RECOGNITION))
{
scores =
bundle.getFloatArray(SpeechRecognizer.CONFIDENCE_SCORES);
}
return scores;
}
public static List<String> getHeardFromDirectPartial(Bundle bundle)
{
List<String> results = new ArrayList<String>();
if (bundle.containsKey(UNSUPPORTED_GOOGLE_RESULTS))
{
String [] resultsArray =
bundle.getStringArray(UNSUPPORTED_GOOGLE_RESULTS);
results = Arrays.asList(resultsArray);
}
else
{
return getHeardFromDirect(bundle);
}
return results;
}
public static float[] getConfidenceFromDirectPartial(Bundle bundle)
{
float[] scores = null;
if (bundle
.containsKey(UNSUPPORTED_GOOGLE_RESULTS_CONFIDENCE))
{
scores =
bundle.getFloatArray(UNSUPPORTED_GOOGLE_RESULTS_CONFIDENCE);
}
else
{
scores = getConfidenceFromDirect(bundle);
}
return scores;
}
public static void recognizeSpeechDirectly(Context context,
Intent recognizerIntent, RecognitionListener listener,
SpeechRecognizer recognizer)
{
//need to have a calling package for it to work
if (!recognizerIntent.hasExtra(RecognizerIntent.EXTRA_CALLING_PACKAGE))
{
recognizerIntent.putExtra(RecognizerIntent.EXTRA_CALLING_PACKAGE, "com.dummy");
}
recognizer.setRecognitionListener(listener);
recognizer.startListening(recognizerIntent);
}
public static String diagnoseErrorCode(int errorCode)
{
String message;
switch (errorCode)
{
case SpeechRecognizer.ERROR_AUDIO:
message = "Audio recording error";
break;
case SpeechRecognizer.ERROR_CLIENT:
message = "Client side error";
break;
case SpeechRecognizer.ERROR_INSUFFICIENT_PERMISSIONS:
message = "Insufficient permissions";
break;
case SpeechRecognizer.ERROR_NETWORK:
message = "Network error";
break;
case SpeechRecognizer.ERROR_NETWORK_TIMEOUT:
message = "Network timeout";
break;
case SpeechRecognizer.ERROR_NO_MATCH:
message = "No match";
break;
case SpeechRecognizer.ERROR_RECOGNIZER_BUSY:
message = "RecognitionService busy";
break;
case SpeechRecognizer.ERROR_SERVER:
message = "error from server";
break;
case SpeechRecognizer.ERROR_SPEECH_TIMEOUT:
message = "No speech input";
break;
default:
message = "Didn't understand, please try again.";
break;
}
return message;
}
}