質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.48%
Android

Androidは、Google社が開発したスマートフォンやタブレットなど携帯端末向けのプラットフォームです。 カーネル・ミドルウェア・ユーザーインターフェイス・ウェブブラウザ・電話帳などのアプリケーションやソフトウェアをひとつにまとめて構成。 カーネル・ライブラリ・ランタイムはほとんどがC言語/C++、アプリケーションなどはJavaSEのサブセットとAndroid環境で書かれています。

Q&A

解決済

1回答

9811閲覧

androidでbluetoothヘッドセットで音声認識&読み上げがしたい

Feynman

総合スコア19

Android

Androidは、Google社が開発したスマートフォンやタブレットなど携帯端末向けのプラットフォームです。 カーネル・ミドルウェア・ユーザーインターフェイス・ウェブブラウザ・電話帳などのアプリケーションやソフトウェアをひとつにまとめて構成。 カーネル・ライブラリ・ランタイムはほとんどがC言語/C++、アプリケーションなどはJavaSEのサブセットとAndroid環境で書かれています。

0グッド

0クリップ

投稿2016/10/09 00:09

編集2016/10/10 01:00

androidで音声認識をするために以下のようなプログラムを書いたのですが、音声認識が始まった後の文章も途中からしか認識しなかったり、文章の読み上げが途中から聞こえたりします。そのタイミングもまちまちです。
そもそもこんな方法で良いのかも含め教えていただけたら幸いです。
Bluetoothを使わない状態での音声認識、読み上げは上手くいきます。

動作は、
Bluetoothヘッドセットのボタンを押す
→ BroadcastReceiverで受け取りbluetoothHeadset.startVoiceRecognitionを行う
→ mHeadsetBroadcastReceiverでbluetoothがAUDIO_CONNECTEDを受け取り
音声認識を開始
→ 音声認識が成功したらTextToSpeechを実行
→ bluetoothHeadset.stopVoiceRecognitionでヘッドセットとの接続を終了

Java

1 private SpeechRecognizer sr; 2 private TextToSpeech tts; 3 private String ttsString; 4 5 private BluetoothHeadset mBluetoothHeadset; 6 private boolean isBluetoothConnected; 7 private BluetoothDevice bluetoothDevice; 8 9 public static MediaButtonIntentReceiver AMButtonReciever = null; 10 11 @Override 12 protected void onCreate(Bundle savedInstanceState) { 13//TTS初期化 14 tts = new TextToSpeech(this, this); 15 tts.setOnUtteranceProgressListener(new UtteranceProgressListener() { 16 @Override 17 public void onDone(String utteranceId) { 18 mBluetoothHeadset.stopVoiceRecognition(bluetoothDevice); 19 } 20 @Override 21 public void onError(String utteranceId) {} 22 @Override 23 public void onStart(String utteranceId) {} 24 }); 25 26// Bluetoothヘッドセットのボタンイベント 27 if(AMButtonReciever != null){ 28 unregisterReceiver(AMButtonReciever); 29 AMButtonReciever = null; 30 } 31 AMButtonReciever = new MediaButtonIntentReceiver(); 32 IntentFilter filter = new IntentFilter(Intent.ACTION_MEDIA_BUTTON); 33 MediaButtonIntentReceiver r = new MediaButtonIntentReceiver(); 34 filter.setPriority(1000); 35 registerReceiver(AMButtonReciever, filter); 36 37// Bluetoothの接続状況 38 registerReceiver(mHeadsetBroadcastReceiver, new IntentFilter(BluetoothHeadset.ACTION_CONNECTION_STATE_CHANGED)); 39 registerReceiver(mHeadsetBroadcastReceiver, new IntentFilter(BluetoothHeadset.ACTION_AUDIO_STATE_CHANGED)); 40 41 BluetoothAdapter bluetoothAdapter = BluetoothAdapter.getDefaultAdapter(); 42 bluetoothAdapter.getProfileProxy(this, mProfileListener, BluetoothProfile.HEADSET); 43 44 }//onCreate 45 46private BroadcastReceiver mHeadsetBroadcastReceiver = new BroadcastReceiver() { 47 public void onReceive(Context context, Intent intent) { 48 String action = intent.getAction(); 49 int state; 50 if (action.equals(BluetoothHeadset.ACTION_CONNECTION_STATE_CHANGED)) { 51 state = intent.getIntExtra(BluetoothHeadset.EXTRA_STATE, 52 BluetoothHeadset.STATE_DISCONNECTED); 53 if (state == BluetoothHeadset.STATE_CONNECTED) { 54 } else if (state == BluetoothHeadset.STATE_DISCONNECTED) {} 55 } else { 56 state = intent.getIntExtra(BluetoothHeadset.EXTRA_STATE, BluetoothHeadset.STATE_AUDIO_DISCONNECTED); 57 if (state == BluetoothHeadset.STATE_AUDIO_CONNECTED) { 58 59 try{ 60 Intent intentSR = new Intent(RecognizerIntent.ACTION_RECOGNIZE_SPEECH); 61 intentSR.putExtra(RecognizerIntent.EXTRA_LANGUAGE_MODEL, 62 RecognizerIntent.LANGUAGE_MODEL_FREE_FORM); 63 intentSR.putExtra(RecognizerIntent.EXTRA_PARTIAL_RESULTS, true); 64 intentSR.putExtra(RecognizerIntent.EXTRA_PROMPT, "話してください"); 65 intentSR.putExtra(RecognizerIntent.EXTRA_PREFER_OFFLINE, true); 66 67 sr.startListening(intentSR); 68 }catch(Exception ex){ 69 Toast.makeText(getApplicationContext(), "error", 70 Toast.LENGTH_LONG).show(); 71 } 72 73 } else if (state == BluetoothHeadset.STATE_AUDIO_DISCONNECTED) { 74 } 75 76 } 77 } 78 }; 79 80 private BluetoothProfile.ServiceListener mProfileListener = new BluetoothProfile.ServiceListener() { 81 public void onServiceConnected(int profile, BluetoothProfile proxy) { 82 if (profile == BluetoothProfile.HEADSET) { 83 mBluetoothHeadset = (BluetoothHeadset) proxy; 84 List<BluetoothDevice> devices = mBluetoothHeadset.getConnectedDevices(); 85 if(devices.size() > 0){ 86 isBluetoothConnected = true; 87 bluetoothDevice = devices.get(0); 88 } 89 } 90 } 91 public void onServiceDisconnected(int profile) { 92 if (profile == BluetoothProfile.HEADSET) { 93 mBluetoothHeadset = null; 94 } 95 } 96 }; 97 98// メディアボタンが押された時 99 public class MediaButtonIntentReceiver extends BroadcastReceiver { 100 @Override 101 public void onReceive(Context context, Intent intent) { 102 String intentAction = intent.getAction(); 103 if (!Intent.ACTION_MEDIA_BUTTON.equals(intentAction)) { 104 return; 105 } 106 KeyEvent event = (KeyEvent)intent.getParcelableExtra(Intent.EXTRA_KEY_EVENT); 107 if (event == null) { 108 return; 109 } 110 int action = event.getAction(); 111 if (action == KeyEvent.ACTION_DOWN) { 112 if (sr == null) { 113 sr = SpeechRecognizer.createSpeechRecognizer(this); 114 sr.setRecognitionListener(new listener()); 115 } 116 if (tts.isSpeaking()) { 117 tts.stop(); // 読み上げ中なら止める 118 } 119 120 mBluetoothHeadset.startVoiceRecognition(bluetoothDevice); 121 abortBroadcast(); 122 } 123 } 124 125 126 // TextToSpeech 127 @Override 128 public void onInit(int status) { 129 if (TextToSpeech.SUCCESS == status) { 130 Locale locale = Locale.JAPANESE; 131 if (tts.isLanguageAvailable(locale) >= TextToSpeech.LANG_AVAILABLE) { 132 tts.setLanguage(locale); 133 } else { 134 } 135 } else { 136 } 137 } 138 139 private void speechText() { 140 if (0 < string.length()) { 141 if (tts.isSpeaking()) { 142 tts.stop();// 読み上げ中なら止める 143 } 144 Bundle bundle = new Bundle(); 145 bundle.putString(TextToSpeech.Engine.KEY_PARAM_STREAM, String.valueOf(AudioManager.STREAM_VOICE_CALL)); 146 tts.speak(ttsString, TextToSpeech.QUEUE_FLUSH, bundle, utteranceId); 147 } 148 } 149 150 // 音声認識を終了する 151 protected void stopListening() { 152 if (sr != null) sr.destroy(); 153 sr = null; 154 } 155 156 // 音声認識を再開する 157 public void restartListeningService() { 158 stopListening(); 159 startListening(); 160 } 161 162 // RecognitionListenerの定義 163 class listener implements RecognitionListener { 164 public void onBeginningOfSpeech() {} 165 166 public void onBufferReceived(byte[] buffer) {} 167 168 public void onEndOfSpeech() {} 169 170 public void onError(int error) { 171 mBluetoothHeadset.stopVoiceRecognition(bluetoothDevice); 172 stopListening(); 173 } 174 175 public void onEvent(int eventType, Bundle params) {} 176 177 public void onPartialResults(Bundle partialResults) {} 178 179 public void onReadyForSpeech(Bundle params) { 180 Toast.makeText(getApplicationContext(), "話してください", 181 Toast.LENGTH_SHORT).show(); 182 } 183 184 public void onResults(Bundle results) { 185 stopListening(); 186 ArrayList results_array = results.getStringArrayList( 187 SpeechRecognizer.RESULTS_RECOGNITION); 188 String resultsString = ""; 189 for (int i = 0; i < results_array.size(); i++) { 190 resultsString += results_array.get(i) + ";"; 191 } 192 ttsString = resultsString; 193 speechText(); 194 } 195 public void onRmsChanged(float rmsdB) {} 196 } 197

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

guest

回答1

0

自己解決

ネット上の記事ではaudioManagerの以下のものよりも
audioManager.startBluetoothSco();
audioManager.setBluetoothScoOn(true);
bluetoothHeadset.startVoiceRecognitionの方が上手くいくという話があった。
http://android.roof-balcony.com/bluetooth/sip_bluetooth/)
実際、参考サイトにもあるように
APIレベル11以上だとstartVoiceRecognitionで良いように思える。

しかし、実験した環境では、startVoiceRecognitionでは
音質が突然良くなったり悪くなったりと定まらなかったりした。
一方で、audioManager.startBluetoothScoでは(SCOだから当然)音質が低いモードであるが、
確実に接続することができた。
こちらは最新のAPIレベルでも使えるので、startVoiceRecognitionが上手くいかない場合は
こちらを使ってみると良いかもしれません。

投稿2016/10/19 05:48

編集2016/10/19 06:20
Feynman

総合スコア19

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.48%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問