PageRenderTime 32ms CodeModel.GetById 24ms RepoModel.GetById 0ms app.codeStats 0ms

/tts/src/com/google/tts/TextToSpeechBeta.java

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