How to Take Voice Dictation on your Android Wearable

By Michael Burton

Do you have an Android Wear watch? If so, you probably love it, and you’ve already noticed that it doesn’t have a keyboard. If not, try looking for one. I’ll wait.

If you’re an Android Wear developer, you should know that most apps on Android Wear are usually read-only. Android Wear apps are useful for getting notified about particular things you need to do, but if you want to do anything complicated, you’ll most likely pull out your phone and do it there rather than on your watch.

Voice control is one exciting exception to this rule. With voice dictation, you can easily “type” information into your watch without having to use a keyboard.

Here, you’ll learn how to add new items to your database using your voice.

Three types of voice control

Android Wear provides three types of voice control out of the box.

  • System-provided voice actions, such as “Take a note” or “Call a cab/taxi”.

  • App-provided voice “Start” commands, such as “Start Tasks” or “Start MyRunningApp”

  • Free-form voice dictation

The system-provided voice actions are the most convenient for users. They don’t require the user to learn any new voice prompts, and they “just work” from anywhere. If one of Android’s built-in voice actions is appropriate for your app, this is the best way to go.

The app-provided voice “Start” commands are a viable but less powerful way to add voice commands to your app. Each activity in your app can have a separate start name specified by the activity’s label. For example, if you set your Tasks activity label to MyTasksApp, then your Tasks activity would launch when the user says “Start MyTasksApp”. Unlike the system-provided voice actions, which recognize common alternatives to the voice action, the user must match the label exactly. Saying “Start TasksApp” won’t start your app, for example.

The free-form voice dictation option is a very powerful option, but it does require that the user already be in your app in order to take advantage of it. Because it’s not always obvious how to launch an Android Wear app, this option is a good one but less common.

Android Wear comes with a system-provided “Take a note” action, so let’s use that to add a Task to our app.

Setup the Intent Filter

When the user says “Take a note” to their Android watch, the resulting text is sent to your app via an Intent. To capture that intent, you must create an activity and an intent filter that matches the intent.

Add a TakeVoiceNote activity to the AndroidManifest.xml of your Wear app, and register an intent filter to capture the SELF_NOTE intent:

<activity android:name=".TakeVoiceNote">
  <intent-filter>
    <action android:name="android.intent.action.SEND"/>
    <category 
      android:name="android.intent.category.DEFAULT"/>
    <category android:name
      ="com.google.android.voicesearch.SELF_NOTE"/>
    <data android:mimeType="text/plain"/>
  </intent-filter>
</activity>

Getting the voice text

It’s the easiest thing in the world to get the output from the Speech recognizer activity. You just need to add the TakeVoiceNote activity and retrieve the text from the intent, like so:

public class TakeVoiceNote extends Activity
{
  @Override
  protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    String voiceNote 
        = getIntent().getStringExtra(Intent.EXTRA_TEXT);
  }
}

That’s it! Whatever the user said has been transcribed and placed into the voiceNote variable.

Now the tricky part is what to do with that text.

Open a connection to Google Play

The Voice action APIs are quite simple, but to use them you’ll need to set up the Google Play Services APIs, and those are a little more complicated to use.

To add Google Play Services Location API to your project, place the following dependency into your build.config file:

dependencies {
  compile 
    'com.google.android.gms:play-services-wearable:6.5.87'
}

Next, add the following to your AndroidManifest.xml:

<application … >
  <meta-data
    android:name="com.google.android.gms.version"
    android:value
      ="@integer/google_play_services_version"/>
</application>

To establish a connection to the Google Play Services, add the following to your activity:

// The Google API client, for wearable services
  GoogleApiClient googleApiClient;
  @Override
  public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    googleApiClient = new GoogleApiClient.Builder(this)
      .addConnectionCallbacks(this)
      .addOnConnectionFailedListener(this)
      .addApi(Wearable.API)
      .build();  
    …
  }
  @Override
  public void onStart() {
    super.onStart();
    googleApiClient.connect();
  }
  @Override
  public void onStop() {
    googleApiClient.disconnect();
    super.onStop();
  }

Remember that the application ID of your phone app and the Wear app must be the same! If they are different, the connection will not be established.

This code creates a new GoogleApiClient object in your onCreate() to connect to the Google Play Services, and then it tries to connect in your onStart() and disconnect in your onStop(). The GoogleApiClient needs a callback object to inform it when a connection has been established, so you will need to add callbacks to your activity.

public class TakeVoiceNote extends Activity implements
  GoogleApiClient.ConnectionCallbacks,
  GoogleApiClient.OnConnectionFailedListener
{
  @Override
  public void onConnected(Bundle connectionHint) {
    // Connected to Google Play services!
    // This is where you will write your new task to the
    // database.
  }
  @Override
  public void onConnectionSuspended(int cause) {
    // The Google Play connection has been interrupted.
    // Disable any UI components that depend on Google 
    // APIs until onConnected() is called.
    //
    // This example doesn't need to do anything here.
  }
  @Override
  public void onConnectionFailed(ConnectionResult result) 
  {
    // This callback is important for handling errors 
    // that may occur while attempting to connect with 
    // Google.
    //
    // For more information about how to handle errors, 
    // see
    // https://developer.android.com/google/auth/api-client.html
  }
}

Congratulations! You’ve now properly set up a connection to Google Play Services which will automatically disconnect when your activity is stopped. The next step is to ask the phone to create a new task.

Asking the phone to add a new task

Now that you have a connection to Google Play, the next step is to send the voice text to your phone so that the phone can add a new task to its database.

Update the onConnected() method of your activity to send a message to your phone with the contents of the voice dictation:

public class TakeVoiceNote extends Activity
  implements GoogleApiClient.ConnectionCallbacks, 
             GoogleApiClient.OnConnectionFailedListener
{
  // The path (sort of like a URI) that identifies the
  // operation you want to perform on the handset.
  private static final String PATH_ADD_TASK = "/addTask";

  @Override
  public void onConnected(Bundle bundle) {
    Log.d("TakeVoiceNote", "onConnected");
   
    // The speech recognition text is passed in via the 
    // intent
    String voiceNote = getIntent().getStringExtra(
      Intent.EXTRA_TEXT);
    // Convert the string to bytes
    final byte[] voiceNoteBytes =
      voiceNote.getBytes(Charset.forName("utf-8"));
    // Get a list of all of the devices that you're 
    // connected to. Usually this will just be your 
    // phone. Any other devices will ignore your message.
    Wearable.NodeApi.getConnectedNodes(googleApiClient)
      .setResultCallback(
        new ResultCallback<GetConnectedNodesResult>() {
          @Override
          public void onResult(
                        GetConnectedNodesResult nodes) 
          {
            for (Node node : nodes.getNodes()) {
             
              // Send the phone a message requesting that
              // it add the task to the database
              Wearable.MessageApi.sendMessage(
                googleApiClient,
                node.getId(),
                PATH_ADD_TASK,
                voiceNoteBytes
                );
             
            }
           
            finish();
          }
        }
      );
  }
}

Create the new task on the phone

The only thing left to do is to listen for the message on your phone so that you can create a new task when requested. You’ll do this with a simple WearableListenerService.

In your phone app, create a new class named AddTaskWearableListenerService and add the following code:

public class AddTaskWearableListenerService extends
  WearableListenerService
{
  // Should match the string in TakeVoiceNote
  private static final String PATH_ADD_TASK = "/addTask";
  @Override
  public void onMessageReceived(
                          MessageEvent messageEvent) 
  {
    if( PATH_ADD_TASK.equals(messageEvent.getPath())) {
      // Create the ContentValues object that stores all
      // of the information for the task
      String title = new String(messageEvent.getData(),
        Charset.forName("utf-8"));
      ContentValues values = new ContentValues();
      values.put(COLUMN_TITLE, title);
      values.put(COLUMN_NOTES, ");
      values.put(COLUMN_DATE_TIME, 
          System.currentTimeMillis());
      // Insert the task into the database
      getContentResolver().insert(CONTENT_URI, values);
    }
  }
}

You’ll need to register the service in your phone app’s AndroidManifest.xml, so add the following to your application node:

<service android:name=".AddTaskWearableListenerService">
  <intent-filter>
    <action android:name
      ="com.google.android.gms.wearable.BIND_LISTENER"/>
  </intent-filter>
</service>
    <service android:name=".AddTaskWearableListenerService">

Test it out!

If you’re using an emulator for your Android Wear device, you’ll want to connect it to your Android phone.

Once that’s up and running, go ahead and tap your Android Wear to bring up the actions menu, and then click the Take a note option.

image0.png

If you’re using a watch emulator, then type in your response.

image1.png

Once the note saves, pull up the Tasks app on your phone and you should see the new item:

image2.png

Congratulations! You’ve successfully dictated a voice note and saved it to your Tasks app.

There are all kinds of interesting things you can do with Voice Controls on the Android and Android Wear platforms. For some more ideas, check out the Adding Voice Capabilities and Receiving Voice Input in a Notification articles on the Android Developer website. Happy hacking!