- Getting Started
- Android Manifest File
- Activities
- Layouts
- Example Application: Building the Layout View and Main Activity
- Testing
- Conclusion
Example Application: Building the Layout View and Main Activity
Bring up the activity_main.xml file in the res/layouts folder. Click the activity_main view xml tab and remove the default text view. After this, click the Graphical Layout tab and select the Button Widget from the Form Widgets category by dragging it onto the view. You should now have a simple Button showing on the view. Double-click the button and change the text from “Button" to “Speak!" in the XML view. Your code should look something like this:
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent" android:layout_height="match_parent" > <Button android:id="@+id/button1" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_alignParentLeft="true" android:layout_alignParentTop="true" android:layout_marginLeft="87dp" android:layout_marginTop="75dp" android:text="Speak!" /> </RelativeLayout>
In order to make the button active, we need to define a method that will be called when clicked. We can call this method onClick, which is the default override method for button clicks within activities. To do this, just add the following parameter after the text parameter for the button:
android:onClick="onClick"
Now that the view has been established, we can add code to the main activity to make the button do something. Open the main activity class from your src folder and add the following code in bold:
package com.example.simplevoicecommand; import android.os.Bundle; import android.app.Activity; import android.view.Menu; import android.view.View; public class MainActivity extends Activity { @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); } @Override public boolean onCreateOptionsMenu(Menu menu) { getMenuInflater().inflate(R.menu.activity_main, menu); return true; } public void onClick(View v) { switch (v.getId()) { case R.id.button1: startVoiceRecognitionActivity(); break; } } }
As you can see, a new button handler method was added called onClick (derived from the Activity super class). Inside the method, we determine which ID is being passed by the view when a button is clicked, and if an ID called button1 is pressed, then a new method is called to start a voice recognition activity that is not created yet.
The voice recognition activity is going to be part of our main activity, so do not let the name be confusing; it is just a method name and not an activity. To create the activity, add this code under the onClick method that was just created:
void startVoiceRecognitionActivity() { Intent intent = new Intent(RecognizerIntent.ACTION_RECOGNIZE_SPEECH); intent.putExtra(RecognizerIntent.EXTRA_CALLING_PACKAGE, getClass() .getPackage().getName()); intent.putExtra(RecognizerIntent.EXTRA_LANGUAGE_MODEL, RecognizerIntent.LANGUAGE_MODEL_FREE_FORM); intent.putExtra(RecognizerIntent.EXTRA_MAX_RESULTS, 5); startActivityForResult(intent, VOICE_RECOGNITION_REQUEST_CODE); }
Without getting into to much detail about what this method is doing, it is fairly self-describing. An Intent is a special method handler provided by the SDK that initiates actions with parameters. In this example, the extras are the parameters that are to be passed with the intent to the activity for result method. The extras tell the system to expect speech input that will contain up to five results or word sets that match what the speaker said. The language model specifies that whatever the user’s system has as the default locale, to go ahead and use the language associated with that region. The request code is used for the callback method called onActivityForResult, which is invoked by the startActivityForResult method passing the intent and request code. Make the request code a static constant of 1234:
private static final int VOICE_RECOGNITION_REQUEST_CODE = 1234;
Next, create the onActivityForResult class to handle the speech input. Add the following method below the startVoiceRecognitionActivity method:
@Override protected void onActivityResult(int requestCode, int resultCode, Intent data) { String wordStr = null; String[] words = null; String firstWord = null; String secondWord = null; if (requestCode == VOICE_RECOGNITION_REQUEST_CODE && resultCode == RESULT_OK) { ArrayList<String> matches = data .getStringArrayListExtra(RecognizerIntent.EXTRA_RESULTS); wordStr = matches.get(0); words = wordStr.split(" "); firstWord = words[0]; secondWord = words[1]; }
The onActivityForResult method checks the status and request codes to determine if speech recognition is present on the user’s phone. Most phones have this now, so it is just a matter of capturing the words spoken with a call to the getStringArrayListExtra that is passed by the Intent. A string called wordStr was created to only capture the first set of words (remember there can be up to five). And, we are only concerned with the first couple of words, which will likely be open and the name of the app to open.
Now, we are ready to create the code that will open the application. All the speech input skeleton code has been added. Add the following code to the inside of the onActivityResult method:
if (firstWord.equals("open")) { PackageManager packageManager = getPackageManager(); List<PackageInfo> packs = packageManager .getInstalledPackages(0); int size = packs.size(); boolean uninstallApp = false; boolean exceptFlg = false; for (int v = 0; v < size; v++) { PackageInfo p = packs.get(v); String tmpAppName = p.applicationInfo.loadLabel( packageManager).toString(); String pname = p.packageName; urlAddress = urlAddress.toLowerCase(); tmpAppName = tmpAppName.toLowerCase(); if (tmpAppName.trim().toLowerCase(). equals(secondWord.trim().toLowerCase())) { PackageManager pm = this.getPackageManager(); Intent appStartIntent = pm getLaunchIntentForPackage(pname); if (null != appStartIntent) { try { this.startActivity(appStartIntent); } catch (Exception e) { } } } } } // end of open app code } // end of activityOnResult method
There is a bit to digest here, so will only go over the most important elements. Basically, the SDK has a package manager that fetches all installed packages on the person’s phone. Once the list is returned, then is just a matter of iterating through the packages and getting the package info. The application name is retrieved from the loadLabel method. The app name is compared to the speech input, and if there is a match, then an intent for the target application is created and that application’s main activity is launched.