1 /*
2  * Copyright (C) 2008 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 
17 package com.example.android.apis.app;
18 
19 import com.example.android.apis.R;
20 
21 import android.app.Activity;
22 import android.content.BroadcastReceiver;
23 import android.content.Context;
24 import android.content.Intent;
25 import android.content.pm.PackageManager;
26 import android.content.pm.ResolveInfo;
27 import android.os.Bundle;
28 import android.os.Handler;
29 import android.speech.RecognizerIntent;
30 import android.util.Log;
31 import android.view.View;
32 import android.view.View.OnClickListener;
33 import android.widget.ArrayAdapter;
34 import android.widget.Button;
35 import android.widget.ListView;
36 import android.widget.Spinner;
37 import android.widget.SpinnerAdapter;
38 import android.widget.TextView;
39 import android.widget.Toast;
40 
41 import java.util.ArrayList;
42 import java.util.List;
43 
44 /**
45  * Sample code that invokes the speech recognition intent API.
46  */
47 public class VoiceRecognition extends Activity implements OnClickListener {
48 
49     private static final String TAG = "VoiceRecognition";
50 
51     private static final int VOICE_RECOGNITION_REQUEST_CODE = 1234;
52 
53     private ListView mList;
54 
55     private Handler mHandler;
56 
57     private Spinner mSupportedLanguageView;
58 
59     /**
60      * Called with the activity is first created.
61      */
62     @Override
onCreate(Bundle savedInstanceState)63     public void onCreate(Bundle savedInstanceState) {
64         super.onCreate(savedInstanceState);
65         mHandler = new Handler();
66 
67         // Inflate our UI from its XML layout description.
68         setContentView(R.layout.voice_recognition);
69 
70         // Get display items for later interaction
71         Button speakButton = (Button) findViewById(R.id.btn_speak);
72 
73         mList = (ListView) findViewById(R.id.list);
74 
75         mSupportedLanguageView = (Spinner) findViewById(R.id.supported_languages);
76 
77         // Check to see if a recognition activity is present
78         PackageManager pm = getPackageManager();
79         List<ResolveInfo> activities = pm.queryIntentActivities(
80                 new Intent(RecognizerIntent.ACTION_RECOGNIZE_SPEECH), 0);
81         if (activities.size() != 0) {
82             speakButton.setOnClickListener(this);
83         } else {
84             speakButton.setEnabled(false);
85             speakButton.setText("Recognizer not present");
86         }
87 
88         // Most of the applications do not have to handle the voice settings. If the application
89         // does not require a recognition in a specific language (i.e., different from the system
90         // locale), the application does not need to read the voice settings.
91         refreshVoiceSettings();
92     }
93 
94     /**
95      * Handle the click on the start recognition button.
96      */
onClick(View v)97     public void onClick(View v) {
98         if (v.getId() == R.id.btn_speak) {
99             startVoiceRecognitionActivity();
100         }
101     }
102 
103     /**
104      * Fire an intent to start the speech recognition activity.
105      */
startVoiceRecognitionActivity()106     private void startVoiceRecognitionActivity() {
107         Intent intent = new Intent(RecognizerIntent.ACTION_RECOGNIZE_SPEECH);
108 
109         // Specify the calling package to identify your application
110         intent.putExtra(RecognizerIntent.EXTRA_CALLING_PACKAGE, getClass().getPackage().getName());
111 
112         // Display an hint to the user about what he should say.
113         intent.putExtra(RecognizerIntent.EXTRA_PROMPT, "Speech recognition demo");
114 
115         // Given an hint to the recognizer about what the user is going to say
116         intent.putExtra(RecognizerIntent.EXTRA_LANGUAGE_MODEL,
117                 RecognizerIntent.LANGUAGE_MODEL_FREE_FORM);
118 
119         // Specify how many results you want to receive. The results will be sorted
120         // where the first result is the one with higher confidence.
121         intent.putExtra(RecognizerIntent.EXTRA_MAX_RESULTS, 5);
122 
123         // Specify the recognition language. This parameter has to be specified only if the
124         // recognition has to be done in a specific language and not the default one (i.e., the
125         // system locale). Most of the applications do not have to set this parameter.
126         if (!mSupportedLanguageView.getSelectedItem().toString().equals("Default")) {
127             intent.putExtra(RecognizerIntent.EXTRA_LANGUAGE,
128                     mSupportedLanguageView.getSelectedItem().toString());
129         }
130 
131         startActivityForResult(intent, VOICE_RECOGNITION_REQUEST_CODE);
132     }
133 
134     /**
135      * Handle the results from the recognition activity.
136      */
137     @Override
onActivityResult(int requestCode, int resultCode, Intent data)138     protected void onActivityResult(int requestCode, int resultCode, Intent data) {
139         if (requestCode == VOICE_RECOGNITION_REQUEST_CODE && resultCode == RESULT_OK) {
140             // Fill the list view with the strings the recognizer thought it could have heard
141             ArrayList<String> matches = data.getStringArrayListExtra(
142                     RecognizerIntent.EXTRA_RESULTS);
143             mList.setAdapter(new ArrayAdapter<String>(this, android.R.layout.simple_list_item_1,
144                     matches));
145         }
146 
147         super.onActivityResult(requestCode, resultCode, data);
148     }
149 
refreshVoiceSettings()150     private void refreshVoiceSettings() {
151         Log.i(TAG, "Sending broadcast");
152         sendOrderedBroadcast(RecognizerIntent.getVoiceDetailsIntent(this), null,
153                 new SupportedLanguageBroadcastReceiver(), null, Activity.RESULT_OK, null, null);
154     }
155 
updateSupportedLanguages(List<String> languages)156     private void updateSupportedLanguages(List<String> languages) {
157         // We add "Default" at the beginning of the list to simulate default language.
158         languages.add(0, "Default");
159 
160         SpinnerAdapter adapter = new ArrayAdapter<CharSequence>(this,
161                 android.R.layout.simple_spinner_item, languages.toArray(
162                         new String[languages.size()]));
163         mSupportedLanguageView.setAdapter(adapter);
164     }
165 
updateLanguagePreference(String language)166     private void updateLanguagePreference(String language) {
167         TextView textView = (TextView) findViewById(R.id.language_preference);
168         textView.setText(language);
169     }
170 
171     /**
172      * Handles the response of the broadcast request about the recognizer supported languages.
173      *
174      * The receiver is required only if the application wants to do recognition in a specific
175      * language.
176      */
177     private class SupportedLanguageBroadcastReceiver extends BroadcastReceiver {
178 
179         @Override
onReceive(Context context, final Intent intent)180         public void onReceive(Context context, final Intent intent) {
181             Log.i(TAG, "Receiving broadcast " + intent);
182 
183             final Bundle extra = getResultExtras(false);
184 
185             if (getResultCode() != Activity.RESULT_OK) {
186                 mHandler.post(new Runnable() {
187                     @Override
188                     public void run() {
189                         showToast("Error code:" + getResultCode());
190                     }
191                 });
192             }
193 
194             if (extra == null) {
195                 mHandler.post(new Runnable() {
196                     @Override
197                     public void run() {
198                         showToast("No extra");
199                     }
200                 });
201             }
202 
203             if (extra.containsKey(RecognizerIntent.EXTRA_SUPPORTED_LANGUAGES)) {
204                 mHandler.post(new Runnable() {
205 
206                     @Override
207                     public void run() {
208                         updateSupportedLanguages(extra.getStringArrayList(
209                                 RecognizerIntent.EXTRA_SUPPORTED_LANGUAGES));
210                     }
211                 });
212             }
213 
214             if (extra.containsKey(RecognizerIntent.EXTRA_LANGUAGE_PREFERENCE)) {
215                 mHandler.post(new Runnable() {
216 
217                     @Override
218                     public void run() {
219                         updateLanguagePreference(
220                                 extra.getString(RecognizerIntent.EXTRA_LANGUAGE_PREFERENCE));
221                     }
222                 });
223             }
224         }
225 
showToast(String text)226         private void showToast(String text) {
227             Toast.makeText(VoiceRecognition.this, text, 1000).show();
228         }
229     }
230 }
231