I created a simple speech recognition service: for this purpose I created a subclass of android.speech.RecognitionService , and I created an action 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; 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 operation.
public class VoiceServiceStarterActivity extends Activity { @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 announced my service on AndroidManifest.xml (see the VoiceRecognition sample in the 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 the Android device and started it: - when I start the service, it starts correctly; - when I stop him, he stops properly.
But if I ran the following code in another action, the activities List contains only the element, which is the default speech recognizer.
PackageManager pm = getPackageManager(); List<ResolveInfo> activities = pm.queryIntentActivities( new Intent(RecognizerIntent.ACTION_RECOGNIZE_SPEECH), 0);
Why does my speech recognizer not return among those present in the system?