I created a simple speech recognition service: for this purpose I created a subclass of android.speech.RecognitionService
and I created an activity to start and stop this service.
My custom speech recognition service trivially uses the default speech recognizer, because my goal is simply to understand how the RecognitionService
and RecognitionService.Callback
classes work.
public class SimpleVoiceService extends RecognitionService {
private SpeechRecognizer m_EngineSR;
@Override
public void onCreate() {
super.onCreate();
Log.i("SimpleVoiceService", "Service started");
}
@Override
public void onDestroy() {
super.onDestroy();
Log.i("SimpleVoiceService", "Service stopped");
}
@Override
protected void onCancel(Callback listener) {
m_EngineSR.cancel();
}
@Override
protected void onStartListening(Intent recognizerIntent, Callback listener) {
m_EngineSR.setRecognitionListener(new VoiceResultsListener(listener));
m_EngineSR.startListening(recognizerIntent);
}
@Override
protected void onStopListening(Callback listener) {
m_EngineSR.stopListening();
}
/**
*
*/
private class VoiceResultsListener implements RecognitionListener {
private Callback m_UserSpecifiedListener;
/**
*
* @param userSpecifiedListener
*/
public VoiceResultsListener(Callback userSpecifiedListener) {
m_UserSpecifiedListener = userSpecifiedListener;
}
@Override
public void onBeginningOfSpeech() {
try {
m_UserSpecifiedListener.beginningOfSpeech();
} catch (RemoteException e) {
e.printStackTrace();
}
}
@Override
public void onBufferReceived(byte[] buffer) {
try {
m_UserSpecifiedListener.bufferReceived(buffer);
} catch (RemoteException e) {
e.printStackTrace();
}
}
@Override
public void onEndOfSpeech() {
try {
m_UserSpecifiedListener.endOfSpeech();
} catch (RemoteException e) {
e.printStackTrace();
}
}
@Override
public void onError(int error) {
try {
m_UserSpecifiedListener.error(error);
} catch (RemoteException e) {
e.printStackTrace();
}
}
@Override
public void onEvent(int eventType, Bundle params) { ; }
@Override
public void onPartialResults(Bundle partialResults) {
try {
m_UserSpecifiedListener.partialResults(partialResults);
} catch (RemoteException e) {
e.printStackTrace();
}
}
@Override
public void onReadyForSpeech(Bundle params) {
try {
m_UserSpecifiedListener.readyForSpeech(params);
} catch (RemoteException e) {
e.printStackTrace();
}
}
@Override
public void onResults(Bundle results) {
try {
m_UserSpecifiedListener.results(results);
} catch (RemoteException e) {
e.printStackTrace();
}
}
@Override
public void onRmsChanged(float rmsdB) {
try {
m_UserSpecifiedListener.rmsChanged(rmsdB);
} catch (RemoteException e) {
e.printStackTrace();
}
}
}
}
I start and stop the service using the following activity.
public class VoiceServiceStarterActivity extends Activity {
/** Called when the activity is first created. */
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
Button startButton = new Button(this);
startButton.setText("Start the service");
startButton.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) { startVoiceService(); }
});
Button stopButton = new Button(this);
stopButton.setText("Stop the service");
stopButton.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) { stopVoiceService(); }
});
LinearLayout layout = new LinearLayout(this);
layout.setOrientation(LinearLayout.VERTICAL);
layout.addView(startButton);
layout.addView(stopButton);
setContentView(layout);
}
private void startVoiceService() {
startService(new Intent(this, SimpleVoiceService.class));
}
private void stopVoiceService() {
stopService(new Intent(this, SimpleVoiceService.class));
}
}
Finally I declared my service on the AndroidManifest.xml
(see VoiceRecognition sample within Android SDK folder).
<service android:name="SimpleVoiceService"
android:label="@string/service_name" >
<intent-filter>
<action android:name="android.speech.RecognitionService" />
<category android:name="android.intent.category.DEFAULT" />
</intent-filter>
</service>
Then I installed this application on an Android device and I start it:
- when I start the service, it starts properly;
- when I stop it, it stops properly.
But if I launch the following code in a another activity, the activities
List
contains only an element, which is the default speech recognizer.
PackageManager pm = getPackageManager();
List<ResolveInfo> activities = pm.queryIntentActivities(
new Intent(RecognizerIntent.ACTION_RECOGNIZE_SPEECH), 0);
Why is my speech recognizer not returned among those present in the system?
See Question&Answers more detail:
os 与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…