2012-04-03 65 views
7

我創建了一個簡單的語音識別服務:爲此,我創建了一個android.speech.RecognitionService的子類,並創建了一個活動來啓動和停止此服務。如何註冊自定義語音識別服務?

我的自定義語音識別服務平凡使用默認的語音識別器,因爲我的目標只是瞭解RecognitionServiceRecognitionService.Callback類如何工作。

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(); 
      } 
     } 
    } 

} 

我使用以下活動啓動和停止服務。

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)); 
    } 
} 

最後,我宣佈我對AndroidManifest.xml服務(見Android SDK中的文件夾內VoiceRecognition樣品)。

<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> 

然後我安裝在Android設備上這個應用程序,我啓動它: - 當我啓動該服務,它正常啓動; - 當我停下來時,它會正常停止。

但是,如果我在另一活動中啓動以下代碼,則activitiesList僅包含一個元素,它是默認的語音識別器。

PackageManager pm = getPackageManager(); 
List<ResolveInfo> activities = pm.queryIntentActivities(
      new Intent(RecognizerIntent.ACTION_RECOGNIZE_SPEECH), 0); 

爲什麼我的語音識別器不能在系統中存在的人之間返回?

+1

這是否讓我們重寫「谷歌現在」默認RecognitionService?我的意思是,我現在可以將我自己的擴展識別服務掛鉤到Google嗎? – 2014-12-09 18:51:09

+1

當您啓動SimpleVoiceSearch服務時,您的onStartListening是否已開始工作? @ enzom83 – 2016-10-09 07:34:46

回答

7

如果你想queryIntentActivities(new Intent(RecognizerIntent.ACTION_RECOGNIZE_SPEECH), 0)拿起你的活動(VoiceServiceStarterActivity),那麼你必須在你的應用清單聲明,此活動處理RecognizerIntent.ACTION_RECOGNIZE_SPEECH,這樣

<activity android:name="VoiceServiceStarterActivity"> 
    <intent-filter> 
    <action android:name="android.speech.action.RECOGNIZE_SPEECH" /> 
    <category android:name="android.intent.category.DEFAULT" /> 
    </intent-filter> 
    ... 
</activity> 

對於更具體的代碼看一下項目Kõnelesource code),其本質上是經由該語音識別設置Android上的接口的一個開源實現,即,它涵蓋:

  • ACTION_RECOGNIZE_語音
  • ACTION_WEB_SEARCH
  • RecognitionService

,並使用開源的語音識別服務器。

+1

我不明白爲什麼我應該創建一個新的活動。目前我有一個活動('VoiceDemoActivity'),通過'SpeechRecognizer'對象處理默認語音識別器。爲了使用自定義語音識別服務,我必須在'createSpeechRecognizer'方法中創建一個新的'SpeechRecognizer'對象來指定一個'ComponentName'對象:我想這個'ComponentName'應該引用自定義語音識別器服務,所以我創建了一個新的'RecognitionService'類。爲什麼我需要實現另一個可以處理'ACTION_RECOGNIZE_SPEECH'意圖的活動? – enzom83 2012-04-05 13:49:40

+2

我改進了一點我的答案,也許它更清晰一點。 – Kaarel 2012-04-05 17:07:47

+0

@Kaarel我真的很喜歡你在Kõnele做的事(儘管我不知道愛沙尼亞語)。我從github下載了源代碼,以便通過示例學習如何實現我自己的(僅限英文版),但它不會構建開箱即用,並且發佈的應用程序本身(從Google Play下載)陷入*「轉錄」。 ..「*。我在哪裏可以瞭解更多關於代碼結構的知識(3種不同的軟件包)和*爲什麼*它是按照它的方式實現的?謝謝! – ripopenid 2013-11-08 01:46:47

0

是的,你需要使用createSpeechRecognizer(上下文的背景下,組件名稱的ServiceComponent)