Go to the documentation of this file.00001 package com.riverlab.robotmanager.voice_recognition;
00002
00003 import java.util.ArrayList;
00004 import java.util.HashMap;
00005
00006 import android.bluetooth.BluetoothAdapter;
00007 import android.bluetooth.BluetoothDevice;
00008 import android.content.Context;
00009 import android.content.Intent;
00010 import android.os.Handler;
00011 import android.os.HandlerThread;
00012 import android.os.Message;
00013 import android.os.Parcelable;
00014
00015 import com.google.glass.input.VoiceInputHelper;
00016 import com.google.glass.input.VoiceListener;
00017 import com.google.glass.logging.FormattingLogger;
00018 import com.google.glass.logging.FormattingLoggers;
00019 import com.google.glass.logging.Log;
00020 import com.google.glass.voice.VoiceCommand;
00021 import com.google.glass.voice.VoiceConfig;
00022 import com.riverlab.robotmanager.MainActivity;
00023 import com.riverlab.robotmanager.RobotManagerApplication;
00024 import com.riverlab.robotmanager.bluetooth.ConnectedThread;
00025 import com.riverlab.robotmanager.robot.Robot;
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037
00038 public class VoiceRecognitionThread extends HandlerThread
00039 {
00040
00041 private RobotManagerApplication mApplication;
00042 private BluetoothAdapter mBluetoothAdapter;
00043 private Context mContext;
00044
00045
00046 private boolean isShutdown = false;
00047 private boolean isListening = true;
00048 private boolean isConnected = false;
00049 private boolean usingSystemCommands = false;
00050
00051
00052 private VoiceInputHelper mVoiceInputHelper;
00053 private VoiceConfig mVoiceConfig;
00054 private ArrayList<String> mSystemCommands;
00055 private ArrayList<String> mConnectCommands;
00056 private ArrayList<String> mVoiceConfigList;
00057 private HashMap<String, Runnable> mActionMap;
00058
00059
00060 private VoiceHelperThread mHelper = null;
00061 private Handler mHelperHandler = null;
00062
00063
00064 public static final int ENABLE_SYSTEM_CMD_MESSAGE = 0;
00065 public static final int ADD_VOCAB_MESSAGE = 1;
00066 public static final int REMOVE_VOCAB_MESSAGE = 2;
00067 public static final int CHANGE_VOCAB_MESSAGE = 3;
00068 public static final int CHANGE_VOCAB_ACTION_MESSAGE = 4;
00069 public static final int RESET_MESSAGE = 5;
00070 public static final int LISTENING_MESSAGE = 6;
00071 public static final int CONTEXT_MESSAGE = 7;
00072 public static final int CONNECTION_MESSAGE = 8;
00073 public static final int UPDATE_MESSAGE = 9;
00074 public static final int SHUTDOWN_MESSAGE = 10;
00075
00076
00077 private Handler mainHandler;
00078 private Handler connectedHandler;
00079 private Handler mHandler = null;
00080
00081
00082
00083
00084 public VoiceRecognitionThread(RobotManagerApplication app, Context context)
00085 {
00086 super("Voice Recognition Thread");
00087 this.mApplication = app;
00088 this.mContext = context;
00089 }
00090
00091
00092
00093
00094
00095
00096
00097
00098
00099 private void setup()
00100 {
00101
00102 mSystemCommands = new ArrayList<String>();
00103 mConnectCommands = new ArrayList<String>();
00104
00105
00106
00107
00108 mBluetoothAdapter = BluetoothAdapter.getDefaultAdapter();
00109 for (BluetoothDevice device : mBluetoothAdapter.getBondedDevices())
00110 {
00111 mConnectCommands.add("Connect to " + device.getName());
00112 }
00113 mConnectCommands.add("Close robot manager");
00114
00115
00116
00117 mSystemCommands.add("All robots");
00118 mSystemCommands.add("Start listening");
00119 mSystemCommands.add("Stop listening");
00120 mSystemCommands.add("End connection");
00121 mSystemCommands.add("Close robot manager");
00122 mSystemCommands.add("View robots");
00123
00124 mSystemCommands.add("View messages");
00125
00126
00127
00128
00129
00130 mVoiceConfigList = new ArrayList<String>(mConnectCommands);
00131 mVoiceConfig = new VoiceConfig("MyVoiceConfig", mConnectCommands.toArray(new String[mConnectCommands.size()]));
00132 mVoiceInputHelper = new VoiceInputHelper(mContext, new VoiceListenerImpl(mVoiceConfig),
00133 VoiceInputHelper.newUserActivityObserver(mContext));
00134
00135 mVoiceInputHelper.addVoiceServiceListener();
00136 }
00137
00138
00139
00140
00141
00142
00143 @Override
00144 public void start()
00145 {
00146 super.start();
00147
00148 mHandler = new Handler(getLooper()){
00149 @Override
00150 public void handleMessage(Message msg) {
00151 switch (msg.what) {
00152
00153 case ENABLE_SYSTEM_CMD_MESSAGE:
00154 Boolean enable = (Boolean)msg.obj;
00155 useSystemCommands(enable);
00156 break;
00157
00158 case ADD_VOCAB_MESSAGE:
00159 String addition = (String)msg.obj;
00160 addToVocab(addition);
00161 break;
00162
00163 case REMOVE_VOCAB_MESSAGE:
00164 String deletion = (String)msg.obj;
00165 removeFromVocab(deletion);
00166 break;
00167
00168 case CHANGE_VOCAB_MESSAGE:
00169 ArrayList<String> newVocab = (ArrayList<String>)msg.obj;
00170 changeVocab(newVocab);
00171 break;
00172
00173 case CHANGE_VOCAB_ACTION_MESSAGE:
00174 HashMap<String, Runnable> actionMap = (HashMap<String, Runnable>)msg.obj;
00175 changeVocabWithAction(actionMap);
00176 break;
00177
00178 case RESET_MESSAGE:
00179 String resetMessage = (String)msg.obj;
00180 reset(resetMessage);
00181 break;
00182
00183 case LISTENING_MESSAGE:
00184 boolean isListening = (Boolean) msg.obj;
00185 VoiceRecognitionThread.this.isListening = isListening;
00186 break;
00187
00188 case CONTEXT_MESSAGE:
00189 Context newContext = (Context)msg.obj;
00190 setContext(newContext);
00191 break;
00192
00193 case CONNECTION_MESSAGE:
00194 String status = (String)msg.obj;
00195 if (status.equals("connected"))
00196 {
00197 useSystemCommands(true);
00198 changeVocab(new ArrayList<String>());
00199 }
00200 else if (status.equals("disconnected"))
00201 {
00202 useSystemCommands(false);
00203 changeVocab(mConnectCommands);
00204 }
00205 break;
00206
00207 case UPDATE_MESSAGE:
00208 update();
00209 break;
00210
00211 case SHUTDOWN_MESSAGE:
00212 shutdown();
00213 break;
00214 }
00215
00216 }
00217 };
00218
00219 setup();
00220 }
00221
00222
00223
00224
00225
00226 public synchronized boolean isReady()
00227 {
00228 return mHandler != null;
00229 }
00230
00231
00232
00233
00234
00235 public void setHandlers(Handler mainHandler, Handler connectedHandler)
00236 {
00237 this.mainHandler = mainHandler;
00238 this.connectedHandler = connectedHandler;
00239 }
00240
00241
00242
00243
00244 public Handler getHandler()
00245 {
00246 return mHandler;
00247 }
00248
00249
00250
00251
00252
00253 public void setListeningStatus(boolean isListening)
00254 {
00255 this.isListening = isListening;
00256 }
00257
00258
00259
00260
00261
00262 public ArrayList<String> getDefaultRobotCommands()
00263 {
00264 ArrayList<String> newVocab = new ArrayList<String>();
00265
00266
00267 Robot robot = mApplication.getRobotInFocus();
00268
00269
00270 if (robot == null)
00271 {
00272 for (Robot rbt : mApplication.getRobots())
00273 {
00274 newVocab.addAll(rbt.getNextPhrases(new ArrayList<String>()).newVocab);
00275 }
00276 return newVocab;
00277 }
00278 else
00279 {
00280 NewPhrasesMessage msg = robot.getNextPhrases(new ArrayList<String>());
00281 return msg.newVocab;
00282 }
00283 }
00284
00285
00286
00287
00288
00289 public void addToVocab(String newVoiceCommand)
00290 {
00291 Log.d("VoiceThread", "Adding " + newVoiceCommand + " to vocab");
00292
00293
00294 mVoiceConfigList.add(newVoiceCommand);
00295
00296 Log.d("VoiceThread", "Vocab: " + mVoiceConfigList.toString());
00297
00298
00299
00300 mVoiceInputHelper.removeVoiceServiceListener();
00301 mVoiceConfig = new VoiceConfig("MyVoiceConfig", mVoiceConfigList.toArray(new String[mVoiceConfigList.size()]));
00302 mVoiceInputHelper = new VoiceInputHelper(mContext, new VoiceListenerImpl(mVoiceConfig),
00303 VoiceInputHelper.newUserActivityObserver(mContext));
00304
00305 mVoiceInputHelper.addVoiceServiceListener();
00306 }
00307
00308
00309
00310
00311
00312 public void removeFromVocab(String vcToRemove)
00313 {
00314
00315 mVoiceConfigList.remove(vcToRemove);
00316
00317
00318
00319 mVoiceInputHelper.removeVoiceServiceListener();
00320 mVoiceConfig = new VoiceConfig("MyVoiceConfig", mVoiceConfigList.toArray(new String[mVoiceConfigList.size()]));
00321 mVoiceInputHelper = new VoiceInputHelper(mContext, new VoiceListenerImpl(mVoiceConfig),
00322 VoiceInputHelper.newUserActivityObserver(mContext));
00323
00324 mVoiceInputHelper.addVoiceServiceListener();
00325 }
00326
00327
00328
00329
00330
00331 public void changeVocab(ArrayList<String> newVocab)
00332 {
00333 Log.i("VoiceThread", "Changing vocab");
00334
00335
00336 if (mApplication.getConnectionStatus() || newVocab.equals(mConnectCommands))
00337 {
00338
00339 mVoiceConfigList = new ArrayList<String>();
00340 mVoiceConfigList.addAll(newVocab);
00341
00342 if (usingSystemCommands)
00343 {
00344 mVoiceConfigList.addAll(mSystemCommands);
00345 mVoiceConfigList.addAll(mApplication.getRobotNames());
00346 }
00347 }
00348 else
00349 {
00350 mVoiceConfigList.addAll(mConnectCommands);
00351 }
00352
00353
00354 mVoiceInputHelper.removeVoiceServiceListener();
00355 mVoiceConfig = new VoiceConfig("MyVoiceConfig", mVoiceConfigList.toArray(new String[mVoiceConfigList.size()]));
00356 mVoiceInputHelper = new VoiceInputHelper(mContext, new VoiceListenerImpl(mVoiceConfig),
00357 VoiceInputHelper.newUserActivityObserver(mContext));
00358
00359 mVoiceInputHelper.addVoiceServiceListener();
00360
00361 Log.d("VoiceRecognitionThread", "New listening list: " + mVoiceConfigList.toString());
00362
00363 }
00364
00365
00366
00367
00368
00369
00370 public void changeVocabWithAction(HashMap<String, Runnable> vocabWithAction)
00371 {
00372 mActionMap = vocabWithAction;
00373
00374
00375 ArrayList<String> commands = new ArrayList<String>();
00376 for (String command : mActionMap.keySet())
00377 {
00378 commands.add(command);
00379 }
00380
00381
00382 useSystemCommands(false);
00383 changeVocab(commands);
00384 }
00385
00386
00387
00388
00389 public void setContext(Context newContext)
00390 {
00391 mContext = newContext;
00392
00393 }
00394
00395
00396
00397
00398 public void useSystemCommands(boolean use)
00399 {
00400 usingSystemCommands = use;
00401 }
00402
00403
00404
00405
00406
00407
00408 private void update()
00409 {
00410 if (mHelper == null)
00411 {
00412 changeVocab(getDefaultRobotCommands());
00413 }
00414 }
00415
00416
00417
00418
00419
00420
00421 public void reset(String expression)
00422 {
00423 Message msg = connectedHandler.obtainMessage(ConnectedThread.WRITE_MESSAGE, expression);
00424 connectedHandler.sendMessage(msg);
00425
00426 mHelper = null;
00427 usingSystemCommands = true;
00428 changeVocab(getDefaultRobotCommands());
00429 }
00430
00431
00432
00433
00434 public void shutdown()
00435 {
00436 isShutdown = true;
00437 mVoiceInputHelper.removeVoiceServiceListener();
00438 mVoiceInputHelper = null;
00439 if (mHelper != null)
00440 {
00441 mHelper.interrupt();
00442 mHelper = null;
00443 }
00444 mApplication.setVoiceThreadHandler(null);
00445 }
00446
00447
00448
00449 public class VoiceListenerImpl implements VoiceListener {
00450 protected final VoiceConfig voiceConfig;
00451
00452 public VoiceListenerImpl(VoiceConfig voiceConfig) {
00453 this.voiceConfig = voiceConfig;
00454 }
00455
00456 @Override
00457 public void onVoiceServiceConnected() {
00458 mVoiceInputHelper.setVoiceConfig(mVoiceConfig);
00459 }
00460
00461 @Override
00462 public void onVoiceServiceDisconnected() {
00463
00464 }
00465
00466
00467 @Override
00468 public VoiceConfig onVoiceCommand(VoiceCommand vc) {
00469 String recognizedStr = vc.getLiteral();
00470
00471 Log.i("VoiceRecognitionThread", "Recognized text: "+recognizedStr);
00472
00473 if (isListening)
00474 {
00475
00476 if (recognizedStr.equals("All robots"))
00477 {
00478 Log.d("VoiceRecognitionThread", "Setting focus on All");
00479
00480 mApplication.setRobotInFocus("All");
00481
00482 Message msg = mainHandler.obtainMessage(MainActivity.FOCUS_MESSAGE, "All");
00483 mainHandler.sendMessageAtFrontOfQueue(msg);
00484
00485 changeVocab(getDefaultRobotCommands());
00486 }
00487
00488 else if (mApplication.getRobotNames().contains(recognizedStr))
00489 {
00490 Log.d("VoiceRecognitionThread", "Setting focus on: " + recognizedStr);
00491
00492 mApplication.setRobotInFocus(recognizedStr);
00493
00494
00495 Message msg = mainHandler.obtainMessage(MainActivity.FOCUS_MESSAGE, recognizedStr);
00496 mainHandler.sendMessageAtFrontOfQueue(msg);
00497
00498 changeVocab(getDefaultRobotCommands());
00499 }
00500 else
00501 {
00502
00503 Message msg = mainHandler.obtainMessage(MainActivity.COMMAND_MESSAGE, recognizedStr);
00504 mainHandler.sendMessageAtFrontOfQueue(msg);
00505
00506
00507 if (recognizedStr.startsWith("Connect to"))
00508 {
00509 if (!isConnected)
00510 {
00511 Message msgConnected = connectedHandler.obtainMessage(ConnectedThread.CONNECT_MESSAGE, recognizedStr.substring(11));
00512 connectedHandler.sendMessageAtFrontOfQueue(msgConnected);
00513 }
00514 }
00515 else if (recognizedStr.equals("End connection"))
00516 {
00517 Message msgConnected = connectedHandler.obtainMessage();
00518 msgConnected.what = ConnectedThread.DISCONNECT_MESSAGE;
00519 connectedHandler.sendMessage(msgConnected);
00520 }
00521
00522 else if (recognizedStr.equals("Close robot manager"))
00523 {
00524 mApplication.onShutdown();
00525 }
00526
00527 else if (recognizedStr.equals("Stop listening"))
00528 {
00529 setListeningStatus(false);
00530 }
00531
00532 else if (recognizedStr.equals("View robots"))
00533 {
00534 Log.i("VoiceRecognitionThread", "Requesting launch of RobotListActivity");
00535 Message msgView = mainHandler.obtainMessage();
00536 msgView.what = MainActivity.ROBOT_LIST_MESSAGE;
00537 mainHandler.sendMessage(msgView);
00538 }
00539
00540 else if (recognizedStr.equals("Create group"))
00541 {
00542
00543 }
00544
00545 else if (recognizedStr.equals("View messages"))
00546 {
00547 Log.i("VoiceRecognitionThread", "Requesting launch of MessageListActivity");
00548 Message msgView = mainHandler.obtainMessage();
00549 msgView.what = MainActivity.MESSAGE_LIST_MESSAGE;
00550 mainHandler.sendMessage(msgView);
00551 }
00552
00553 else if (recognizedStr.equals("View map"))
00554 {
00555
00556 }
00557
00558 else if (recognizedStr.equals("Cancel"))
00559 {
00560 mHelper.interrupt();
00561 mHelper = null;
00562 changeVocab(getDefaultRobotCommands());
00563 Message mainMsg = mainHandler.obtainMessage(MainActivity.COMMAND_MESSAGE, "Cancel");
00564 mainHandler.sendMessage(mainMsg);
00565 }
00566
00567 else if (mActionMap != null && mActionMap.containsKey(recognizedStr))
00568 {
00569 mActionMap.get(recognizedStr).run();
00570 }
00571
00572
00573 else if (!recognizedStr.equals("Start listening"))
00574 {
00575 if (mHelper == null)
00576 {
00577 Robot focus = mApplication.getRobotInFocus();
00578 if (focus == null)
00579 {
00580 mHelper = new VoiceHelperThread(mApplication, recognizedStr,
00581 "All", mHandler);
00582 }
00583 else
00584 {
00585 mHelper = new VoiceHelperThread(mApplication, recognizedStr,
00586 focus.getName(), mHandler);
00587 }
00588
00589 mHelper.start();
00590 while(!mHelper.isReady());
00591 mHelperHandler = mHelper.getHandler();
00592
00593
00594 usingSystemCommands = false;
00595 }
00596 else
00597 {
00598 Message newPhraseMsg = mHelperHandler.obtainMessage(VoiceHelperThread.RECEIVE_PHRASE_MESSAGE, recognizedStr);
00599 mHelperHandler.sendMessageAtFrontOfQueue(newPhraseMsg);
00600 }
00601 }
00602 }
00603 }
00604 else if (recognizedStr.equals("Start listening"))
00605 {
00606 Message msgShow = mainHandler.obtainMessage(MainActivity.COMMAND_MESSAGE, recognizedStr);
00607 mainHandler.sendMessageAtFrontOfQueue(msgShow);
00608 setListeningStatus(true);
00609 }
00610
00611 return null;
00612 }
00613
00614 @Override
00615 public FormattingLogger getLogger() {
00616 return FormattingLoggers.getContextLogger();
00617 }
00618
00619 @Override
00620 public boolean isRunning() {
00621 return true;
00622 }
00623
00624 @Override
00625 public boolean onResampledAudioData(byte[] arg0, int arg1, int arg2) {
00626 return false;
00627 }
00628
00629
00630
00631 @Override
00632 public boolean onVoiceAmplitudeChanged(double arg0) {
00633 return false;
00634 }
00635
00636 @Override
00637 public void onVoiceConfigChanged(VoiceConfig arg0, boolean arg1)
00638 {
00639 }
00640 }
00641 }