Merge "Adding speech recognition service public API"
This commit is contained in:
committed by
Android (Google) Code Review
commit
1009e82ef2
259
api/current.xml
259
api/current.xml
@@ -135042,7 +135042,7 @@
|
||||
<parameter name="error" type="int">
|
||||
</parameter>
|
||||
</method>
|
||||
<method name="onInit"
|
||||
<method name="onEvent"
|
||||
return="void"
|
||||
abstract="true"
|
||||
native="false"
|
||||
@@ -135052,6 +135052,10 @@
|
||||
deprecated="not deprecated"
|
||||
visibility="public"
|
||||
>
|
||||
<parameter name="eventType" type="int">
|
||||
</parameter>
|
||||
<parameter name="params" type="android.os.Bundle">
|
||||
</parameter>
|
||||
</method>
|
||||
<method name="onPartialResults"
|
||||
return="void"
|
||||
@@ -135137,10 +135141,6 @@
|
||||
>
|
||||
<parameter name="context" type="android.content.Context">
|
||||
</parameter>
|
||||
<parameter name="listener" type="android.speech.RecognitionListener">
|
||||
</parameter>
|
||||
<parameter name="recognizerIntent" type="android.content.Intent">
|
||||
</parameter>
|
||||
</method>
|
||||
<method name="destroy"
|
||||
return="void"
|
||||
@@ -135166,6 +135166,19 @@
|
||||
<parameter name="context" type="android.content.Context">
|
||||
</parameter>
|
||||
</method>
|
||||
<method name="setRecognitionListener"
|
||||
return="void"
|
||||
abstract="false"
|
||||
native="false"
|
||||
synchronized="false"
|
||||
static="false"
|
||||
final="false"
|
||||
deprecated="not deprecated"
|
||||
visibility="public"
|
||||
>
|
||||
<parameter name="listener" type="android.speech.RecognitionListener">
|
||||
</parameter>
|
||||
</method>
|
||||
<method name="startListening"
|
||||
return="void"
|
||||
abstract="false"
|
||||
@@ -135190,7 +135203,7 @@
|
||||
visibility="public"
|
||||
>
|
||||
</method>
|
||||
<field name="AUDIO_ERROR"
|
||||
<field name="ERROR_AUDIO"
|
||||
type="int"
|
||||
transient="false"
|
||||
volatile="false"
|
||||
@@ -135201,7 +135214,7 @@
|
||||
visibility="public"
|
||||
>
|
||||
</field>
|
||||
<field name="CLIENT_ERROR"
|
||||
<field name="ERROR_CLIENT"
|
||||
type="int"
|
||||
transient="false"
|
||||
volatile="false"
|
||||
@@ -135212,7 +135225,7 @@
|
||||
visibility="public"
|
||||
>
|
||||
</field>
|
||||
<field name="MANAGER_NOT_INITIALIZED_ERROR"
|
||||
<field name="ERROR_INSUFFICIENT_PERMISSIONS"
|
||||
type="int"
|
||||
transient="false"
|
||||
volatile="false"
|
||||
@@ -135223,7 +135236,7 @@
|
||||
visibility="public"
|
||||
>
|
||||
</field>
|
||||
<field name="NETWORK_ERROR"
|
||||
<field name="ERROR_NETWORK"
|
||||
type="int"
|
||||
transient="false"
|
||||
volatile="false"
|
||||
@@ -135234,7 +135247,7 @@
|
||||
visibility="public"
|
||||
>
|
||||
</field>
|
||||
<field name="NETWORK_TIMEOUT_ERROR"
|
||||
<field name="ERROR_NETWORK_TIMEOUT"
|
||||
type="int"
|
||||
transient="false"
|
||||
volatile="false"
|
||||
@@ -135245,7 +135258,7 @@
|
||||
visibility="public"
|
||||
>
|
||||
</field>
|
||||
<field name="NO_MATCH_ERROR"
|
||||
<field name="ERROR_NO_MATCH"
|
||||
type="int"
|
||||
transient="false"
|
||||
volatile="false"
|
||||
@@ -135256,18 +135269,7 @@
|
||||
visibility="public"
|
||||
>
|
||||
</field>
|
||||
<field name="RECOGNITION_RESULTS_STRING_ARRAY"
|
||||
type="java.lang.String"
|
||||
transient="false"
|
||||
volatile="false"
|
||||
value=""recognition_results_string_array""
|
||||
static="true"
|
||||
final="true"
|
||||
deprecated="not deprecated"
|
||||
visibility="public"
|
||||
>
|
||||
</field>
|
||||
<field name="SERVER_BUSY_ERROR"
|
||||
<field name="ERROR_RECOGNIZER_BUSY"
|
||||
type="int"
|
||||
transient="false"
|
||||
volatile="false"
|
||||
@@ -135278,7 +135280,7 @@
|
||||
visibility="public"
|
||||
>
|
||||
</field>
|
||||
<field name="SERVER_ERROR"
|
||||
<field name="ERROR_SERVER"
|
||||
type="int"
|
||||
transient="false"
|
||||
volatile="false"
|
||||
@@ -135289,7 +135291,7 @@
|
||||
visibility="public"
|
||||
>
|
||||
</field>
|
||||
<field name="SPEECH_TIMEOUT_ERROR"
|
||||
<field name="ERROR_SPEECH_TIMEOUT"
|
||||
type="int"
|
||||
transient="false"
|
||||
volatile="false"
|
||||
@@ -135300,6 +135302,213 @@
|
||||
visibility="public"
|
||||
>
|
||||
</field>
|
||||
<field name="RESULTS_RECOGNITION"
|
||||
type="java.lang.String"
|
||||
transient="false"
|
||||
volatile="false"
|
||||
value=""results_recognition""
|
||||
static="true"
|
||||
final="true"
|
||||
deprecated="not deprecated"
|
||||
visibility="public"
|
||||
>
|
||||
</field>
|
||||
</class>
|
||||
<class name="RecognitionService"
|
||||
extends="android.app.Service"
|
||||
abstract="true"
|
||||
static="false"
|
||||
final="false"
|
||||
deprecated="not deprecated"
|
||||
visibility="public"
|
||||
>
|
||||
<constructor name="RecognitionService"
|
||||
type="android.speech.RecognitionService"
|
||||
static="false"
|
||||
final="false"
|
||||
deprecated="not deprecated"
|
||||
visibility="public"
|
||||
>
|
||||
</constructor>
|
||||
<method name="onBind"
|
||||
return="android.os.IBinder"
|
||||
abstract="false"
|
||||
native="false"
|
||||
synchronized="false"
|
||||
static="false"
|
||||
final="true"
|
||||
deprecated="not deprecated"
|
||||
visibility="public"
|
||||
>
|
||||
<parameter name="intent" type="android.content.Intent">
|
||||
</parameter>
|
||||
</method>
|
||||
<method name="onCancel"
|
||||
return="void"
|
||||
abstract="true"
|
||||
native="false"
|
||||
synchronized="false"
|
||||
static="false"
|
||||
final="false"
|
||||
deprecated="not deprecated"
|
||||
visibility="protected"
|
||||
>
|
||||
<parameter name="listener" type="android.speech.RecognitionService.Callback">
|
||||
</parameter>
|
||||
</method>
|
||||
<method name="onStartListening"
|
||||
return="void"
|
||||
abstract="true"
|
||||
native="false"
|
||||
synchronized="false"
|
||||
static="false"
|
||||
final="false"
|
||||
deprecated="not deprecated"
|
||||
visibility="protected"
|
||||
>
|
||||
<parameter name="recognizerIntent" type="android.content.Intent">
|
||||
</parameter>
|
||||
<parameter name="listener" type="android.speech.RecognitionService.Callback">
|
||||
</parameter>
|
||||
</method>
|
||||
<method name="onStopListening"
|
||||
return="void"
|
||||
abstract="true"
|
||||
native="false"
|
||||
synchronized="false"
|
||||
static="false"
|
||||
final="false"
|
||||
deprecated="not deprecated"
|
||||
visibility="protected"
|
||||
>
|
||||
<parameter name="listener" type="android.speech.RecognitionService.Callback">
|
||||
</parameter>
|
||||
</method>
|
||||
</class>
|
||||
<class name="RecognitionService.Callback"
|
||||
extends="java.lang.Object"
|
||||
abstract="false"
|
||||
static="false"
|
||||
final="false"
|
||||
deprecated="not deprecated"
|
||||
visibility="public"
|
||||
>
|
||||
<method name="beginningOfSpeech"
|
||||
return="void"
|
||||
abstract="false"
|
||||
native="false"
|
||||
synchronized="false"
|
||||
static="false"
|
||||
final="false"
|
||||
deprecated="not deprecated"
|
||||
visibility="public"
|
||||
>
|
||||
<exception name="RemoteException" type="android.os.RemoteException">
|
||||
</exception>
|
||||
</method>
|
||||
<method name="bufferReceived"
|
||||
return="void"
|
||||
abstract="false"
|
||||
native="false"
|
||||
synchronized="false"
|
||||
static="false"
|
||||
final="false"
|
||||
deprecated="not deprecated"
|
||||
visibility="public"
|
||||
>
|
||||
<parameter name="buffer" type="byte[]">
|
||||
</parameter>
|
||||
<exception name="RemoteException" type="android.os.RemoteException">
|
||||
</exception>
|
||||
</method>
|
||||
<method name="endOfSpeech"
|
||||
return="void"
|
||||
abstract="false"
|
||||
native="false"
|
||||
synchronized="false"
|
||||
static="false"
|
||||
final="false"
|
||||
deprecated="not deprecated"
|
||||
visibility="public"
|
||||
>
|
||||
<exception name="RemoteException" type="android.os.RemoteException">
|
||||
</exception>
|
||||
</method>
|
||||
<method name="error"
|
||||
return="void"
|
||||
abstract="false"
|
||||
native="false"
|
||||
synchronized="false"
|
||||
static="false"
|
||||
final="false"
|
||||
deprecated="not deprecated"
|
||||
visibility="public"
|
||||
>
|
||||
<parameter name="error" type="int">
|
||||
</parameter>
|
||||
<exception name="RemoteException" type="android.os.RemoteException">
|
||||
</exception>
|
||||
</method>
|
||||
<method name="partialResults"
|
||||
return="void"
|
||||
abstract="false"
|
||||
native="false"
|
||||
synchronized="false"
|
||||
static="false"
|
||||
final="false"
|
||||
deprecated="not deprecated"
|
||||
visibility="public"
|
||||
>
|
||||
<parameter name="partialResults" type="android.os.Bundle">
|
||||
</parameter>
|
||||
<exception name="RemoteException" type="android.os.RemoteException">
|
||||
</exception>
|
||||
</method>
|
||||
<method name="readyForSpeech"
|
||||
return="void"
|
||||
abstract="false"
|
||||
native="false"
|
||||
synchronized="false"
|
||||
static="false"
|
||||
final="false"
|
||||
deprecated="not deprecated"
|
||||
visibility="public"
|
||||
>
|
||||
<parameter name="params" type="android.os.Bundle">
|
||||
</parameter>
|
||||
<exception name="RemoteException" type="android.os.RemoteException">
|
||||
</exception>
|
||||
</method>
|
||||
<method name="results"
|
||||
return="void"
|
||||
abstract="false"
|
||||
native="false"
|
||||
synchronized="false"
|
||||
static="false"
|
||||
final="false"
|
||||
deprecated="not deprecated"
|
||||
visibility="public"
|
||||
>
|
||||
<parameter name="results" type="android.os.Bundle">
|
||||
</parameter>
|
||||
<exception name="RemoteException" type="android.os.RemoteException">
|
||||
</exception>
|
||||
</method>
|
||||
<method name="rmsChanged"
|
||||
return="void"
|
||||
abstract="false"
|
||||
native="false"
|
||||
synchronized="false"
|
||||
static="false"
|
||||
final="false"
|
||||
deprecated="not deprecated"
|
||||
visibility="public"
|
||||
>
|
||||
<parameter name="rmsdB" type="float">
|
||||
</parameter>
|
||||
<exception name="RemoteException" type="android.os.RemoteException">
|
||||
</exception>
|
||||
</method>
|
||||
</class>
|
||||
<class name="RecognizerIntent"
|
||||
extends="java.lang.Object"
|
||||
|
||||
@@ -19,12 +19,12 @@ package android.speech;
|
||||
import android.os.Bundle;
|
||||
|
||||
/**
|
||||
* Listener for speech recognition events, used with RecognitionService.
|
||||
* Listener for speech recognition events, used with RecognitionService.
|
||||
* This gives you both the final recognition results, as well as various
|
||||
* intermediate events that can be used to show visual feedback to the user.
|
||||
* {@hide}
|
||||
*/
|
||||
interface IRecognitionListener {
|
||||
oneway interface IRecognitionListener {
|
||||
/**
|
||||
* Called when the endpointer is ready for the user to start speaking.
|
||||
*
|
||||
@@ -76,4 +76,12 @@ interface IRecognitionListener {
|
||||
* @param results a Bundle containing the current most likely result.
|
||||
*/
|
||||
void onPartialResults(in Bundle results);
|
||||
|
||||
/**
|
||||
* Reserved for adding future events.
|
||||
*
|
||||
* @param eventType the type of the occurred event
|
||||
* @param params a Bundle containing the passed parameters
|
||||
*/
|
||||
void onEvent(in int eventType, in Bundle params);
|
||||
}
|
||||
|
||||
@@ -29,7 +29,7 @@ import android.speech.IRecognitionListener;
|
||||
* accessing recognition service.
|
||||
* {@hide}
|
||||
*/
|
||||
interface IRecognitionService {
|
||||
oneway interface IRecognitionService {
|
||||
/**
|
||||
* Starts listening for speech. Please note that the recognition service supports
|
||||
* one listener only, therefore, if this function is called from two different threads,
|
||||
@@ -38,7 +38,7 @@ interface IRecognitionService {
|
||||
* @param recognizerIntent the intent from which the invocation occurred. Additionally,
|
||||
* this intent can contain extra parameters to manipulate the behavior of the recognition
|
||||
* client. For more information see {@link RecognizerIntent}.
|
||||
* @param listener to receive callbacks
|
||||
* @param listener to receive callbacks, note that this must be non-null
|
||||
*/
|
||||
void startListening(in Intent recognizerIntent, in IRecognitionListener listener);
|
||||
|
||||
@@ -46,11 +46,15 @@ interface IRecognitionService {
|
||||
* Stops listening for speech. Speech captured so far will be recognized as
|
||||
* if the user had stopped speaking at this point. The function has no effect unless it
|
||||
* is called during the speech capturing.
|
||||
*
|
||||
* @param listener to receive callbacks, note that this must be non-null
|
||||
*/
|
||||
void stopListening();
|
||||
void stopListening(in IRecognitionListener listener);
|
||||
|
||||
/**
|
||||
* Cancels the speech recognition.
|
||||
*
|
||||
* @param listener to receive callbacks, note that this must be non-null
|
||||
*/
|
||||
void cancel();
|
||||
void cancel(in IRecognitionListener listener);
|
||||
}
|
||||
|
||||
@@ -24,12 +24,6 @@ import android.os.Bundle;
|
||||
* Application main thread.
|
||||
*/
|
||||
public interface RecognitionListener {
|
||||
|
||||
/**
|
||||
* Called when RecognitionManager is successfully initialized
|
||||
*/
|
||||
void onInit();
|
||||
|
||||
/**
|
||||
* Called when the endpointer is ready for the user to start speaking.
|
||||
*
|
||||
@@ -76,7 +70,7 @@ public interface RecognitionListener {
|
||||
*
|
||||
* @param results the recognition results. To retrieve the results in {@code
|
||||
* ArrayList<String>} format use {@link Bundle#getStringArrayList(String)} with
|
||||
* {@link RecognitionManager#RECOGNITION_RESULTS_STRING_ARRAY} as a parameter
|
||||
* {@link RecognitionManager#RESULTS_RECOGNITION} as a parameter
|
||||
*/
|
||||
void onResults(Bundle results);
|
||||
|
||||
@@ -89,8 +83,15 @@ public interface RecognitionListener {
|
||||
*
|
||||
* @param partialResults the returned results. To retrieve the results in
|
||||
* ArrayList<String> format use {@link Bundle#getStringArrayList(String)} with
|
||||
* {@link RecognitionManager#RECOGNITION_RESULTS_STRING_ARRAY} as a parameter
|
||||
* {@link RecognitionManager#RESULTS_RECOGNITION} as a parameter
|
||||
*/
|
||||
void onPartialResults(Bundle partialResults);
|
||||
|
||||
/**
|
||||
* Reserved for adding future events.
|
||||
*
|
||||
* @param eventType the type of the occurred event
|
||||
* @param params a Bundle containing the passed parameters
|
||||
*/
|
||||
void onEvent(int eventType, Bundle params);
|
||||
}
|
||||
|
||||
@@ -22,17 +22,23 @@ import android.content.Intent;
|
||||
import android.content.ServiceConnection;
|
||||
import android.content.pm.ResolveInfo;
|
||||
import android.os.Bundle;
|
||||
import android.os.Handler;
|
||||
import android.os.IBinder;
|
||||
import android.os.Looper;
|
||||
import android.os.Message;
|
||||
import android.os.RemoteException;
|
||||
import android.util.Log;
|
||||
|
||||
import java.util.LinkedList;
|
||||
import java.util.List;
|
||||
import java.util.Queue;
|
||||
|
||||
/**
|
||||
* This class provides access to the speech recognition service. This service allows access to the
|
||||
* speech recognizer. Do not instantiate this class directly, instead, call
|
||||
* {@link RecognitionManager#createRecognitionManager(Context, RecognitionListener, Intent)}. This
|
||||
* class is not thread safe and must be synchronized externally if accessed from multiple threads.
|
||||
* {@link RecognitionManager#createRecognitionManager(Context)}. This class's methods must be
|
||||
* invoked only from the main application thread. Please note that the application must have
|
||||
* {@link android.Manifest.permission#RECORD_AUDIO} permission to use this class.
|
||||
*/
|
||||
public class RecognitionManager {
|
||||
/** DEBUG value to enable verbose debug prints */
|
||||
@@ -47,8 +53,40 @@ public class RecognitionManager {
|
||||
* {@link RecognitionListener#onPartialResults(Bundle)} methods. These strings are the possible
|
||||
* recognition results, where the first element is the most likely candidate.
|
||||
*/
|
||||
public static final String RECOGNITION_RESULTS_STRING_ARRAY =
|
||||
"recognition_results_string_array";
|
||||
public static final String RESULTS_RECOGNITION = "results_recognition";
|
||||
|
||||
/** Network operation timed out. */
|
||||
public static final int ERROR_NETWORK_TIMEOUT = 1;
|
||||
|
||||
/** Other network related errors. */
|
||||
public static final int ERROR_NETWORK = 2;
|
||||
|
||||
/** Audio recording error. */
|
||||
public static final int ERROR_AUDIO = 3;
|
||||
|
||||
/** Server sends error status. */
|
||||
public static final int ERROR_SERVER = 4;
|
||||
|
||||
/** Other client side errors. */
|
||||
public static final int ERROR_CLIENT = 5;
|
||||
|
||||
/** No speech input */
|
||||
public static final int ERROR_SPEECH_TIMEOUT = 6;
|
||||
|
||||
/** No recognition result matched. */
|
||||
public static final int ERROR_NO_MATCH = 7;
|
||||
|
||||
/** RecognitionService busy. */
|
||||
public static final int ERROR_RECOGNIZER_BUSY = 8;
|
||||
|
||||
/** Insufficient permissions */
|
||||
public static final int ERROR_INSUFFICIENT_PERMISSIONS = 9;
|
||||
|
||||
/** action codes */
|
||||
private final static int MSG_START = 1;
|
||||
private final static int MSG_STOP = 2;
|
||||
private final static int MSG_CANCEL = 3;
|
||||
private final static int MSG_CHANGE_LISTENER = 4;
|
||||
|
||||
/** The actual RecognitionService endpoint */
|
||||
private IRecognitionService mService;
|
||||
@@ -59,80 +97,74 @@ public class RecognitionManager {
|
||||
/** Context with which the manager was created */
|
||||
private final Context mContext;
|
||||
|
||||
/** Listener that will receive all the callbacks */
|
||||
private final RecognitionListener mListener;
|
||||
|
||||
/** Helper class wrapping the IRecognitionListener */
|
||||
private final InternalRecognitionListener mInternalRecognitionListener;
|
||||
|
||||
/** Network operation timed out. */
|
||||
public static final int NETWORK_TIMEOUT_ERROR = 1;
|
||||
|
||||
/** Other network related errors. */
|
||||
public static final int NETWORK_ERROR = 2;
|
||||
|
||||
/** Audio recording error. */
|
||||
public static final int AUDIO_ERROR = 3;
|
||||
|
||||
/** Server sends error status. */
|
||||
public static final int SERVER_ERROR = 4;
|
||||
|
||||
/** Other client side errors. */
|
||||
public static final int CLIENT_ERROR = 5;
|
||||
|
||||
/** No speech input */
|
||||
public static final int SPEECH_TIMEOUT_ERROR = 6;
|
||||
|
||||
/** No recognition result matched. */
|
||||
public static final int NO_MATCH_ERROR = 7;
|
||||
|
||||
/** RecognitionService busy. */
|
||||
public static final int SERVER_BUSY_ERROR = 8;
|
||||
/** Handler that will execute the main tasks */
|
||||
private Handler mHandler = new Handler() {
|
||||
@Override
|
||||
public void handleMessage(Message msg) {
|
||||
switch (msg.what) {
|
||||
case MSG_START:
|
||||
handleStartListening((Intent) msg.obj);
|
||||
break;
|
||||
case MSG_STOP:
|
||||
handleStopMessage();
|
||||
break;
|
||||
case MSG_CANCEL:
|
||||
handleCancelMessage();
|
||||
break;
|
||||
case MSG_CHANGE_LISTENER:
|
||||
handleChangeListener((RecognitionListener) msg.obj);
|
||||
break;
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* RecognitionManager was not initialized yet, most probably because
|
||||
* {@link RecognitionListener#onInit()} was not called yet.
|
||||
* Temporary queue, saving the messages until the connection will be established, afterwards,
|
||||
* only mHandler will receive the messages
|
||||
*/
|
||||
public static final int MANAGER_NOT_INITIALIZED_ERROR = 9;
|
||||
private final Queue<Message> mPendingTasks = new LinkedList<Message>();
|
||||
|
||||
/** The Listener that will receive all the callbacks */
|
||||
private final InternalListener mListener = new InternalListener();
|
||||
|
||||
/**
|
||||
* The right way to create a RecognitionManager is by using
|
||||
* The right way to create a {@code RecognitionManager} is by using
|
||||
* {@link #createRecognitionManager} static factory method
|
||||
*/
|
||||
private RecognitionManager(final RecognitionListener listener, final Context context) {
|
||||
mInternalRecognitionListener = new InternalRecognitionListener();
|
||||
private RecognitionManager(final Context context) {
|
||||
mContext = context;
|
||||
mListener = listener;
|
||||
}
|
||||
|
||||
/**
|
||||
* Basic ServiceConnection which just records mService variable.
|
||||
* Basic ServiceConnection that records the mService variable. Additionally, on creation it
|
||||
* invokes the {@link IRecognitionService#startListening(Intent, IRecognitionListener)}.
|
||||
*/
|
||||
private class Connection implements ServiceConnection {
|
||||
|
||||
public synchronized void onServiceConnected(final ComponentName name,
|
||||
final IBinder service) {
|
||||
public void onServiceConnected(final ComponentName name, final IBinder service) {
|
||||
// always done on the application main thread, so no need to send message to mHandler
|
||||
mService = IRecognitionService.Stub.asInterface(service);
|
||||
if (mListener != null) {
|
||||
mListener.onInit();
|
||||
}
|
||||
if (DBG) Log.d(TAG, "onServiceConnected - Success");
|
||||
while (!mPendingTasks.isEmpty()) {
|
||||
mHandler.sendMessage(mPendingTasks.poll());
|
||||
}
|
||||
}
|
||||
|
||||
public void onServiceDisconnected(final ComponentName name) {
|
||||
// always done on the application main thread, so no need to send message to mHandler
|
||||
mService = null;
|
||||
mConnection = null;
|
||||
mPendingTasks.clear();
|
||||
if (DBG) Log.d(TAG, "onServiceDisconnected - Success");
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks whether a speech recognition service is available on the system. If this method
|
||||
* returns {@code false},
|
||||
* {@link RecognitionManager#createRecognitionManager(Context, RecognitionListener, Intent)}
|
||||
* will fail.
|
||||
* returns {@code false}, {@link RecognitionManager#createRecognitionManager(Context)} will
|
||||
* fail.
|
||||
*
|
||||
* @param context with which RecognitionManager will be created
|
||||
* @param context with which {@code RecognitionManager} will be created
|
||||
* @return {@code true} if recognition is available, {@code false} otherwise
|
||||
*/
|
||||
public static boolean isRecognitionAvailable(final Context context) {
|
||||
@@ -142,78 +174,61 @@ public class RecognitionManager {
|
||||
}
|
||||
|
||||
/**
|
||||
* Factory method to create a new RecognitionManager
|
||||
* Factory method to create a new {@code RecognitionManager}, please note that
|
||||
* {@link #setRecognitionListener(RecognitionListener)} must be called before dispatching any
|
||||
* command to the created {@code RecognitionManager}.
|
||||
*
|
||||
* @param context in which to create RecognitionManager
|
||||
* @param listener that will receive all the callbacks from the created
|
||||
* {@link RecognitionManager}
|
||||
* @param recognizerIntent contains initialization parameters for the speech recognizer. The
|
||||
* intent action should be {@link RecognizerIntent#ACTION_RECOGNIZE_SPEECH}. Future
|
||||
* versions of this API may add startup parameters for speech recognizer.
|
||||
* @return null if a recognition service implementation is not installed or if speech
|
||||
* recognition is not supported by the device, otherwise a new RecognitionManager is
|
||||
* returned. The created RecognitionManager can only be used after the
|
||||
* {@link RecognitionListener#onInit()} method has been called.
|
||||
* @param context in which to create {@code RecognitionManager}
|
||||
* @return a new {@code RecognitionManager}
|
||||
*/
|
||||
public static RecognitionManager createRecognitionManager(final Context context,
|
||||
final RecognitionListener listener, final Intent recognizerIntent) {
|
||||
if (context == null || recognizerIntent == null) {
|
||||
throw new IllegalArgumentException(
|
||||
"Context and recognizerListener argument cannot be null)");
|
||||
public static RecognitionManager createRecognitionManager(final Context context) {
|
||||
if (context == null) {
|
||||
throw new IllegalArgumentException("Context cannot be null)");
|
||||
}
|
||||
RecognitionManager manager = new RecognitionManager(listener, context);
|
||||
manager.mConnection = manager.new Connection();
|
||||
if (!context.bindService(recognizerIntent, manager.mConnection, Context.BIND_AUTO_CREATE)) {
|
||||
Log.e(TAG, "bind to recognition service failed");
|
||||
listener.onError(CLIENT_ERROR);
|
||||
return null;
|
||||
}
|
||||
return manager;
|
||||
checkIsCalledFromMainThread();
|
||||
return new RecognitionManager(context);
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks whether the service is connected
|
||||
*
|
||||
* @param functionName from which the call originated
|
||||
* @return {@code true} if the service was successfully initialized, {@code false} otherwise
|
||||
* Sets the listener that will receive all the callbacks. The previous unfinished commands will
|
||||
* be executed with the old listener, while any following command will be executed with the new
|
||||
* listener.
|
||||
*
|
||||
* @param listener listener that will receive all the callbacks from the created
|
||||
* {@link RecognitionManager}, this must not be null.
|
||||
*/
|
||||
private boolean connectToService(final String functionName) {
|
||||
if (mService != null) {
|
||||
return true;
|
||||
}
|
||||
if (mConnection == null) {
|
||||
if (DBG) Log.d(TAG, "restarting connection to the recognition service");
|
||||
mConnection = new Connection();
|
||||
mContext.bindService(new Intent(RecognizerIntent.ACTION_RECOGNIZE_SPEECH), mConnection,
|
||||
Context.BIND_AUTO_CREATE);
|
||||
}
|
||||
mInternalRecognitionListener.onError(MANAGER_NOT_INITIALIZED_ERROR);
|
||||
Log.e(TAG, functionName + " was called before service connection was initialized");
|
||||
return false;
|
||||
public void setRecognitionListener(RecognitionListener listener) {
|
||||
checkIsCalledFromMainThread();
|
||||
putMessage(Message.obtain(mHandler, MSG_CHANGE_LISTENER, listener));
|
||||
}
|
||||
|
||||
/**
|
||||
* Starts listening for speech.
|
||||
* Starts listening for speech. Please note that
|
||||
* {@link #setRecognitionListener(RecognitionListener)} must be called beforehand, otherwise a
|
||||
* {@link RuntimeException} will be thrown.
|
||||
*
|
||||
* @param recognizerIntent contains parameters for the recognition to be performed. The intent
|
||||
* action should be {@link RecognizerIntent#ACTION_RECOGNIZE_SPEECH}. The intent may also
|
||||
* contain optional extras, see {@link RecognizerIntent}. If these values are not set
|
||||
* explicitly, default values will be used by the recognizer.
|
||||
* may also contain optional extras, see {@link RecognizerIntent}. If these values are
|
||||
* not set explicitly, default values will be used by the recognizer.
|
||||
*/
|
||||
public void startListening(Intent recognizerIntent) {
|
||||
public void startListening(final Intent recognizerIntent) {
|
||||
if (recognizerIntent == null) {
|
||||
throw new IllegalArgumentException("recognizerIntent argument cannot be null");
|
||||
throw new IllegalArgumentException("intent must not be null");
|
||||
}
|
||||
if (!connectToService("startListening")) {
|
||||
return; // service is not connected yet, reconnect in progress
|
||||
}
|
||||
try {
|
||||
mService.startListening(recognizerIntent, mInternalRecognitionListener);
|
||||
if (DBG) Log.d(TAG, "service start listening command succeded");
|
||||
} catch (final RemoteException e) {
|
||||
Log.e(TAG, "startListening() failed", e);
|
||||
mInternalRecognitionListener.onError(CLIENT_ERROR);
|
||||
checkIsCalledFromMainThread();
|
||||
checkIsCommandAllowed();
|
||||
if (mConnection == null) { // first time connection
|
||||
mConnection = new Connection();
|
||||
if (!mContext.bindService(new Intent(RecognizerIntent.ACTION_RECOGNIZE_SPEECH),
|
||||
mConnection, Context.BIND_AUTO_CREATE)) {
|
||||
Log.e(TAG, "bind to recognition service failed");
|
||||
mConnection = null;
|
||||
mService = null;
|
||||
mListener.onError(ERROR_CLIENT);
|
||||
return;
|
||||
}
|
||||
}
|
||||
putMessage(Message.obtain(mHandler, MSG_START, recognizerIntent));
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -222,100 +237,190 @@ public class RecognitionManager {
|
||||
* called, as the speech endpointer will automatically stop the recognizer listening when it
|
||||
* determines speech has completed. However, you can manipulate endpointer parameters directly
|
||||
* using the intent extras defined in {@link RecognizerIntent}, in which case you may sometimes
|
||||
* want to manually call this method to stop listening sooner.
|
||||
* want to manually call this method to stop listening sooner. Please note that
|
||||
* {@link #setRecognitionListener(RecognitionListener)} must be called beforehand, otherwise a
|
||||
* {@link RuntimeException} will be thrown.
|
||||
*/
|
||||
public void stopListening() {
|
||||
if (mService == null) {
|
||||
return; // service is not connected, but no need to reconnect at this point
|
||||
checkIsCalledFromMainThread();
|
||||
checkIsCommandAllowed();
|
||||
putMessage(Message.obtain(mHandler, MSG_STOP));
|
||||
}
|
||||
|
||||
/**
|
||||
* Cancels the speech recognition. Please note that
|
||||
* {@link #setRecognitionListener(RecognitionListener)} must be called beforehand, otherwise a
|
||||
* {@link RuntimeException} will be thrown.
|
||||
*/
|
||||
public void cancel() {
|
||||
checkIsCalledFromMainThread();
|
||||
checkIsCommandAllowed();
|
||||
putMessage(Message.obtain(mHandler, MSG_CANCEL));
|
||||
}
|
||||
|
||||
private static void checkIsCalledFromMainThread() {
|
||||
if (Looper.myLooper() != Looper.getMainLooper()) {
|
||||
throw new RuntimeException(
|
||||
"RecognitionManager should be used only from the application's main thread");
|
||||
}
|
||||
}
|
||||
|
||||
private void checkIsCommandAllowed() {
|
||||
if (mService == null && mPendingTasks.isEmpty()) { // setListener message must be there
|
||||
throw new IllegalStateException("Listener must be set before any command is called");
|
||||
}
|
||||
}
|
||||
|
||||
private void putMessage(Message msg) {
|
||||
if (mService == null) {
|
||||
mPendingTasks.offer(msg);
|
||||
} else {
|
||||
mHandler.sendMessage(msg);
|
||||
}
|
||||
}
|
||||
|
||||
/** sends the actual message to the service */
|
||||
private void handleStartListening(Intent recognizerIntent) {
|
||||
try {
|
||||
mService.stopListening();
|
||||
mService.startListening(recognizerIntent, mListener);
|
||||
if (DBG) Log.d(TAG, "service start listening command succeded");
|
||||
} catch (final RemoteException e) {
|
||||
Log.e(TAG, "startListening() failed", e);
|
||||
mListener.onError(ERROR_CLIENT);
|
||||
}
|
||||
}
|
||||
|
||||
/** sends the actual message to the service */
|
||||
private void handleStopMessage() {
|
||||
try {
|
||||
mService.stopListening(mListener);
|
||||
if (DBG) Log.d(TAG, "service stop listening command succeded");
|
||||
} catch (final RemoteException e) {
|
||||
Log.e(TAG, "stopListening() failed", e);
|
||||
mInternalRecognitionListener.onError(CLIENT_ERROR);
|
||||
mListener.onError(ERROR_CLIENT);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Cancels the speech recognition.
|
||||
*/
|
||||
public void cancel() {
|
||||
if (mService == null) {
|
||||
return; // service is not connected, but no need to reconnect at this point
|
||||
}
|
||||
/** sends the actual message to the service */
|
||||
private void handleCancelMessage() {
|
||||
try {
|
||||
mService.cancel();
|
||||
mService.cancel(mListener);
|
||||
if (DBG) Log.d(TAG, "service cancel command succeded");
|
||||
} catch (final RemoteException e) {
|
||||
Log.e(TAG, "cancel() failed", e);
|
||||
mInternalRecognitionListener.onError(CLIENT_ERROR);
|
||||
mListener.onError(ERROR_CLIENT);
|
||||
}
|
||||
}
|
||||
|
||||
/** changes the listener */
|
||||
private void handleChangeListener(RecognitionListener listener) {
|
||||
if (DBG) Log.d(TAG, "handleChangeListener, listener=" + listener);
|
||||
mListener.mInternalListener = listener;
|
||||
}
|
||||
|
||||
/**
|
||||
* Destroys the RecognitionManager object. Note that after calling this method all method calls
|
||||
* on this object will fail, triggering {@link RecognitionListener#onError}.
|
||||
* Destroys the {@code RecognitionManager} object. Note that after calling this method all
|
||||
* method calls on this object will fail, triggering {@link RecognitionListener#onError}.
|
||||
*/
|
||||
public void destroy() {
|
||||
if (mConnection != null) {
|
||||
mContext.unbindService(mConnection);
|
||||
}
|
||||
mPendingTasks.clear();
|
||||
mService = null;
|
||||
mConnection = null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Internal wrapper of IRecognitionListener which will propagate the results
|
||||
* to RecognitionListener
|
||||
* Internal wrapper of IRecognitionListener which will propagate the results to
|
||||
* RecognitionListener
|
||||
*/
|
||||
private class InternalRecognitionListener extends IRecognitionListener.Stub {
|
||||
private class InternalListener extends IRecognitionListener.Stub {
|
||||
private RecognitionListener mInternalListener;
|
||||
|
||||
private final static int MSG_BEGINNING_OF_SPEECH = 1;
|
||||
private final static int MSG_BUFFER_RECEIVED = 2;
|
||||
private final static int MSG_END_OF_SPEECH = 3;
|
||||
private final static int MSG_ERROR = 4;
|
||||
private final static int MSG_READY_FOR_SPEECH = 5;
|
||||
private final static int MSG_RESULTS = 6;
|
||||
private final static int MSG_PARTIAL_RESULTS = 7;
|
||||
private final static int MSG_RMS_CHANGED = 8;
|
||||
private final static int MSG_ON_EVENT = 9;
|
||||
|
||||
private final Handler mInternalHandler = new Handler() {
|
||||
@Override
|
||||
public void handleMessage(Message msg) {
|
||||
if (mInternalListener == null) {
|
||||
return;
|
||||
}
|
||||
switch (msg.what) {
|
||||
case MSG_BEGINNING_OF_SPEECH:
|
||||
mInternalListener.onBeginningOfSpeech();
|
||||
break;
|
||||
case MSG_BUFFER_RECEIVED:
|
||||
mInternalListener.onBufferReceived((byte[]) msg.obj);
|
||||
break;
|
||||
case MSG_END_OF_SPEECH:
|
||||
mInternalListener.onEndOfSpeech();
|
||||
break;
|
||||
case MSG_ERROR:
|
||||
mInternalListener.onError((Integer) msg.obj);
|
||||
break;
|
||||
case MSG_READY_FOR_SPEECH:
|
||||
mInternalListener.onReadyForSpeech((Bundle) msg.obj);
|
||||
break;
|
||||
case MSG_RESULTS:
|
||||
mInternalListener.onResults((Bundle) msg.obj);
|
||||
break;
|
||||
case MSG_PARTIAL_RESULTS:
|
||||
mInternalListener.onPartialResults((Bundle) msg.obj);
|
||||
break;
|
||||
case MSG_RMS_CHANGED:
|
||||
mInternalListener.onRmsChanged((Float) msg.obj);
|
||||
break;
|
||||
case MSG_ON_EVENT:
|
||||
mInternalListener.onEvent(msg.arg1, (Bundle) msg.obj);
|
||||
break;
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
public void onBeginningOfSpeech() {
|
||||
if (mListener != null) {
|
||||
mListener.onBeginningOfSpeech();
|
||||
}
|
||||
Message.obtain(mInternalHandler, MSG_BEGINNING_OF_SPEECH).sendToTarget();
|
||||
}
|
||||
|
||||
public void onBufferReceived(final byte[] buffer) {
|
||||
if (mListener != null) {
|
||||
mListener.onBufferReceived(buffer);
|
||||
}
|
||||
Message.obtain(mInternalHandler, MSG_BUFFER_RECEIVED, buffer).sendToTarget();
|
||||
}
|
||||
|
||||
public void onEndOfSpeech() {
|
||||
if (mListener != null) {
|
||||
mListener.onEndOfSpeech();
|
||||
}
|
||||
Message.obtain(mInternalHandler, MSG_END_OF_SPEECH).sendToTarget();
|
||||
}
|
||||
|
||||
public void onError(final int error) {
|
||||
if (mListener != null) {
|
||||
mListener.onError(error);
|
||||
}
|
||||
Message.obtain(mInternalHandler, MSG_ERROR, error).sendToTarget();
|
||||
}
|
||||
|
||||
public void onReadyForSpeech(final Bundle noiseParams) {
|
||||
if (mListener != null) {
|
||||
mListener.onReadyForSpeech(noiseParams);
|
||||
}
|
||||
Message.obtain(mInternalHandler, MSG_READY_FOR_SPEECH, noiseParams).sendToTarget();
|
||||
}
|
||||
|
||||
public void onResults(final Bundle results) {
|
||||
if (mListener != null) {
|
||||
mListener.onResults(results);
|
||||
}
|
||||
Message.obtain(mInternalHandler, MSG_RESULTS, results).sendToTarget();
|
||||
}
|
||||
|
||||
public void onPartialResults(final Bundle results) {
|
||||
if (mListener != null) {
|
||||
mListener.onPartialResults(results);
|
||||
}
|
||||
Message.obtain(mInternalHandler, MSG_PARTIAL_RESULTS, results).sendToTarget();
|
||||
}
|
||||
|
||||
public void onRmsChanged(final float rmsdB) {
|
||||
if (mListener != null) {
|
||||
mListener.onRmsChanged(rmsdB);
|
||||
}
|
||||
Message.obtain(mInternalHandler, MSG_RMS_CHANGED, rmsdB).sendToTarget();
|
||||
}
|
||||
|
||||
public void onEvent(final int eventType, final Bundle params) {
|
||||
Message.obtain(mInternalHandler, MSG_ON_EVENT, eventType, eventType, params)
|
||||
.sendToTarget();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
295
core/java/android/speech/RecognitionService.java
Normal file
295
core/java/android/speech/RecognitionService.java
Normal file
@@ -0,0 +1,295 @@
|
||||
/*
|
||||
* Copyright (C) 2010 The Android Open Source Project
|
||||
*
|
||||
* 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 android.speech;
|
||||
|
||||
import android.app.Service;
|
||||
import android.content.Intent;
|
||||
import android.content.pm.PackageManager;
|
||||
import android.os.Bundle;
|
||||
import android.os.Handler;
|
||||
import android.os.IBinder;
|
||||
import android.os.Message;
|
||||
import android.os.RemoteException;
|
||||
import android.util.Log;
|
||||
|
||||
/**
|
||||
* This class provides a base class for recognition service implementations. This class should be
|
||||
* extended only in case you wish to implement a new speech recognizer. Please not that the
|
||||
* implementation of this service is state-less.
|
||||
*/
|
||||
public abstract class RecognitionService extends Service {
|
||||
|
||||
/** Log messages identifier */
|
||||
private static final String TAG = "RecognitionService";
|
||||
|
||||
/** Debugging flag */
|
||||
private static final boolean DBG = false;
|
||||
|
||||
/**
|
||||
* The current callback of an application that invoked the
|
||||
* {@link RecognitionService#onStartListening(Intent, Callback)} method
|
||||
*/
|
||||
private Callback mCurrentCallback = null;
|
||||
|
||||
private static final int MSG_START_LISTENING = 1;
|
||||
|
||||
private static final int MSG_STOP_LISTENING = 2;
|
||||
|
||||
private static final int MSG_CANCEL = 3;
|
||||
|
||||
private final Handler mHandler = new Handler() {
|
||||
@Override
|
||||
public void handleMessage(Message msg) {
|
||||
switch (msg.what) {
|
||||
case MSG_START_LISTENING:
|
||||
StartListeningArgs args = (StartListeningArgs) msg.obj;
|
||||
dispatchStartListening(args.mIntent, args.mListener);
|
||||
break;
|
||||
case MSG_STOP_LISTENING:
|
||||
dispatchStopListening((IRecognitionListener) msg.obj);
|
||||
break;
|
||||
case MSG_CANCEL:
|
||||
dispatchCancel((IRecognitionListener) msg.obj);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
private void dispatchStartListening(Intent intent, IRecognitionListener listener) {
|
||||
if (mCurrentCallback == null) {
|
||||
if (DBG) Log.d(TAG, "created new mCurrentCallback, listener = " + listener.asBinder());
|
||||
mCurrentCallback = new Callback(listener);
|
||||
RecognitionService.this.onStartListening(intent, mCurrentCallback);
|
||||
} else {
|
||||
try {
|
||||
listener.onError(RecognitionManager.ERROR_RECOGNIZER_BUSY);
|
||||
} catch (RemoteException e) {
|
||||
Log.d(TAG, "onError call from startListening failed");
|
||||
}
|
||||
Log.i(TAG, "concurrent startListening received - ignoring this call");
|
||||
}
|
||||
}
|
||||
|
||||
private void dispatchStopListening(IRecognitionListener listener) {
|
||||
try {
|
||||
if (mCurrentCallback == null) {
|
||||
listener.onError(RecognitionManager.ERROR_CLIENT);
|
||||
Log.w(TAG, "stopListening called with no preceding startListening - ignoring");
|
||||
} else if (mCurrentCallback.mListener.asBinder() != listener.asBinder()) {
|
||||
listener.onError(RecognitionManager.ERROR_RECOGNIZER_BUSY);
|
||||
Log.w(TAG, "stopListening called by other caller than startListening - ignoring");
|
||||
} else { // the correct state
|
||||
RecognitionService.this.onStopListening(mCurrentCallback);
|
||||
}
|
||||
} catch (RemoteException e) { // occurs if onError fails
|
||||
Log.d(TAG, "onError call from stopListening failed");
|
||||
}
|
||||
}
|
||||
|
||||
private void dispatchCancel(IRecognitionListener listener) {
|
||||
if (mCurrentCallback == null) {
|
||||
Log.w(TAG, "cancel called with no preceding startListening - ignoring");
|
||||
} else if (mCurrentCallback.mListener.asBinder() != listener.asBinder()) {
|
||||
Log.w(TAG, "cancel called by client who did not call startListening - ignoring");
|
||||
} else { // the correct state
|
||||
RecognitionService.this.onCancel(mCurrentCallback);
|
||||
mCurrentCallback = null;
|
||||
if (DBG) Log.d(TAG, "canceling - setting mCurrentCallback to null");
|
||||
}
|
||||
}
|
||||
|
||||
private class StartListeningArgs {
|
||||
public final Intent mIntent;
|
||||
|
||||
public final IRecognitionListener mListener;
|
||||
|
||||
public StartListeningArgs(Intent intent, IRecognitionListener listener) {
|
||||
this.mIntent = intent;
|
||||
this.mListener = listener;
|
||||
}
|
||||
}
|
||||
|
||||
/** Binder of the recognition service */
|
||||
private final IRecognitionService.Stub mBinder = new IRecognitionService.Stub() {
|
||||
public void startListening(Intent recognizerIntent, IRecognitionListener listener) {
|
||||
if (DBG) Log.d(TAG, "startListening called by:" + listener.asBinder());
|
||||
if (checkPermissions(listener)) {
|
||||
mHandler.sendMessage(Message.obtain(mHandler, MSG_START_LISTENING,
|
||||
new StartListeningArgs(recognizerIntent, listener)));
|
||||
}
|
||||
}
|
||||
|
||||
public void stopListening(IRecognitionListener listener) {
|
||||
if (DBG) Log.d(TAG, "stopListening called by:" + listener.asBinder());
|
||||
if (checkPermissions(listener)) {
|
||||
mHandler.sendMessage(Message.obtain(mHandler, MSG_STOP_LISTENING, listener));
|
||||
}
|
||||
}
|
||||
|
||||
public void cancel(IRecognitionListener listener) {
|
||||
if (DBG) Log.d(TAG, "cancel called by:" + listener.asBinder());
|
||||
if (checkPermissions(listener)) {
|
||||
mHandler.sendMessage(Message.obtain(mHandler, MSG_CANCEL, listener));
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* Checks whether the caller has sufficient permissions
|
||||
*
|
||||
* @param listener to send the error message to in case of error
|
||||
* @return {@code true} if the caller has enough permissions, {@code false} otherwise
|
||||
*/
|
||||
private boolean checkPermissions(IRecognitionListener listener) {
|
||||
if (DBG) Log.d(TAG, "checkPermissions");
|
||||
if (RecognitionService.this.checkCallingOrSelfPermission(android.Manifest.permission.
|
||||
RECORD_AUDIO) == PackageManager.PERMISSION_GRANTED) {
|
||||
return true;
|
||||
}
|
||||
try {
|
||||
Log.e(TAG, "call for recognition service without RECORD_AUDIO permissions");
|
||||
listener.onError(RecognitionManager.ERROR_INSUFFICIENT_PERMISSIONS);
|
||||
} catch (RemoteException re) {
|
||||
Log.e(TAG, "sending ERROR_INSUFFICIENT_PERMISSIONS message failed", re);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Notifies the service that it should start listening for speech.
|
||||
*
|
||||
* @param recognizerIntent contains parameters for the recognition to be performed. The intent
|
||||
* may also contain optional extras, see {@link RecognizerIntent}. If these values are
|
||||
* not set explicitly, default values should be used by the recognizer.
|
||||
* @param listener that will receive the service's callbacks
|
||||
*/
|
||||
protected abstract void onStartListening(Intent recognizerIntent, Callback listener);
|
||||
|
||||
/**
|
||||
* Notifies the service that it should cancel the speech recognition.
|
||||
*/
|
||||
protected abstract void onCancel(Callback listener);
|
||||
|
||||
/**
|
||||
* Notifies the service that it should stop listening for speech. Speech captured so far should
|
||||
* be recognized as if the user had stopped speaking at this point. This method is only called
|
||||
* if the application calls it explicitly.
|
||||
*/
|
||||
protected abstract void onStopListening(Callback listener);
|
||||
|
||||
@Override
|
||||
public final IBinder onBind(final Intent intent) {
|
||||
if (DBG) Log.d(TAG, "onBind, intent=" + intent);
|
||||
return mBinder;
|
||||
}
|
||||
|
||||
/**
|
||||
* This class receives callbacks from the speech recognition service and forwards them to the
|
||||
* user. An instance of this class is passed to the
|
||||
* {@link RecognitionService#onStartListening(Intent, Callback)} method. Recognizers may call
|
||||
* these methods on any thread.
|
||||
*/
|
||||
public class Callback {
|
||||
private final IRecognitionListener mListener;
|
||||
|
||||
private Callback(IRecognitionListener listener) {
|
||||
mListener = listener;
|
||||
}
|
||||
|
||||
/**
|
||||
* The service should call this method when the user has started to speak.
|
||||
*/
|
||||
public void beginningOfSpeech() throws RemoteException {
|
||||
if (DBG) Log.d(TAG, "beginningOfSpeech");
|
||||
mListener.onBeginningOfSpeech();
|
||||
}
|
||||
|
||||
/**
|
||||
* The service should call this method when sound has been received. The purpose of this
|
||||
* function is to allow giving feedback to the user regarding the captured audio.
|
||||
*
|
||||
* @param buffer a buffer containing a sequence of big-endian 16-bit integers representing a
|
||||
* single channel audio stream. The sample rate is implementation dependent.
|
||||
*/
|
||||
public void bufferReceived(byte[] buffer) throws RemoteException {
|
||||
mListener.onBufferReceived(buffer);
|
||||
}
|
||||
|
||||
/**
|
||||
* The service should call this method after the user stops speaking.
|
||||
*/
|
||||
public void endOfSpeech() throws RemoteException {
|
||||
mListener.onEndOfSpeech();
|
||||
}
|
||||
|
||||
/**
|
||||
* The service should call this method when a network or recognition error occurred.
|
||||
*
|
||||
* @param error code is defined in {@link RecognitionManager}
|
||||
*/
|
||||
public void error(int error) throws RemoteException {
|
||||
mCurrentCallback = null;
|
||||
mListener.onError(error);
|
||||
}
|
||||
|
||||
/**
|
||||
* The service should call this method when partial recognition results are available. This
|
||||
* method can be called at any time between {@link #beginningOfSpeech()} and
|
||||
* {@link #results(Bundle)} when partial results are ready. This method may be called zero,
|
||||
* one or multiple times for each call to {@link RecognitionManager#startListening(Intent)},
|
||||
* depending on the speech recognition service implementation.
|
||||
*
|
||||
* @param partialResults the returned results. To retrieve the results in
|
||||
* ArrayList<String> format use {@link Bundle#getStringArrayList(String)} with
|
||||
* {@link RecognitionManager#RESULTS_RECOGNITION} as a parameter
|
||||
*/
|
||||
public void partialResults(Bundle partialResults) throws RemoteException {
|
||||
mListener.onPartialResults(partialResults);
|
||||
}
|
||||
|
||||
/**
|
||||
* The service should call this method when the endpointer is ready for the user to start
|
||||
* speaking.
|
||||
*
|
||||
* @param params parameters set by the recognition service. Reserved for future use.
|
||||
*/
|
||||
public void readyForSpeech(Bundle params) throws RemoteException {
|
||||
mListener.onReadyForSpeech(params);
|
||||
}
|
||||
|
||||
/**
|
||||
* The service should call this method when recognition results are ready.
|
||||
*
|
||||
* @param results the recognition results. To retrieve the results in {@code
|
||||
* ArrayList<String>} format use {@link Bundle#getStringArrayList(String)} with
|
||||
* {@link RecognitionManager#RESULTS_RECOGNITION} as a parameter
|
||||
*/
|
||||
public void results(Bundle results) throws RemoteException {
|
||||
mCurrentCallback = null;
|
||||
mListener.onResults(results);
|
||||
}
|
||||
|
||||
/**
|
||||
* The service should call this method when the sound level in the audio stream has changed.
|
||||
* There is no guarantee that this method will be called.
|
||||
*
|
||||
* @param rmsdB the new RMS dB value
|
||||
*/
|
||||
public void rmsChanged(float rmsdB) throws RemoteException {
|
||||
mListener.onRmsChanged(rmsdB);
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user