TextToSpeech.java revision 1a2712ce2a18eba6809d984d2f7443fbdccaa7ed
1/* 2 * Copyright (C) 2009 Google Inc. 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); you may not 5 * use this file except in compliance with the License. You may obtain a copy of 6 * the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT 12 * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the 13 * License for the specific language governing permissions and limitations under 14 * the License. 15 */ 16package android.speech.tts; 17 18import android.speech.tts.ITts; 19import android.speech.tts.ITtsCallback; 20 21import android.annotation.SdkConstant; 22import android.annotation.SdkConstant.SdkConstantType; 23import android.content.ComponentName; 24import android.content.Context; 25import android.content.Intent; 26import android.content.ServiceConnection; 27import android.media.AudioManager; 28import android.os.IBinder; 29import android.os.RemoteException; 30import android.util.Log; 31 32import java.util.HashMap; 33import java.util.Locale; 34 35/** 36 * 37 * Synthesizes speech from text for immediate playback or to create a sound file. 38 * <p>A TextToSpeech instance can only be used to synthesize text once it has completed its 39 * initialization. Implement the {@link TextToSpeech.OnInitListener} to be 40 * notified of the completion of the initialization.<br> 41 * When you are done using the TextToSpeech instance, call the {@link #shutdown()} method 42 * to release the native resources used by the TextToSpeech engine. 43 * 44 */ 45public class TextToSpeech { 46 47 /** 48 * Denotes a successful operation. 49 */ 50 public static final int SUCCESS = 0; 51 /** 52 * Denotes a generic operation failure. 53 */ 54 public static final int ERROR = -1; 55 56 /** 57 * Queue mode where all entries in the playback queue (media to be played 58 * and text to be synthesized) are dropped and replaced by the new entry. 59 */ 60 public static final int QUEUE_FLUSH = 0; 61 /** 62 * Queue mode where the new entry is added at the end of the playback queue. 63 */ 64 public static final int QUEUE_ADD = 1; 65 66 67 /** 68 * Denotes the language is available exactly as specified by the locale. 69 */ 70 public static final int LANG_COUNTRY_VAR_AVAILABLE = 2; 71 72 73 /** 74 * Denotes the language is available for the language and country specified 75 * by the locale, but not the variant. 76 */ 77 public static final int LANG_COUNTRY_AVAILABLE = 1; 78 79 80 /** 81 * Denotes the language is available for the language by the locale, 82 * but not the country and variant. 83 */ 84 public static final int LANG_AVAILABLE = 0; 85 86 /** 87 * Denotes the language data is missing. 88 */ 89 public static final int LANG_MISSING_DATA = -1; 90 91 /** 92 * Denotes the language is not supported. 93 */ 94 public static final int LANG_NOT_SUPPORTED = -2; 95 96 97 /** 98 * Broadcast Action: The TextToSpeech synthesizer has completed processing 99 * of all the text in the speech queue. 100 */ 101 @SdkConstant(SdkConstantType.BROADCAST_INTENT_ACTION) 102 public static final String ACTION_TTS_QUEUE_PROCESSING_COMPLETED = 103 "android.speech.tts.TTS_QUEUE_PROCESSING_COMPLETED"; 104 105 106 /** 107 * Interface definition of a callback to be invoked indicating the completion of the 108 * TextToSpeech engine initialization. 109 */ 110 public interface OnInitListener { 111 /** 112 * Called to signal the completion of the TextToSpeech engine initialization. 113 * @param status {@link TextToSpeech#SUCCESS} or {@link TextToSpeech#ERROR}. 114 */ 115 public void onInit(int status); 116 } 117 118 /** 119 * Interface definition of a callback to be invoked indicating the TextToSpeech engine has 120 * completed synthesizing an utterance with an utterance ID set. 121 * 122 */ 123 public interface OnUtteranceCompletedListener { 124 /** 125 * Called to signal the completion of the synthesis of the utterance that was identified 126 * with the string parameter. This identifier is the one originally passed in the 127 * parameter hashmap of the synthesis request in 128 * {@link TextToSpeech#speak(String, int, HashMap)} or 129 * {@link TextToSpeech#synthesizeToFile(String, HashMap, String)} with the 130 * {@link TextToSpeech.Engine#KEY_PARAM_UTTERANCE_ID} key. 131 * @param utteranceId the identifier of the utterance. 132 */ 133 public void onUtteranceCompleted(String utteranceId); 134 } 135 136 137 /** 138 * Internal constants for the TextToSpeech functionality 139 * 140 */ 141 public class Engine { 142 // default values for a TTS engine when settings are not found in the provider 143 /** 144 * {@hide} 145 */ 146 public static final int DEFAULT_RATE = 100; // 1x 147 /** 148 * {@hide} 149 */ 150 public static final int DEFAULT_PITCH = 100;// 1x 151 /** 152 * {@hide} 153 */ 154 public static final int USE_DEFAULTS = 0; // false 155 /** 156 * {@hide} 157 */ 158 public static final String DEFAULT_SYNTH = "com.svox.pico"; 159 160 // default values for rendering 161 /** 162 * Default audio stream used when playing synthesized speech. 163 */ 164 public static final int DEFAULT_STREAM = AudioManager.STREAM_MUSIC; 165 166 // return codes for a TTS engine's check data activity 167 /** 168 * Indicates success when checking the installation status of the resources used by the 169 * TextToSpeech engine with the {@link #ACTION_CHECK_TTS_DATA} intent. 170 */ 171 public static final int CHECK_VOICE_DATA_PASS = 1; 172 /** 173 * Indicates failure when checking the installation status of the resources used by the 174 * TextToSpeech engine with the {@link #ACTION_CHECK_TTS_DATA} intent. 175 */ 176 public static final int CHECK_VOICE_DATA_FAIL = 0; 177 /** 178 * Indicates erroneous data when checking the installation status of the resources used by 179 * the TextToSpeech engine with the {@link #ACTION_CHECK_TTS_DATA} intent. 180 */ 181 public static final int CHECK_VOICE_DATA_BAD_DATA = -1; 182 /** 183 * Indicates missing resources when checking the installation status of the resources used 184 * by the TextToSpeech engine with the {@link #ACTION_CHECK_TTS_DATA} intent. 185 */ 186 public static final int CHECK_VOICE_DATA_MISSING_DATA = -2; 187 /** 188 * Indicates missing storage volume when checking the installation status of the resources 189 * used by the TextToSpeech engine with the {@link #ACTION_CHECK_TTS_DATA} intent. 190 */ 191 public static final int CHECK_VOICE_DATA_MISSING_VOLUME = -3; 192 193 // intents to ask engine to install data or check its data 194 /** 195 * Activity Action: Triggers the platform TextToSpeech engine to 196 * start the activity that installs the resource files on the device 197 * that are required for TTS to be operational. Since the installation 198 * of the data can be interrupted or declined by the user, the application 199 * shouldn't expect successful installation upon return from that intent, 200 * and if need be, should check installation status with 201 * {@link #ACTION_CHECK_TTS_DATA}. 202 */ 203 @SdkConstant(SdkConstantType.ACTIVITY_INTENT_ACTION) 204 public static final String ACTION_INSTALL_TTS_DATA = 205 "android.speech.tts.engine.INSTALL_TTS_DATA"; 206 207 /** 208 * Broadcast Action: broadcast to signal the completion of the installation of 209 * the data files used by the synthesis engine. Success or failure is indicated in the 210 * {@link #EXTRA_TTS_DATA_INSTALLED} extra. 211 */ 212 @SdkConstant(SdkConstantType.BROADCAST_INTENT_ACTION) 213 public static final String ACTION_TTS_DATA_INSTALLED = 214 "android.speech.tts.engine.TTS_DATA_INSTALLED"; 215 /** 216 * Activity Action: Starts the activity from the platform TextToSpeech 217 * engine to verify the proper installation and availability of the 218 * resource files on the system. Upon completion, the activity will 219 * return one of the following codes: 220 * {@link #CHECK_VOICE_DATA_PASS}, 221 * {@link #CHECK_VOICE_DATA_FAIL}, 222 * {@link #CHECK_VOICE_DATA_BAD_DATA}, 223 * {@link #CHECK_VOICE_DATA_MISSING_DATA}, or 224 * {@link #CHECK_VOICE_DATA_MISSING_VOLUME}. 225 * <p> Moreover, the data received in the activity result will contain the following 226 * fields: 227 * <ul> 228 * <li>{@link #EXTRA_VOICE_DATA_ROOT_DIRECTORY} which 229 * indicates the path to the location of the resource files,</li> 230 * <li>{@link #EXTRA_VOICE_DATA_FILES} which contains 231 * the list of all the resource files,</li> 232 * <li>and {@link #EXTRA_VOICE_DATA_FILES_INFO} which 233 * contains, for each resource file, the description of the language covered by 234 * the file in the xxx-YYY format, where xxx is the 3-letter ISO language code, 235 * and YYY is the 3-letter ISO country code.</li> 236 * </ul> 237 */ 238 @SdkConstant(SdkConstantType.ACTIVITY_INTENT_ACTION) 239 public static final String ACTION_CHECK_TTS_DATA = 240 "android.speech.tts.engine.CHECK_TTS_DATA"; 241 242 // extras for a TTS engine's check data activity 243 /** 244 * Extra information received with the {@link #ACTION_CHECK_TTS_DATA} intent where 245 * the TextToSpeech engine specifies the path to its resources. 246 */ 247 public static final String EXTRA_VOICE_DATA_ROOT_DIRECTORY = "dataRoot"; 248 /** 249 * Extra information received with the {@link #ACTION_CHECK_TTS_DATA} intent where 250 * the TextToSpeech engine specifies the file names of its resources under the 251 * resource path. 252 */ 253 public static final String EXTRA_VOICE_DATA_FILES = "dataFiles"; 254 /** 255 * Extra information received with the {@link #ACTION_CHECK_TTS_DATA} intent where 256 * the TextToSpeech engine specifies the locale associated with each resource file. 257 */ 258 public static final String EXTRA_VOICE_DATA_FILES_INFO = "dataFilesInfo"; 259 /** 260 * Extra information received with the {@link #ACTION_CHECK_TTS_DATA} intent where 261 * the TextToSpeech engine returns an ArrayList<String> of all the available voices. 262 * The format of each voice is: lang-COUNTRY-variant where COUNTRY and variant are 263 * optional (ie, "eng" or "eng-USA" or "eng-USA-FEMALE"). 264 * {@hide} 265 */ 266 public static final String EXTRA_AVAILABLE_VOICES = "availableVoices"; 267 /** 268 * Extra information received with the {@link #ACTION_CHECK_TTS_DATA} intent where 269 * the TextToSpeech engine returns an ArrayList<String> of all the unavailable voices. 270 * The format of each voice is: lang-COUNTRY-variant where COUNTRY and variant are 271 * optional (ie, "eng" or "eng-USA" or "eng-USA-FEMALE"). 272 * {@hide} 273 */ 274 public static final String EXTRA_UNAVAILABLE_VOICES = "unavailableVoices"; 275 /** 276 * Extra information sent with the {@link #ACTION_CHECK_TTS_DATA} intent where the 277 * caller indicates to the TextToSpeech engine which specific sets of voice data to 278 * check for by sending an ArrayList<String> of the voices that are of interest. 279 * The format of each voice is: lang-COUNTRY-variant where COUNTRY and variant are 280 * optional (ie, "eng" or "eng-USA" or "eng-USA-FEMALE"). 281 * {@hide} 282 */ 283 public static final String EXTRA_CHECK_VOICE_DATA_FOR = "checkVoiceDataFor"; 284 285 // extras for a TTS engine's data installation 286 /** 287 * Extra information received with the {@link #ACTION_TTS_DATA_INSTALLED} intent. 288 * It indicates whether the data files for the synthesis engine were successfully 289 * installed. The installation was initiated with the {@link #ACTION_INSTALL_TTS_DATA} 290 * intent. The possible values for this extra are 291 * {@link TextToSpeech#SUCCESS} and {@link TextToSpeech#ERROR}. 292 */ 293 public static final String EXTRA_TTS_DATA_INSTALLED = "dataInstalled"; 294 295 // keys for the parameters passed with speak commands. Hidden keys are used internally 296 // to maintain engine state for each TextToSpeech instance. 297 /** 298 * {@hide} 299 */ 300 public static final String KEY_PARAM_RATE = "rate"; 301 /** 302 * {@hide} 303 */ 304 public static final String KEY_PARAM_LANGUAGE = "language"; 305 /** 306 * {@hide} 307 */ 308 public static final String KEY_PARAM_COUNTRY = "country"; 309 /** 310 * {@hide} 311 */ 312 public static final String KEY_PARAM_VARIANT = "variant"; 313 /** 314 * {@hide} 315 */ 316 public static final String KEY_PARAM_ENGINE = "engine"; 317 /** 318 * {@hide} 319 */ 320 public static final String KEY_PARAM_PITCH = "pitch"; 321 /** 322 * Parameter key to specify the audio stream type to be used when speaking text 323 * or playing back a file. 324 * @see TextToSpeech#speak(String, int, HashMap) 325 * @see TextToSpeech#playEarcon(String, int, HashMap) 326 */ 327 public static final String KEY_PARAM_STREAM = "streamType"; 328 /** 329 * Parameter key to identify an utterance in the 330 * {@link TextToSpeech.OnUtteranceCompletedListener} after text has been 331 * spoken, a file has been played back or a silence duration has elapsed. 332 * @see TextToSpeech#speak(String, int, HashMap) 333 * @see TextToSpeech#playEarcon(String, int, HashMap) 334 * @see TextToSpeech#synthesizeToFile(String, HashMap, String) 335 */ 336 public static final String KEY_PARAM_UTTERANCE_ID = "utteranceId"; 337 338 // key positions in the array of cached parameters 339 /** 340 * {@hide} 341 */ 342 protected static final int PARAM_POSITION_RATE = 0; 343 /** 344 * {@hide} 345 */ 346 protected static final int PARAM_POSITION_LANGUAGE = 2; 347 /** 348 * {@hide} 349 */ 350 protected static final int PARAM_POSITION_COUNTRY = 4; 351 /** 352 * {@hide} 353 */ 354 protected static final int PARAM_POSITION_VARIANT = 6; 355 /** 356 * {@hide} 357 */ 358 protected static final int PARAM_POSITION_STREAM = 8; 359 /** 360 * {@hide} 361 */ 362 protected static final int PARAM_POSITION_UTTERANCE_ID = 10; 363 364 /** 365 * {@hide} 366 */ 367 protected static final int PARAM_POSITION_ENGINE = 12; 368 369 /** 370 * {@hide} 371 */ 372 protected static final int PARAM_POSITION_PITCH = 14; 373 374 /** 375 * {@hide} 376 */ 377 protected static final int NB_CACHED_PARAMS = 8; 378 } 379 380 /** 381 * Connection needed for the TTS. 382 */ 383 private ServiceConnection mServiceConnection; 384 385 private ITts mITts = null; 386 private ITtsCallback mITtscallback = null; 387 private Context mContext = null; 388 private String mPackageName = ""; 389 private OnInitListener mInitListener = null; 390 private boolean mStarted = false; 391 private final Object mStartLock = new Object(); 392 /** 393 * Used to store the cached parameters sent along with each synthesis request to the 394 * TTS service. 395 */ 396 private String[] mCachedParams; 397 398 /** 399 * The constructor for the TextToSpeech class. 400 * This will also initialize the associated TextToSpeech engine if it isn't already running. 401 * 402 * @param context 403 * The context this instance is running in. 404 * @param listener 405 * The {@link TextToSpeech.OnInitListener} that will be called when the 406 * TextToSpeech engine has initialized. 407 */ 408 public TextToSpeech(Context context, OnInitListener listener) { 409 mContext = context; 410 mPackageName = mContext.getPackageName(); 411 mInitListener = listener; 412 413 mCachedParams = new String[2*Engine.NB_CACHED_PARAMS]; // store key and value 414 mCachedParams[Engine.PARAM_POSITION_RATE] = Engine.KEY_PARAM_RATE; 415 mCachedParams[Engine.PARAM_POSITION_LANGUAGE] = Engine.KEY_PARAM_LANGUAGE; 416 mCachedParams[Engine.PARAM_POSITION_COUNTRY] = Engine.KEY_PARAM_COUNTRY; 417 mCachedParams[Engine.PARAM_POSITION_VARIANT] = Engine.KEY_PARAM_VARIANT; 418 mCachedParams[Engine.PARAM_POSITION_STREAM] = Engine.KEY_PARAM_STREAM; 419 mCachedParams[Engine.PARAM_POSITION_UTTERANCE_ID] = Engine.KEY_PARAM_UTTERANCE_ID; 420 mCachedParams[Engine.PARAM_POSITION_ENGINE] = Engine.KEY_PARAM_ENGINE; 421 mCachedParams[Engine.PARAM_POSITION_PITCH] = Engine.KEY_PARAM_PITCH; 422 423 // Leave all defaults that are shown in Settings uninitialized/at the default 424 // so that the values set in Settings will take effect if the application does 425 // not try to change these settings itself. 426 mCachedParams[Engine.PARAM_POSITION_RATE + 1] = ""; 427 mCachedParams[Engine.PARAM_POSITION_LANGUAGE + 1] = ""; 428 mCachedParams[Engine.PARAM_POSITION_COUNTRY + 1] = ""; 429 mCachedParams[Engine.PARAM_POSITION_VARIANT + 1] = ""; 430 mCachedParams[Engine.PARAM_POSITION_STREAM + 1] = 431 String.valueOf(Engine.DEFAULT_STREAM); 432 mCachedParams[Engine.PARAM_POSITION_UTTERANCE_ID + 1] = ""; 433 mCachedParams[Engine.PARAM_POSITION_ENGINE + 1] = ""; 434 mCachedParams[Engine.PARAM_POSITION_PITCH + 1] = "100"; 435 436 initTts(); 437 } 438 439 440 private void initTts() { 441 mStarted = false; 442 443 // Initialize the TTS, run the callback after the binding is successful 444 mServiceConnection = new ServiceConnection() { 445 public void onServiceConnected(ComponentName name, IBinder service) { 446 synchronized(mStartLock) { 447 mITts = ITts.Stub.asInterface(service); 448 mStarted = true; 449 // Cache the default engine and current language 450 setEngineByPackageName(getDefaultEngine()); 451 setLanguage(getLanguage()); 452 if (mInitListener != null) { 453 // TODO manage failures and missing resources 454 mInitListener.onInit(SUCCESS); 455 } 456 } 457 } 458 459 public void onServiceDisconnected(ComponentName name) { 460 synchronized(mStartLock) { 461 mITts = null; 462 mInitListener = null; 463 mStarted = false; 464 } 465 } 466 }; 467 468 Intent intent = new Intent("android.intent.action.START_TTS_SERVICE"); 469 intent.addCategory("android.intent.category.TTS"); 470 mContext.bindService(intent, mServiceConnection, 471 Context.BIND_AUTO_CREATE); 472 // TODO handle case where the binding works (should always work) but 473 // the plugin fails 474 } 475 476 477 /** 478 * Releases the resources used by the TextToSpeech engine. 479 * It is good practice for instance to call this method in the onDestroy() method of an Activity 480 * so the TextToSpeech engine can be cleanly stopped. 481 */ 482 public void shutdown() { 483 try { 484 mContext.unbindService(mServiceConnection); 485 } catch (IllegalArgumentException e) { 486 // Do nothing and fail silently since an error here indicates that 487 // binding never succeeded in the first place. 488 } 489 } 490 491 492 /** 493 * Adds a mapping between a string of text and a sound resource in a 494 * package. After a call to this method, subsequent calls to 495 * {@link #speak(String, int, HashMap)} will play the specified sound resource 496 * if it is available, or synthesize the text it is missing. 497 * 498 * @param text 499 * The string of text. Example: <code>"south_south_east"</code> 500 * 501 * @param packagename 502 * Pass the packagename of the application that contains the 503 * resource. If the resource is in your own application (this is 504 * the most common case), then put the packagename of your 505 * application here.<br/> 506 * Example: <b>"com.google.marvin.compass"</b><br/> 507 * The packagename can be found in the AndroidManifest.xml of 508 * your application. 509 * <p> 510 * <code><manifest xmlns:android="..." 511 * package="<b>com.google.marvin.compass</b>"></code> 512 * </p> 513 * 514 * @param resourceId 515 * Example: <code>R.raw.south_south_east</code> 516 * 517 * @return Code indicating success or failure. See {@link #ERROR} and {@link #SUCCESS}. 518 */ 519 public int addSpeech(String text, String packagename, int resourceId) { 520 synchronized(mStartLock) { 521 if (!mStarted) { 522 return ERROR; 523 } 524 try { 525 mITts.addSpeech(mPackageName, text, packagename, resourceId); 526 return SUCCESS; 527 } catch (RemoteException e) { 528 // TTS died; restart it. 529 Log.e("TextToSpeech.java - addSpeech", "RemoteException"); 530 e.printStackTrace(); 531 mStarted = false; 532 initTts(); 533 } catch (NullPointerException e) { 534 // TTS died; restart it. 535 Log.e("TextToSpeech.java - addSpeech", "NullPointerException"); 536 e.printStackTrace(); 537 mStarted = false; 538 initTts(); 539 } catch (IllegalStateException e) { 540 // TTS died; restart it. 541 Log.e("TextToSpeech.java - addSpeech", "IllegalStateException"); 542 e.printStackTrace(); 543 mStarted = false; 544 initTts(); 545 } 546 return ERROR; 547 } 548 } 549 550 551 /** 552 * Adds a mapping between a string of text and a sound file. Using this, it 553 * is possible to add custom pronounciations for a string of text. 554 * After a call to this method, subsequent calls to {@link #speak(String, int, HashMap)} 555 * will play the specified sound resource if it is available, or synthesize the text it is 556 * missing. 557 * 558 * @param text 559 * The string of text. Example: <code>"south_south_east"</code> 560 * @param filename 561 * The full path to the sound file (for example: 562 * "/sdcard/mysounds/hello.wav") 563 * 564 * @return Code indicating success or failure. See {@link #ERROR} and {@link #SUCCESS}. 565 */ 566 public int addSpeech(String text, String filename) { 567 synchronized (mStartLock) { 568 if (!mStarted) { 569 return ERROR; 570 } 571 try { 572 mITts.addSpeechFile(mPackageName, text, filename); 573 return SUCCESS; 574 } catch (RemoteException e) { 575 // TTS died; restart it. 576 Log.e("TextToSpeech.java - addSpeech", "RemoteException"); 577 e.printStackTrace(); 578 mStarted = false; 579 initTts(); 580 } catch (NullPointerException e) { 581 // TTS died; restart it. 582 Log.e("TextToSpeech.java - addSpeech", "NullPointerException"); 583 e.printStackTrace(); 584 mStarted = false; 585 initTts(); 586 } catch (IllegalStateException e) { 587 // TTS died; restart it. 588 Log.e("TextToSpeech.java - addSpeech", "IllegalStateException"); 589 e.printStackTrace(); 590 mStarted = false; 591 initTts(); 592 } 593 return ERROR; 594 } 595 } 596 597 598 /** 599 * Adds a mapping between a string of text and a sound resource in a 600 * package. Use this to add custom earcons. 601 * 602 * @see #playEarcon(String, int, HashMap) 603 * 604 * @param earcon The name of the earcon. 605 * Example: <code>"[tick]"</code><br/> 606 * 607 * @param packagename 608 * the package name of the application that contains the 609 * resource. This can for instance be the package name of your own application. 610 * Example: <b>"com.google.marvin.compass"</b><br/> 611 * The package name can be found in the AndroidManifest.xml of 612 * the application containing the resource. 613 * <p> 614 * <code><manifest xmlns:android="..." 615 * package="<b>com.google.marvin.compass</b>"></code> 616 * </p> 617 * 618 * @param resourceId 619 * Example: <code>R.raw.tick_snd</code> 620 * 621 * @return Code indicating success or failure. See {@link #ERROR} and {@link #SUCCESS}. 622 */ 623 public int addEarcon(String earcon, String packagename, int resourceId) { 624 synchronized(mStartLock) { 625 if (!mStarted) { 626 return ERROR; 627 } 628 try { 629 mITts.addEarcon(mPackageName, earcon, packagename, resourceId); 630 return SUCCESS; 631 } catch (RemoteException e) { 632 // TTS died; restart it. 633 Log.e("TextToSpeech.java - addEarcon", "RemoteException"); 634 e.printStackTrace(); 635 mStarted = false; 636 initTts(); 637 } catch (NullPointerException e) { 638 // TTS died; restart it. 639 Log.e("TextToSpeech.java - addEarcon", "NullPointerException"); 640 e.printStackTrace(); 641 mStarted = false; 642 initTts(); 643 } catch (IllegalStateException e) { 644 // TTS died; restart it. 645 Log.e("TextToSpeech.java - addEarcon", "IllegalStateException"); 646 e.printStackTrace(); 647 mStarted = false; 648 initTts(); 649 } 650 return ERROR; 651 } 652 } 653 654 655 /** 656 * Adds a mapping between a string of text and a sound file. 657 * Use this to add custom earcons. 658 * 659 * @see #playEarcon(String, int, HashMap) 660 * 661 * @param earcon 662 * The name of the earcon. 663 * Example: <code>"[tick]"</code> 664 * @param filename 665 * The full path to the sound file (for example: 666 * "/sdcard/mysounds/tick.wav") 667 * 668 * @return Code indicating success or failure. See {@link #ERROR} and {@link #SUCCESS}. 669 */ 670 public int addEarcon(String earcon, String filename) { 671 synchronized (mStartLock) { 672 if (!mStarted) { 673 return ERROR; 674 } 675 try { 676 mITts.addEarconFile(mPackageName, earcon, filename); 677 return SUCCESS; 678 } catch (RemoteException e) { 679 // TTS died; restart it. 680 Log.e("TextToSpeech.java - addEarcon", "RemoteException"); 681 e.printStackTrace(); 682 mStarted = false; 683 initTts(); 684 } catch (NullPointerException e) { 685 // TTS died; restart it. 686 Log.e("TextToSpeech.java - addEarcon", "NullPointerException"); 687 e.printStackTrace(); 688 mStarted = false; 689 initTts(); 690 } catch (IllegalStateException e) { 691 // TTS died; restart it. 692 Log.e("TextToSpeech.java - addEarcon", "IllegalStateException"); 693 e.printStackTrace(); 694 mStarted = false; 695 initTts(); 696 } 697 return ERROR; 698 } 699 } 700 701 702 /** 703 * Speaks the string using the specified queuing strategy and speech 704 * parameters. 705 * 706 * @param text 707 * The string of text to be spoken. 708 * @param queueMode 709 * The queuing strategy to use. 710 * {@link #QUEUE_ADD} or {@link #QUEUE_FLUSH}. 711 * @param params 712 * The list of parameters to be used. Can be null if no parameters are given. 713 * They are specified using a (key, value) pair, where the key can be 714 * {@link Engine#KEY_PARAM_STREAM} or 715 * {@link Engine#KEY_PARAM_UTTERANCE_ID}. 716 * 717 * @return Code indicating success or failure. See {@link #ERROR} and {@link #SUCCESS}. 718 */ 719 public int speak(String text, int queueMode, HashMap<String,String> params) 720 { 721 synchronized (mStartLock) { 722 int result = ERROR; 723 Log.i("TTS received: ", text); 724 if (!mStarted) { 725 return result; 726 } 727 try { 728 if ((params != null) && (!params.isEmpty())) { 729 String extra = params.get(Engine.KEY_PARAM_STREAM); 730 if (extra != null) { 731 mCachedParams[Engine.PARAM_POSITION_STREAM + 1] = extra; 732 } 733 extra = params.get(Engine.KEY_PARAM_UTTERANCE_ID); 734 if (extra != null) { 735 mCachedParams[Engine.PARAM_POSITION_UTTERANCE_ID + 1] = extra; 736 } 737 extra = params.get(Engine.KEY_PARAM_ENGINE); 738 if (extra != null) { 739 mCachedParams[Engine.PARAM_POSITION_ENGINE + 1] = extra; 740 } 741 } 742 result = mITts.speak(mPackageName, text, queueMode, mCachedParams); 743 } catch (RemoteException e) { 744 // TTS died; restart it. 745 Log.e("TextToSpeech.java - speak", "RemoteException"); 746 e.printStackTrace(); 747 mStarted = false; 748 initTts(); 749 } catch (NullPointerException e) { 750 // TTS died; restart it. 751 Log.e("TextToSpeech.java - speak", "NullPointerException"); 752 e.printStackTrace(); 753 mStarted = false; 754 initTts(); 755 } catch (IllegalStateException e) { 756 // TTS died; restart it. 757 Log.e("TextToSpeech.java - speak", "IllegalStateException"); 758 e.printStackTrace(); 759 mStarted = false; 760 initTts(); 761 } finally { 762 resetCachedParams(); 763 return result; 764 } 765 } 766 } 767 768 769 /** 770 * Plays the earcon using the specified queueing mode and parameters. 771 * 772 * @param earcon 773 * The earcon that should be played 774 * @param queueMode 775 * {@link #QUEUE_ADD} or {@link #QUEUE_FLUSH}. 776 * @param params 777 * The list of parameters to be used. Can be null if no parameters are given. 778 * They are specified using a (key, value) pair, where the key can be 779 * {@link Engine#KEY_PARAM_STREAM} or 780 * {@link Engine#KEY_PARAM_UTTERANCE_ID}. 781 * 782 * @return Code indicating success or failure. See {@link #ERROR} and {@link #SUCCESS}. 783 */ 784 public int playEarcon(String earcon, int queueMode, 785 HashMap<String,String> params) { 786 synchronized (mStartLock) { 787 int result = ERROR; 788 if (!mStarted) { 789 return result; 790 } 791 try { 792 if ((params != null) && (!params.isEmpty())) { 793 String extra = params.get(Engine.KEY_PARAM_STREAM); 794 if (extra != null) { 795 mCachedParams[Engine.PARAM_POSITION_STREAM + 1] = extra; 796 } 797 extra = params.get(Engine.KEY_PARAM_UTTERANCE_ID); 798 if (extra != null) { 799 mCachedParams[Engine.PARAM_POSITION_UTTERANCE_ID + 1] = extra; 800 } 801 } 802 result = mITts.playEarcon(mPackageName, earcon, queueMode, null); 803 } catch (RemoteException e) { 804 // TTS died; restart it. 805 Log.e("TextToSpeech.java - playEarcon", "RemoteException"); 806 e.printStackTrace(); 807 mStarted = false; 808 initTts(); 809 } catch (NullPointerException e) { 810 // TTS died; restart it. 811 Log.e("TextToSpeech.java - playEarcon", "NullPointerException"); 812 e.printStackTrace(); 813 mStarted = false; 814 initTts(); 815 } catch (IllegalStateException e) { 816 // TTS died; restart it. 817 Log.e("TextToSpeech.java - playEarcon", "IllegalStateException"); 818 e.printStackTrace(); 819 mStarted = false; 820 initTts(); 821 } finally { 822 resetCachedParams(); 823 return result; 824 } 825 } 826 } 827 828 /** 829 * Plays silence for the specified amount of time using the specified 830 * queue mode. 831 * 832 * @param durationInMs 833 * A long that indicates how long the silence should last. 834 * @param queueMode 835 * {@link #QUEUE_ADD} or {@link #QUEUE_FLUSH}. 836 * @param params 837 * The list of parameters to be used. Can be null if no parameters are given. 838 * They are specified using a (key, value) pair, where the key can be 839 * {@link Engine#KEY_PARAM_UTTERANCE_ID}. 840 * 841 * @return Code indicating success or failure. See {@link #ERROR} and {@link #SUCCESS}. 842 */ 843 public int playSilence(long durationInMs, int queueMode, HashMap<String,String> params) { 844 synchronized (mStartLock) { 845 int result = ERROR; 846 if (!mStarted) { 847 return result; 848 } 849 try { 850 if ((params != null) && (!params.isEmpty())) { 851 String extra = params.get(Engine.KEY_PARAM_UTTERANCE_ID); 852 if (extra != null) { 853 mCachedParams[Engine.PARAM_POSITION_UTTERANCE_ID + 1] = extra; 854 } 855 } 856 result = mITts.playSilence(mPackageName, durationInMs, queueMode, mCachedParams); 857 } catch (RemoteException e) { 858 // TTS died; restart it. 859 Log.e("TextToSpeech.java - playSilence", "RemoteException"); 860 e.printStackTrace(); 861 mStarted = false; 862 initTts(); 863 } catch (NullPointerException e) { 864 // TTS died; restart it. 865 Log.e("TextToSpeech.java - playSilence", "NullPointerException"); 866 e.printStackTrace(); 867 mStarted = false; 868 initTts(); 869 } catch (IllegalStateException e) { 870 // TTS died; restart it. 871 Log.e("TextToSpeech.java - playSilence", "IllegalStateException"); 872 e.printStackTrace(); 873 mStarted = false; 874 initTts(); 875 } finally { 876 return result; 877 } 878 } 879 } 880 881 882 /** 883 * Returns whether or not the TextToSpeech engine is busy speaking. 884 * 885 * @return Whether or not the TextToSpeech engine is busy speaking. 886 */ 887 public boolean isSpeaking() { 888 synchronized (mStartLock) { 889 if (!mStarted) { 890 return false; 891 } 892 try { 893 return mITts.isSpeaking(); 894 } catch (RemoteException e) { 895 // TTS died; restart it. 896 Log.e("TextToSpeech.java - isSpeaking", "RemoteException"); 897 e.printStackTrace(); 898 mStarted = false; 899 initTts(); 900 } catch (NullPointerException e) { 901 // TTS died; restart it. 902 Log.e("TextToSpeech.java - isSpeaking", "NullPointerException"); 903 e.printStackTrace(); 904 mStarted = false; 905 initTts(); 906 } catch (IllegalStateException e) { 907 // TTS died; restart it. 908 Log.e("TextToSpeech.java - isSpeaking", "IllegalStateException"); 909 e.printStackTrace(); 910 mStarted = false; 911 initTts(); 912 } 913 return false; 914 } 915 } 916 917 918 /** 919 * Interrupts the current utterance (whether played or rendered to file) and discards other 920 * utterances in the queue. 921 * 922 * @return Code indicating success or failure. See {@link #ERROR} and {@link #SUCCESS}. 923 */ 924 public int stop() { 925 synchronized (mStartLock) { 926 int result = ERROR; 927 if (!mStarted) { 928 return result; 929 } 930 try { 931 result = mITts.stop(mPackageName); 932 } catch (RemoteException e) { 933 // TTS died; restart it. 934 Log.e("TextToSpeech.java - stop", "RemoteException"); 935 e.printStackTrace(); 936 mStarted = false; 937 initTts(); 938 } catch (NullPointerException e) { 939 // TTS died; restart it. 940 Log.e("TextToSpeech.java - stop", "NullPointerException"); 941 e.printStackTrace(); 942 mStarted = false; 943 initTts(); 944 } catch (IllegalStateException e) { 945 // TTS died; restart it. 946 Log.e("TextToSpeech.java - stop", "IllegalStateException"); 947 e.printStackTrace(); 948 mStarted = false; 949 initTts(); 950 } finally { 951 return result; 952 } 953 } 954 } 955 956 957 /** 958 * Sets the speech rate for the TextToSpeech engine. 959 * 960 * This has no effect on any pre-recorded speech. 961 * 962 * @param speechRate 963 * The speech rate for the TextToSpeech engine. 1 is the normal speed, 964 * lower values slow down the speech (0.5 is half the normal speech rate), 965 * greater values accelerate it (2 is twice the normal speech rate). 966 * 967 * @return Code indicating success or failure. See {@link #ERROR} and {@link #SUCCESS}. 968 */ 969 public int setSpeechRate(float speechRate) { 970 synchronized (mStartLock) { 971 int result = ERROR; 972 if (!mStarted) { 973 return result; 974 } 975 try { 976 if (speechRate > 0) { 977 int rate = (int)(speechRate*100); 978 mCachedParams[Engine.PARAM_POSITION_RATE + 1] = String.valueOf(rate); 979 // the rate is not set here, instead it is cached so it will be associated 980 // with all upcoming utterances. 981 if (speechRate > 0.0f) { 982 result = SUCCESS; 983 } else { 984 result = ERROR; 985 } 986 } 987 } catch (NullPointerException e) { 988 // TTS died; restart it. 989 Log.e("TextToSpeech.java - setSpeechRate", "NullPointerException"); 990 e.printStackTrace(); 991 mStarted = false; 992 initTts(); 993 } catch (IllegalStateException e) { 994 // TTS died; restart it. 995 Log.e("TextToSpeech.java - setSpeechRate", "IllegalStateException"); 996 e.printStackTrace(); 997 mStarted = false; 998 initTts(); 999 } finally { 1000 return result; 1001 } 1002 } 1003 } 1004 1005 1006 /** 1007 * Sets the speech pitch for the TextToSpeech engine. 1008 * 1009 * This has no effect on any pre-recorded speech. 1010 * 1011 * @param pitch 1012 * The pitch for the TextToSpeech engine. 1 is the normal pitch, 1013 * lower values lower the tone of the synthesized voice, 1014 * greater values increase it. 1015 * 1016 * @return Code indicating success or failure. See {@link #ERROR} and {@link #SUCCESS}. 1017 */ 1018 public int setPitch(float pitch) { 1019 synchronized (mStartLock) { 1020 int result = ERROR; 1021 if (!mStarted) { 1022 return result; 1023 } 1024 try { 1025 // the pitch is not set here, instead it is cached so it will be associated 1026 // with all upcoming utterances. 1027 if (pitch > 0) { 1028 int p = (int)(pitch*100); 1029 mCachedParams[Engine.PARAM_POSITION_PITCH + 1] = String.valueOf(p); 1030 result = SUCCESS; 1031 } 1032 } catch (NullPointerException e) { 1033 // TTS died; restart it. 1034 Log.e("TextToSpeech.java - setPitch", "NullPointerException"); 1035 e.printStackTrace(); 1036 mStarted = false; 1037 initTts(); 1038 } catch (IllegalStateException e) { 1039 // TTS died; restart it. 1040 Log.e("TextToSpeech.java - setPitch", "IllegalStateException"); 1041 e.printStackTrace(); 1042 mStarted = false; 1043 initTts(); 1044 } finally { 1045 return result; 1046 } 1047 } 1048 } 1049 1050 1051 /** 1052 * Sets the language for the TextToSpeech engine. 1053 * The TextToSpeech engine will try to use the closest match to the specified 1054 * language as represented by the Locale, but there is no guarantee that the exact same Locale 1055 * will be used. Use {@link #isLanguageAvailable(Locale)} to check the level of support 1056 * before choosing the language to use for the next utterances. 1057 * 1058 * @param loc 1059 * The locale describing the language to be used. 1060 * 1061 * @return code indicating the support status for the locale. See {@link #LANG_AVAILABLE}, 1062 * {@link #LANG_COUNTRY_AVAILABLE}, {@link #LANG_COUNTRY_VAR_AVAILABLE}, 1063 * {@link #LANG_MISSING_DATA} and {@link #LANG_NOT_SUPPORTED}. 1064 */ 1065 public int setLanguage(Locale loc) { 1066 synchronized (mStartLock) { 1067 int result = LANG_NOT_SUPPORTED; 1068 if (!mStarted) { 1069 return result; 1070 } 1071 try { 1072 String language = loc.getISO3Language(); 1073 String country = loc.getISO3Country(); 1074 String variant = loc.getVariant(); 1075 // Check if the language, country, variant are available, and cache 1076 // the available parts. 1077 // Note that the language is not actually set here, instead it is cached so it 1078 // will be associated with all upcoming utterances. 1079 result = mITts.isLanguageAvailable(language, country, variant, mCachedParams); 1080 if (result >= LANG_AVAILABLE){ 1081 mCachedParams[Engine.PARAM_POSITION_LANGUAGE + 1] = language; 1082 if (result >= LANG_COUNTRY_AVAILABLE){ 1083 mCachedParams[Engine.PARAM_POSITION_COUNTRY + 1] = country; 1084 } else { 1085 mCachedParams[Engine.PARAM_POSITION_COUNTRY + 1] = ""; 1086 } 1087 if (result >= LANG_COUNTRY_VAR_AVAILABLE){ 1088 mCachedParams[Engine.PARAM_POSITION_VARIANT + 1] = variant; 1089 } else { 1090 mCachedParams[Engine.PARAM_POSITION_VARIANT + 1] = ""; 1091 } 1092 } 1093 } catch (RemoteException e) { 1094 // TTS died; restart it. 1095 Log.e("TextToSpeech.java - setLanguage", "RemoteException"); 1096 e.printStackTrace(); 1097 mStarted = false; 1098 initTts(); 1099 } catch (NullPointerException e) { 1100 // TTS died; restart it. 1101 Log.e("TextToSpeech.java - setLanguage", "NullPointerException"); 1102 e.printStackTrace(); 1103 mStarted = false; 1104 initTts(); 1105 } catch (IllegalStateException e) { 1106 // TTS died; restart it. 1107 Log.e("TextToSpeech.java - setLanguage", "IllegalStateException"); 1108 e.printStackTrace(); 1109 mStarted = false; 1110 initTts(); 1111 } finally { 1112 return result; 1113 } 1114 } 1115 } 1116 1117 1118 /** 1119 * Returns a Locale instance describing the language currently being used by the TextToSpeech 1120 * engine. 1121 * @return language, country (if any) and variant (if any) used by the engine stored in a Locale 1122 * instance, or null is the TextToSpeech engine has failed. 1123 */ 1124 public Locale getLanguage() { 1125 synchronized (mStartLock) { 1126 if (!mStarted) { 1127 return null; 1128 } 1129 try { 1130 // Only do a call to the native synth if there is nothing in the cached params 1131 if (mCachedParams[Engine.PARAM_POSITION_LANGUAGE + 1].length() < 1){ 1132 String[] locStrings = mITts.getLanguage(); 1133 if ((locStrings != null) && (locStrings.length == 3)) { 1134 return new Locale(locStrings[0], locStrings[1], locStrings[2]); 1135 } else { 1136 return null; 1137 } 1138 } else { 1139 return new Locale(mCachedParams[Engine.PARAM_POSITION_LANGUAGE + 1], 1140 mCachedParams[Engine.PARAM_POSITION_COUNTRY + 1], 1141 mCachedParams[Engine.PARAM_POSITION_VARIANT + 1]); 1142 } 1143 } catch (RemoteException e) { 1144 // TTS died; restart it. 1145 Log.e("TextToSpeech.java - getLanguage", "RemoteException"); 1146 e.printStackTrace(); 1147 mStarted = false; 1148 initTts(); 1149 } catch (NullPointerException e) { 1150 // TTS died; restart it. 1151 Log.e("TextToSpeech.java - getLanguage", "NullPointerException"); 1152 e.printStackTrace(); 1153 mStarted = false; 1154 initTts(); 1155 } catch (IllegalStateException e) { 1156 // TTS died; restart it. 1157 Log.e("TextToSpeech.java - getLanguage", "IllegalStateException"); 1158 e.printStackTrace(); 1159 mStarted = false; 1160 initTts(); 1161 } 1162 return null; 1163 } 1164 } 1165 1166 /** 1167 * Checks if the specified language as represented by the Locale is available and supported. 1168 * 1169 * @param loc 1170 * The Locale describing the language to be used. 1171 * 1172 * @return code indicating the support status for the locale. See {@link #LANG_AVAILABLE}, 1173 * {@link #LANG_COUNTRY_AVAILABLE}, {@link #LANG_COUNTRY_VAR_AVAILABLE}, 1174 * {@link #LANG_MISSING_DATA} and {@link #LANG_NOT_SUPPORTED}. 1175 */ 1176 public int isLanguageAvailable(Locale loc) { 1177 synchronized (mStartLock) { 1178 int result = LANG_NOT_SUPPORTED; 1179 if (!mStarted) { 1180 return result; 1181 } 1182 try { 1183 result = mITts.isLanguageAvailable(loc.getISO3Language(), 1184 loc.getISO3Country(), loc.getVariant(), mCachedParams); 1185 } catch (RemoteException e) { 1186 // TTS died; restart it. 1187 Log.e("TextToSpeech.java - isLanguageAvailable", "RemoteException"); 1188 e.printStackTrace(); 1189 mStarted = false; 1190 initTts(); 1191 } catch (NullPointerException e) { 1192 // TTS died; restart it. 1193 Log.e("TextToSpeech.java - isLanguageAvailable", "NullPointerException"); 1194 e.printStackTrace(); 1195 mStarted = false; 1196 initTts(); 1197 } catch (IllegalStateException e) { 1198 // TTS died; restart it. 1199 Log.e("TextToSpeech.java - isLanguageAvailable", "IllegalStateException"); 1200 e.printStackTrace(); 1201 mStarted = false; 1202 initTts(); 1203 } finally { 1204 return result; 1205 } 1206 } 1207 } 1208 1209 1210 /** 1211 * Synthesizes the given text to a file using the specified parameters. 1212 * 1213 * @param text 1214 * The String of text that should be synthesized 1215 * @param params 1216 * The list of parameters to be used. Can be null if no parameters are given. 1217 * They are specified using a (key, value) pair, where the key can be 1218 * {@link Engine#KEY_PARAM_UTTERANCE_ID}. 1219 * @param filename 1220 * The string that gives the full output filename; it should be 1221 * something like "/sdcard/myappsounds/mysound.wav". 1222 * 1223 * @return Code indicating success or failure. See {@link #ERROR} and {@link #SUCCESS}. 1224 */ 1225 public int synthesizeToFile(String text, HashMap<String,String> params, 1226 String filename) { 1227 synchronized (mStartLock) { 1228 int result = ERROR; 1229 if (!mStarted) { 1230 return result; 1231 } 1232 try { 1233 if ((params != null) && (!params.isEmpty())) { 1234 // no need to read the stream type here 1235 String extra = params.get(Engine.KEY_PARAM_UTTERANCE_ID); 1236 if (extra != null) { 1237 mCachedParams[Engine.PARAM_POSITION_UTTERANCE_ID + 1] = extra; 1238 } 1239 extra = params.get(Engine.KEY_PARAM_ENGINE); 1240 if (extra != null) { 1241 mCachedParams[Engine.PARAM_POSITION_ENGINE + 1] = extra; 1242 } 1243 } 1244 result = mITts.synthesizeToFile(mPackageName, text, mCachedParams, filename) ? 1245 SUCCESS : ERROR; 1246 } catch (RemoteException e) { 1247 // TTS died; restart it. 1248 Log.e("TextToSpeech.java - synthesizeToFile", "RemoteException"); 1249 e.printStackTrace(); 1250 mStarted = false; 1251 initTts(); 1252 } catch (NullPointerException e) { 1253 // TTS died; restart it. 1254 Log.e("TextToSpeech.java - synthesizeToFile", "NullPointerException"); 1255 e.printStackTrace(); 1256 mStarted = false; 1257 initTts(); 1258 } catch (IllegalStateException e) { 1259 // TTS died; restart it. 1260 Log.e("TextToSpeech.java - synthesizeToFile", "IllegalStateException"); 1261 e.printStackTrace(); 1262 mStarted = false; 1263 initTts(); 1264 } finally { 1265 resetCachedParams(); 1266 return result; 1267 } 1268 } 1269 } 1270 1271 1272 /** 1273 * Convenience method to reset the cached parameters to the current default values 1274 * if they are not persistent between calls to the service. 1275 */ 1276 private void resetCachedParams() { 1277 mCachedParams[Engine.PARAM_POSITION_STREAM + 1] = 1278 String.valueOf(Engine.DEFAULT_STREAM); 1279 mCachedParams[Engine.PARAM_POSITION_UTTERANCE_ID+ 1] = ""; 1280 } 1281 1282 /** 1283 * Sets the OnUtteranceCompletedListener that will fire when an utterance completes. 1284 * 1285 * @param listener 1286 * The OnUtteranceCompletedListener 1287 * 1288 * @return Code indicating success or failure. See {@link #ERROR} and {@link #SUCCESS}. 1289 */ 1290 public int setOnUtteranceCompletedListener( 1291 final OnUtteranceCompletedListener listener) { 1292 synchronized (mStartLock) { 1293 int result = ERROR; 1294 if (!mStarted) { 1295 return result; 1296 } 1297 mITtscallback = new ITtsCallback.Stub() { 1298 public void utteranceCompleted(String utteranceId) throws RemoteException { 1299 if (listener != null) { 1300 listener.onUtteranceCompleted(utteranceId); 1301 } 1302 } 1303 }; 1304 try { 1305 result = mITts.registerCallback(mPackageName, mITtscallback); 1306 } catch (RemoteException e) { 1307 // TTS died; restart it. 1308 Log.e("TextToSpeech.java - registerCallback", "RemoteException"); 1309 e.printStackTrace(); 1310 mStarted = false; 1311 initTts(); 1312 } catch (NullPointerException e) { 1313 // TTS died; restart it. 1314 Log.e("TextToSpeech.java - registerCallback", "NullPointerException"); 1315 e.printStackTrace(); 1316 mStarted = false; 1317 initTts(); 1318 } catch (IllegalStateException e) { 1319 // TTS died; restart it. 1320 Log.e("TextToSpeech.java - registerCallback", "IllegalStateException"); 1321 e.printStackTrace(); 1322 mStarted = false; 1323 initTts(); 1324 } finally { 1325 return result; 1326 } 1327 } 1328 } 1329 1330 /** 1331 * Sets the speech synthesis engine to be used by its packagename. 1332 * 1333 * @param enginePackageName 1334 * The packagename for the synthesis engine (ie, "com.svox.pico") 1335 * 1336 * @return Code indicating success or failure. See {@link #ERROR} and {@link #SUCCESS}. 1337 */ 1338 public int setEngineByPackageName(String enginePackageName) { 1339 synchronized (mStartLock) { 1340 int result = TextToSpeech.ERROR; 1341 if (!mStarted) { 1342 return result; 1343 } 1344 try { 1345 result = mITts.setEngineByPackageName(enginePackageName); 1346 if (result == TextToSpeech.SUCCESS){ 1347 mCachedParams[Engine.PARAM_POSITION_ENGINE + 1] = enginePackageName; 1348 } 1349 } catch (RemoteException e) { 1350 // TTS died; restart it. 1351 Log.e("TextToSpeech.java - setEngineByPackageName", "RemoteException"); 1352 e.printStackTrace(); 1353 mStarted = false; 1354 initTts(); 1355 } catch (NullPointerException e) { 1356 // TTS died; restart it. 1357 Log.e("TextToSpeech.java - setEngineByPackageName", "NullPointerException"); 1358 e.printStackTrace(); 1359 mStarted = false; 1360 initTts(); 1361 } catch (IllegalStateException e) { 1362 // TTS died; restart it. 1363 Log.e("TextToSpeech.java - setEngineByPackageName", "IllegalStateException"); 1364 e.printStackTrace(); 1365 mStarted = false; 1366 initTts(); 1367 } finally { 1368 return result; 1369 } 1370 } 1371 } 1372 1373 1374 /** 1375 * Gets the packagename of the default speech synthesis engine. 1376 * 1377 * @return Packagename of the TTS engine that the user has chosen as their default. 1378 * 1379 * @hide 1380 */ 1381 public String getDefaultEngine() { 1382 synchronized (mStartLock) { 1383 String engineName = ""; 1384 if (!mStarted) { 1385 return engineName; 1386 } 1387 try { 1388 engineName = mITts.getDefaultEngine(); 1389 } catch (RemoteException e) { 1390 // TTS died; restart it. 1391 Log.e("TextToSpeech.java - setEngineByPackageName", "RemoteException"); 1392 e.printStackTrace(); 1393 mStarted = false; 1394 initTts(); 1395 } catch (NullPointerException e) { 1396 // TTS died; restart it. 1397 Log.e("TextToSpeech.java - setEngineByPackageName", "NullPointerException"); 1398 e.printStackTrace(); 1399 mStarted = false; 1400 initTts(); 1401 } catch (IllegalStateException e) { 1402 // TTS died; restart it. 1403 Log.e("TextToSpeech.java - setEngineByPackageName", "IllegalStateException"); 1404 e.printStackTrace(); 1405 mStarted = false; 1406 initTts(); 1407 } finally { 1408 return engineName; 1409 } 1410 } 1411 } 1412 1413 1414 /** 1415 * Returns whether or not the user is forcing their defaults to override the 1416 * Text-To-Speech settings set by applications. 1417 * 1418 * @return Whether or not defaults are enforced. 1419 * 1420 * @hide 1421 */ 1422 public boolean areDefaultsEnforced() { 1423 synchronized (mStartLock) { 1424 boolean defaultsEnforced = false; 1425 if (!mStarted) { 1426 return defaultsEnforced; 1427 } 1428 try { 1429 defaultsEnforced = mITts.areDefaultsEnforced(); 1430 } catch (RemoteException e) { 1431 // TTS died; restart it. 1432 Log.e("TextToSpeech.java - areDefaultsEnforced", "RemoteException"); 1433 e.printStackTrace(); 1434 mStarted = false; 1435 initTts(); 1436 } catch (NullPointerException e) { 1437 // TTS died; restart it. 1438 Log.e("TextToSpeech.java - areDefaultsEnforced", "NullPointerException"); 1439 e.printStackTrace(); 1440 mStarted = false; 1441 initTts(); 1442 } catch (IllegalStateException e) { 1443 // TTS died; restart it. 1444 Log.e("TextToSpeech.java - areDefaultsEnforced", "IllegalStateException"); 1445 e.printStackTrace(); 1446 mStarted = false; 1447 initTts(); 1448 } finally { 1449 return defaultsEnforced; 1450 } 1451 } 1452 } 1453} 1454