1. Introduction to Android Wear Notifications
Regular Android applications use the Notification API to show important information to the user on phones and tablets. One of the most important features of Android Wear is the ability to take these notifications, and show them to the user on their wrist. In this lesson, I'm going to show you how notifications are shown on Android Wear. And how easy it is to extend this code to look great on wearables. So let's get started.
Notes:
2. Notification Bridging
Let's start by talking about how Android Wear deals with notifications. When an Android handheld and Android Wear device are connected, the handheld automatically pushes notifications to the wearable. On the wearable, each notification appears as a new card in the context stream.
Notifications are shown on the Android Wear device automatically with no extra work required by the developer. If you want to give the best wearable experience to your users, you can add wearable specific extensions with just a few extra lines of code. Let's start off by showing how regular Android notifications work on a phone by loading and running a sample. We'll use the sample: Basic Notifications for this. We'll use the same sample later on in the Android auto messaging lesson as well.
Go to File > Import Sample, and search for notification.
You'll see there's Basic Notifications here. Click on that, and then Next. You can leave everything as the default values. Click Finish and it'll create a new project on your machine based on the basic notifications sample. Now let's build and run the sample.
By clicking the green Play button here, it runs the assembleDebug task to compile it and then it asks where to run it. So we select our phone, which is already connected, and then we hit OK to begin the installation and start running it.
You can see the sample has started on the phone. We'll walk through the code shortly. We click do it to generate the notification...
and you can see it appear here in the notification shade.
When you click on it, you'll see it launch a web browser and open up a URL for the notification documentation, which is what the sample was configured to do. Now lets go back and click Do It again. This will regenerate a new notification.
And if we look at our Android wear devices, you'll see both of them show a notification from the application. This all happens automatically.
We can make the intent trigger by clicking Open on the phone and you'll see it appear here just like it did before. The nice thing is that Android wear takes care of all of this for us. So now I want you to replicate the same steps. Run the sample in a phone or emulator and check that you can get it to work.
Notes:
Addendum - Installing an Android Wear Virtual Device
1. Click Tools > Android > AVD Manager.
2. Click Create Virtual Device
3. Click Wear in the Category list:
4. Select Android Wear Square or Android Wear Round.
5. Click Next.
6. Select a release name (as in the above example, N).
Note: If your system does not support HAXM (e.g., if your computer doesn't have an Intel processor), you may need to create an ARM virtual device instead. Click the "Other Images" tag to select a release with an armeabi-v7a ABI.
7. Configure additional settings for the virtual device (e.g., the device name) and click Finish.
Launch The Device
1. Click AVD Manager.
2. Select the Virtual Wear Device.
3. Click the Play Button.
Pair your handheld with the emulator:
1. On your handheld, install the Android Wear app from Google Play.
2. Connect the handheld to your machine through USB.
3. Forward the AVD's communication port to the connected handheld device with the following adb command (you must do this every time the handheld is connected):
adb -d forward tcp:5601 tcp:5601
Note the path where your platform tools are located - similar to the below on Windows:
C:\Users\John\AppData\Local\Android\sdk\platform-tools>adb -d forward tcp:5601 tcp:5601
4. Start the Android Wear app on your handheld device and connect to the emulator.
5. Run the Basic Notifications App as outlined in the above lesson, which should send a notification to the emulator
3. Quick Notification Walkthrough
Now that we've seen notifications in action, let's step through the sample to quickly refresh your memory as to how they work.
We'll need to understand how this works before we can start adding wearable extensions.
So let's open up Application > Java > the Package, and then open up MainActivity.java
.
So lets now work through the code.
NOTIFICATION_ID
here is the unique identifier for the notification.
Each notification we generate has a unique value and if we issue two notifications with the same ID, we override the first one.
The interesting code is in sendNotification()
, which is here.
This creates an intent that is fired when the notification is clicked by the user.
We need to create a new pendingIntent
here, so that the notification service can run the intent later on for our app.
We need to setup a builder for NotificationCompat
objects.
We'll call methods on this to set it up.
This sets up the icon to show for the notification.
This tells the notification what pendingIntent
to use, which we created earlier.
And this here makes the notification automatically disappear when it's clicked on.
This here is a different kind of icon used on the left side of the notification in the notification shade.
These three lines configure the main title, the main text, and also some subtext, all of which are shown in the notification on the phone.
This grabs a reference to the NotificationManager
.
And this takes the builder (NotificationCompat.Builder
) and generates a notification compound object using the .build method.
And passes it to the notificationManager using the NOTIFICATION_ID
value.
The NOTIFICATION_ID
value must be unique amongst the other notifications you might want to create.
4. Preparing for Wearable Extensions
Before we can add wearable features to the sample, or any other code you might have already, we need to get things ready to make sure it works properly.
Firstly, make sure you're compiling against the V4 Support Library
.
[Note the V4 Support Library Split
as of Revision 24.2.0]
Let's open up our build.gradle file, which is contained here.
And if we scroll down, it's important that you use this library because many notification features such as action buttons, large icons, and Android Wear and auto support have been added to the framework since then. And most developers need to support older devices.
The next thing we need to do is make sure our notifications are issued correctly. We open up the main activity, and go down to the bottom here.
It's important that we replace the use of NotificationManager
with NotificationManagerCompat
.
If you try to use notification manager while supporting older API devices, they'll lose any special wearable extensions.
So this is the code change to implement this.
NotificationManagerCompat notificationManager =
NotificationManagerCompat.from(getApplicationContext());
notificationManager.notify(NOTIFICATION_ID, builder.build());
We hit Alt + Enter to add dependencies and then we're done.
5. Notification Actions
Now that we know how to run a simple sample, and how it looks, let's talk about what notification features are possible on Android Wear.
The first thing we can do is add extra action buttons to a notification. The user can view these actions by swiping the notification to the left. These actions are also visible on the phone notification as well, so this is not wearable specific.
So you make a call to the addAction()
method of the NotificationCompat.Builder
.
You need to supply an icon to use, and you also need to provide a string to show underneath, and finally you'll need to provide a pending intent for the specific action.
You'll notice that this code snippet creates a pendingIntent
that refers to a location, so it would open up a mapping application to display this on the phone.
It is important to realize that notifications created on the phone always cause the intent to run on the phone as well, not the wearable.
It's also possible to have different actions appear on the wearable device compared to the actions on the phone.
To do this, we introduce a class called WearableExtender
for wearable specific features we want to use.
We use the extend()
method of NotificationCompat.Builder
, and pass in the new WearableExtender
object.
With WearableExtender
.
we call addAction()
here to add the wearable specific action, which is defined here.
Note that when you use addAction()
with the WearableExtender
, none of the regular addAction()
calls will show up on the wearable, and none of the wearable addAction()
calls will be shown on the phone.
They're decoupled from each other now.
6. Notification Styles
Another feature of Android notifications, called Big View Styles
, also work well on Android Wear.
On a handheld a user can touch one of these notifications and it will expand to show more information.
On a Android Wear device the content is automatically expanded to fill the display, since there is more vertical space available.
If you look at this code snippet here you can see the BigTextStyle
being created and configured here with an edit to the notification by calling set style here.
There is also another style called InboxStyle
that's helpful for showing emails as well.
7. Notification Backgrounds and Gotchas
You may have noticed code snippets using setLargeIcon()
for a notification.
Android Wear automatically uses these as the background image.
However, the android framework only uses a 64x64 pixel version of the image, since it is normally shown quite small in the notification shade on a handheld.
The wearable extender provides a method called setBackground()
.
This method can handle high resolution images, such as mBitmap
here, and send them directly to the wearable so they'll appear nice and sharp.
However, make sure that the image you provide is not too large.
If it is too big, you can overwhelm the memory in the small wearable device.
Instead, we recommend that you provide...
400 x 400 if you want a static background.
And 640 x 400 if you want to have image parallax added, where the left and right edges are used to simulate background movement.
Make sure that you store these resources in the drawable-nodpi
directory to insure the framework does not try to resize them.
8. Voice Replies
Android Wear uses voice throughout the platform, and one of the best places to see it in action is doing replies to notifications.
Normally when you touch the reply action on a phone, it'll take you to an activity to enter the text. On Android Wear, the user can touch this reply button and then speak a reply and it is then converted into a string and delivered to your app. Best of all, you can use this feature with just a few lines of code, added to your existing notifications on the phone.
We use a class called RemoteInput
to implement this.
We declare a string: "extra_voice_reply"
that specifies the key that will be delivered to the intent later on.
We also declare a label to put on the text reply screen telling the user what we want them to speak to us.
You then call build()
to get the remote input object.
Now we need to add the RemoteInput
to our notification.
You can see here we declare a pendingIntent
to receive the reply.
We then create an action
and then we use addRemoteInput()
to use the RemoteInput
object we created earlier.
Then we use extend()
on the notification to add a WearableExtender
, addAction()
, and the action
we just created.
Everything is now linked together, and we can issue the notification.
This code will continue to work on a phone, but now we can have a reply action that asks the user to speak a reply.
So how do we get the reply string back?
The previous code is written to use an activity called ReplyActivity
.
Inside there, you can call getIntent()
to find details about the intent that started the activity.
Once you have the intent, you can pass it to the getMessageText()
method shown here.
We can then extract out the voice reply using the key EXTRA_VOICE_REPLY
, which returns a CharSequence
that was spoken by the user.
And that's it. It's that easy. Speech recognition has traditionally been very hard to do by yourself, and Android Wear takes care of all of it for you. There is also support for emoji entry in Android Wear, and these are automatically handled on the wearable, and sent to your app as standard emoji unicode characters. You don't always have to use voice replies.
Sometimes your user will be unable to speak to the watch and they might want to reply with a set of pre canned replies.
You can use the setChoices()
method to specify an array of options that the user can select from to be used along with a voice reply.
And here's how you define the array in the strings.xml
file.
It contains a set a strings that will be given to the extra voice replied to find earlier.
One more thing to note here, if your using the Android wear emulator, you'll have to type your voice replies on a keyboard, since the emulator does not support speech recognition.
9. Pages
There are times when you would like to provide more information on a notification on a wearable device.
In this example, we have a calendar notification but it would be handy to show some extra reminder notes if the user swipes to the left. Android wear supports a concept called pages which allow you to add extra pages of information to a notification like shown here. To do this, you just create two notification objects.
Here's the first page and this is the start of the second page.
And then here's the second part of the second page where we add the style to it.
And now we create a WearableExtender
.
We use addPage()
to add the second notification to it and then we call extend()
to add this all to the first notification.
You then issue the first notification page [ with NotificationManagerCompat.notify()
], and there's no need to issue the second one.
The notification will then show up with the second page attached.
And note, that any extra pages added will never appear on the phone.
10. Stacks
When you're creating apps like Email Clients, there will be times when there are many emails that have arrived.
On a handheld, you will be shown a notification that looks like this using inbox style. When you touch the notification, it will open up on the Email Client and show you all the emails. On a wearable, you would like to see more information about the emails without having to pull out the handheld device. It's possible to create a series of notifications, one for each email and then stack will group them together. The notifications are initially shown as a single card. That can be expanded into multiple cards by touching it.
So here we create a separate notification for each email our app knows about.
You can see that we add the sender here and the subject here for each email.
Now, we use the setGroup()
method to specify a unique key for this group.
So Android Wear knows which notifications should be stacked together.
We then issue this like any other notification [ with NotificationManagerCompat.notify()
].
And here is another notification for a second email.
You'll notice the use of setGroup()
here, just like the previous one.
And we issue this notification in the same way as well.
The final step is to create the notification for the phone like it's shown here. Clearly we don't want the individual emails to each get a notification on the handheld device.
This code sample creates the inbox style shown in the previous image.
It adds a summary of all the emails in a nice format that's perfect for showing on a handheld device.
The interesting part is the code is setGroup()
here, and setGroupSummary()
here. This makes the notification part of the previous group, but we've specified that this is the summary of the group by passing true here.
Summary is shown on the phone while the other group items are shown on the Android Wear device.
11. Adding Wearable Features to Notifications Quiz
Now that you've seen how notifications can work on Android Wear, it's now time for you to try it out. So, go to this URL here:
https://developer.android.com/training/wearables/notifications/index.html, and go and implement one of the Stacks or Pages examples so that you can see how they work.
12. Local Notifications
There may be cases where you want a notification to only appear on a phone, and you don't want it to be synchronized over to your wearable devices. An example might be a notification showing that there is an upload in progress on the phone. But it's not a notification that a user needs to be notified on their wearable.
The NotificationCompat.Builder
class contains a method called setLocalOnly()
.
You can use this to ensure notifications only appear on the phone.
If you want to make a notification that only appears on a wearable and not the phone, you'll need to wait until the next lesson to learn more about how to do this.
13. Samples
Before we finish the lesson, you should know that there are many Android samples that show off how to use the notification features we've just discussed. Let's go to File > Import Sample, and bring up the selector.
The first is Basic Notifications. This is the sample we first stepped through. This performs generic notifications for Android only, and is a good starting point for testing out the addition of wearable extensions.
The next is Wearable Notifications. This sample allows you to generate every possible notification type for Android Wear and see what they look like. This allows you to prototype everything before you write the code.
Finally, there is Eliza Chat, which allows you to have a conversation using speech recognition with an artificially intelligent robot, using your Android Wear device via notifications. So give this sample a try to find out what is possible with Android Wear notifications.
14. Notification Conclusion
So this is everything you need to know about extending regular notifications for a great experience on Android Wear. Your application remains basically the same as before, but we used Werable extensions to add more detail that is useful on Android Wear. The Android Wear software takes care of all the hard parts such as, showing the user interface and handling speech recognition. Another thing to know, is that these kinds of extensions are quite common in Android. Similar concepts are used to handle messaging with Android Auto. So, you'll be able to use similar techniques to extend your software to many different platforms.