1 /* 2 * Copyright (C) 2011 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of 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, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 package com.example.android.ttsengine; 17 18 import android.app.Activity; 19 import android.content.Intent; 20 import android.os.Bundle; 21 import android.speech.tts.TextToSpeech; 22 import android.text.TextUtils; 23 import android.util.Log; 24 25 import java.io.IOException; 26 import java.io.InputStream; 27 import java.util.ArrayList; 28 import java.util.Arrays; 29 import java.util.List; 30 31 /* 32 * Checks if the voice data is present. 33 */ 34 public class CheckVoiceData extends Activity { 35 private static final String TAG = "CheckVoiceData"; 36 37 private static final String[] SUPPORTED_LANGUAGES = { "eng-GBR", "eng-USA" }; 38 39 @Override 40 protected void onCreate(Bundle savedInstanceState) { 41 super.onCreate(savedInstanceState); 42 43 Intent intent = getIntent(); 44 List<String> checkLanguages = getCheckVoiceDataFor(intent); 45 46 // If the call didn't specify which languages to check, check 47 // for all the supported ones. 48 if (checkLanguages.isEmpty()) { 49 checkLanguages = Arrays.asList(SUPPORTED_LANGUAGES); 50 } 51 52 ArrayList<String> available = new ArrayList<String>(); 53 ArrayList<String> unavailable = new ArrayList<String>(); 54 55 for (String lang : checkLanguages) { 56 // This check is required because checkLanguages might contain 57 // an arbitrary list of languages if the intent specified them 58 // {@link #getCheckVoiceDataFor}. 59 if (isLanguageSupported(lang)) { 60 if (isDataInstalled(lang)) { 61 available.add(lang); 62 } else { 63 unavailable.add(lang); 64 } 65 } 66 } 67 68 int result; 69 if (!checkLanguages.isEmpty() && available.isEmpty()) { 70 // No voices available at all. 71 result = TextToSpeech.Engine.CHECK_VOICE_DATA_FAIL; 72 } else if (!unavailable.isEmpty()) { 73 // Some voices are available, but some have missing 74 // data. 75 result = TextToSpeech.Engine.CHECK_VOICE_DATA_MISSING_DATA; 76 } else { 77 // All voices are available. 78 result = TextToSpeech.Engine.CHECK_VOICE_DATA_PASS; 79 } 80 81 // We now return the list of available and unavailable voices 82 // as well as the return code. 83 Intent returnData = new Intent(); 84 returnData.putStringArrayListExtra( 85 TextToSpeech.Engine.EXTRA_AVAILABLE_VOICES, available); 86 returnData.putStringArrayListExtra( 87 TextToSpeech.Engine.EXTRA_UNAVAILABLE_VOICES, unavailable); 88 setResult(result, returnData); 89 finish(); 90 } 91 92 /** 93 * The intent that launches this activity can contain an intent extra 94 * {@link TextToSpeech.Engine.EXTRA_CHECK_VOICE_DATA_FOR} that might specify 95 * a given language to check voice data for. If the intent does not contain 96 * this extra, we assume that a voice check for all supported languages 97 * was requested. 98 */ 99 private List<String> getCheckVoiceDataFor(Intent intent) { 100 ArrayList<String> list = intent.getStringArrayListExtra( 101 TextToSpeech.Engine.EXTRA_CHECK_VOICE_DATA_FOR); 102 ArrayList<String> ret = new ArrayList<String>(); 103 if (list != null) { 104 for (String lang : list) { 105 if (!TextUtils.isEmpty(lang)) { 106 ret.add(lang); 107 } 108 } 109 } 110 return ret; 111 } 112 113 /** 114 * Checks whether a given language is in the list of supported languages. 115 */ 116 private boolean isLanguageSupported(String input) { 117 for (String lang : SUPPORTED_LANGUAGES) { 118 if (lang.equals(input)) { 119 return true; 120 } 121 } 122 123 return false; 124 } 125 126 /* 127 * Note that in our example, all data is packaged in our APK as 128 * assets (it could be a raw resource as well). This check is unnecessary 129 * because it will always succeed. 130 * 131 * If for example, engine data was downloaded or installed on external storage, 132 * this check would make much more sense. 133 */ 134 private boolean isDataInstalled(String lang) { 135 try { 136 InputStream is = getAssets().open(lang + ".freq"); 137 138 if (is != null) { 139 is.close(); 140 } else { 141 return false; 142 } 143 } catch (IOException e) { 144 Log.w(TAG, "Unable to find data for: " + lang + ", exception: " + e); 145 return false; 146 } 147 148 // The asset InputStream was non null, and therefore this 149 // data file is available. 150 return true; 151 } 152 } 153