diff --git a/docs/html/training/building-wearables.jd b/docs/html/training/building-wearables.jd new file mode 100644 index 0000000000000..4fda10e1f960f --- /dev/null +++ b/docs/html/training/building-wearables.jd @@ -0,0 +1,8 @@ +page.title=Building Apps for Wearables +page.trainingcourse=true + +@jd:body + + +
These classes teach you how to build notifications in a handheld app that are automatically +synced to wearables as well as how to build apps that run on wearables.
\ No newline at end of file diff --git a/docs/html/training/training_toc.cs b/docs/html/training/training_toc.cs index c5dc3c5f76153..4407d304d5a4f 100644 --- a/docs/html/training/training_toc.cs +++ b/docs/html/training/training_toc.cs @@ -638,7 +638,6 @@ include the action bar on devices running Android 2.1 or higher." - @@ -727,6 +726,90 @@ include the action bar on devices running Android 2.1 or higher." +You send messages using the
+MessageApi
+and attach the following items to the message:
+Unlike data items, there is no syncing between the handheld and wearable apps. +Messages are a one-way communication mechanism that's meant for +"fire-and-forget" tasks, such as sending a message to the wearable +to start an activity. You can also use messages in request/response model +where one side of the connection sends a message, does some work, +sends back a response message.
+ +The following example shows how to send a message that indicates to the other +side of the connect to start an activity. +This call is made synchronously, which blocks until the message +is received or when the request times out: +
+ +Note: Read more about asynchronous and synchronous calls +to Google Play services and when to use each in +Communicate with Google Play Services. +
+ +
+Node node; // the connected device to send the message to
+GoogleApiClient mGoogleApiClient;
+public static final START_ACTIVITY_PATH = "/start/MainActivity";
+...
+
+ SendMessageResult result = Wearable.MessageApi.sendMessage(
+ mGoogleApiClient, node, START_ACTIVITY_PATH, null).await();
+ if (!result.getStatus().isSuccess()) {
+ Log.e(TAG, "ERROR: failed to send Message: " + result.getStatus());
+ }
+
+
++Here's a simple way to get a list of connected nodes that you can potentially +send messages to:
+ +
+private Collection<String> getNodes() {
+ HashSet <String>results= new HashSet<String>();
+ NodeApi.GetConnectedNodesResult nodes =
+ Wearable.NodeApi.getConnectedNodes(mGoogleApiClient).await();
+ for (Node node : nodes.getNodes()) {
+ results.add(node.getId());
+ }
+ return results;
+}
+
+
+
+
+To be notified of received messages, you implement a listener for message events.
+This example shows how you might do this by checking the START_ACTIVITY_PATH
+that the previous example used to send the message. If this condition is true,
+a specific activity is started.
+
+@Override
+public void onMessageReceived(MessageEvent messageEvent) {
+ if (messageEvent.getPath().equals(START_ACTIVITY_PATH)) {
+ Intent startIntent = new Intent(this, MainActivity.class);
+ startIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
+ startActivity(startIntent);
+ }
+}
+
+
++This is just a snippet that requires more implementation details. Learn about +how to implement a full listener service or activity in +Listening for Data Layer Events. +
\ No newline at end of file diff --git a/docs/html/training/wearables/notifications/creating.jd b/docs/html/training/wearables/notifications/creating.jd new file mode 100644 index 0000000000000..174cd82cd977a --- /dev/null +++ b/docs/html/training/wearables/notifications/creating.jd @@ -0,0 +1,295 @@ +page.title=Creating a Notification + +@jd:body + +To build handheld notifications that are also sent to wearables, use +{@link android.support.v4.app.NotificationCompat.Builder}. When you build +notifications with this class, the system takes care of displaying +notifications properly, whether they appear on a handheld or wearable. +
+ +Note: +Notifications using {@link android.widget.RemoteViews} are stripped of custom +layouts and the wearable only displays the text and icons. However, you can create +create custom notifications +that use custom card layouts by creating a wearable app that runs on the wearable device.
+ + +Before you begin, import the necessary classes from the support library:
+ ++import android.support.v4.app.NotificationCompat; +import android.support.v4.app.NotificationManagerCompat; +import android.support.v4.app.NotificationCompat.WearableExtender; ++ +
The v4 +support library allows you to create notifications using the latest notification features +such as action buttons and large icons, while remaining compatible with Android 1.6 (API level +4) and higher.
+ +To create a notification with the support library, you create an instance of +{@link android.support.v4.app.NotificationCompat.Builder} and issue the notification by +passing it to {@link android.support.v4.app.NotificationManagerCompat#notify notify()}. For example: +
+ ++int notificationId = 001; +// Build intent for notification content +Intent viewIntent = new Intent(this, ViewEventActivity.class); +viewIntent.putExtra(EXTRA_EVENT_ID, eventId); +PendingIntent viewPendingIntent = + PendingIntent.getActivity(this, 0, viewIntent, 0); + +NotificationCompat.Builder notificationBuilder = + new NotificationCompat.Builder(this) + .setSmallIcon(R.drawable.ic_event) + .setContentTitle(eventTitle) + .setContentText(eventLocation) + .setContentIntent(viewPendingIntent); + +// Get an instance of the NotificationManager service +NotificationManagerCompat notificationManager = + NotificationManagerCompat.from(this); + +// Build the notification and issues it with notification manager. +notificationManager.notify(notificationId, notificationBuilder.build()); ++ +
When this notification appears on a handheld device, the user can invoke the +{@link android.app.PendingIntent} +specified by the {@link android.support.v4.app.NotificationCompat.Builder#setContentIntent +setContentIntent()} method by touching the notification. When this +notification appears on an Android wearable, the user can swipe the notification to the left to +reveal the Open action, which invokes the intent on the handheld device.
+ + +
+
+In addition to the primary content action defined by +{@link android.support.v4.app.NotificationCompat.Builder#setContentIntent +setContentIntent()}, you can add other actions by passing a {@link android.app.PendingIntent} to +the {@link android.support.v4.app.NotificationCompat.Builder#addAction addAction()} method.
+ +For example, the following code shows the same type of notification from above, but adds an +action to view the event location on a map.
+ +
+// Build an intent for an action to view a map
+Intent mapIntent = new Intent(Intent.ACTION_VIEW);
+Uri geoUri = Uri.parse("geo:0,0?q=" + Uri.encode(location));
+mapIntent.setData(geoUri);
+PendingIntent mapPendingIntent =
+ PendingIntent.getActivity(this, 0, mapIntent, 0);
+
+NotificationCompat.Builder notificationBuilder =
+ new NotificationCompat.Builder(this)
+ .setSmallIcon(R.drawable.ic_event)
+ .setContentTitle(eventTitle)
+ .setContentText(eventLocation)
+ .setContentIntent(viewPendingIntent)
+ .addAction(R.drawable.ic_map,
+ getString(R.string.map), mapPendingIntent);
+
+
+On a handheld, the action appears as an +additional button attached to the notification. On a wearable, the action appears as +a large button when the user swipes the notification to the left. When the user taps the action, +the associated intent is invoked on the handheld.
+ +Tip: If your notifications include a "Reply" action + (such as for a messaging app), you can enhance the behavior by enabling + voice input replies directly from the Android wearable. For more information, read + Receiving Remote Input from + a Notification. +
+ ++If you want the actions available on the wearable to be different from those on the handheld, +then use {@link android.support.v4.app.NotificationCompat.WearableExtender#addAction WearableExtender.addAction()}. +Once you add an action with this method, the wearable does not display any other actions added with +{@link android.support.v4.app.NotificationCompat.Builder#addAction NotificationCompat.Builder.addAction()}. +That is, only the actions added with {@link android.support.v4.app.NotificationCompat.WearableExtender#addAction WearableExtender.addAction()} appear on the wearable and they do not appear on the handheld. +
+ ++// Create an intent for the reply action +Intent actionIntent = new Intent(this, ActionActivity.class); +PendingIntent actionPendingIntent = + PendingIntent.getActivity(this, 0, actionIntent, + PendingIntent.FLAG_UPDATE_CURRENT); + +// Create the action +NotificationCompat.Action action = + new NotificationCompat.Action.Builder(R.drawable.ic_action, + getString(R.string.label, actionPendingIntent)) + .build(); + +// Build the notification and add the action via WearableExtender +Notification notification = + new NotificationCompat.Builder(mContext) + .setSmallIcon(R.drawable.ic_message) + .setContentTitle(getString(R.string.title)) + .setContentText(getString(R.string.content)) + .extend(new WearableExtender().addAction(action)) + .build(); ++
+
+You can insert extended text content +to your notification by adding one of the "big view" styles to your notification. On a +handheld device, users can see the big view content by expanding the notification. On +a wearable device, the big view content is visible by default.
+ +To add the extended content to your notification, call {@link +android.support.v4.app.NotificationCompat.Builder#setStyle setStyle()} on the {@link +android.support.v4.app.NotificationCompat.Builder} object, passing it an instance of either +{@link android.support.v4.app.NotificationCompat.BigTextStyle BigTextStyle} or +{@link android.support.v4.app.NotificationCompat.InboxStyle InboxStyle}.
+ +For example, the following code adds an instance of +{@link android.support.v4.app.NotificationCompat.BigTextStyle} to the event notification, +in order to include the complete event description (which includes more text than can fit +into the space provided for {@link android.support.v4.app.NotificationCompat.Builder#setContentText +setContentText()}).
+ ++// Specify the 'big view' content to display the long +// event description that may not fit the normal content text. +BigTextStyle bigStyle = new NotificationCompat.BigTextStyle(); +bigStyle.bigText(eventDescription); + +NotificationCompat.Builder notificationBuilder = + new NotificationCompat.Builder(this) + .setSmallIcon(R.drawable.ic_event) + .setLargeIcon(BitmapFractory.decodeResource( + getResources(), R.drawable.notif_background)) + .setContentTitle(eventTitle) + .setContentText(eventLocation) + .setContentIntent(viewPendingIntent) + .addAction(R.drawable.ic_map, + getString(R.string.map), mapPendingIntent) + .setStyle(bigStyle); ++ +
Notice that you can add a large background image to any notification using the +{@link android.support.v4.app.NotificationCompat.Builder#setLargeIcon setLargeIcon()} +method. For more information about designing notifications with large images, see the +Design Principles of Android +Wear.
+ +If you ever need to add wearable-specific options to a notification, such as specifying additional +pages of content or letting users dictate a text response with voice input, you can use the +{@link android.support.v4.app.NotificationCompat.WearableExtender} class to +specify the options. To use this API:
+ ++For example, the following code calls the +{@link android.support.v4.app.NotificationCompat.WearableExtender#setHintHideIcon setHintHideIcon()} +method to remove the app icon from the notification card. +
+ +
+// Create a WearableExtender to add functionality for wearables
+NotificationCompat.WearableExtender wearableExtender =
+ new NotificationCompat.WearableExtender()
+ .setHintHideIcon(true);
+
+// Create a NotificationCompat.Builder to build a standard notification
+// then extend it with the WearableExtender
+Notification notif = new NotificationCompat.Builder(mContext)
+ .setContentTitle("New mail from " + sender)
+ .setContentText(subject)
+ .setSmallIcon(R.drawable.new_mail);
+ .extend(wearableExtender)
+ .build();
+
+
+The + {@link android.support.v4.app.NotificationCompat.WearableExtender#setHintHideIcon setHintHideIcon()} + method is just one example of new notification features available with + {@link android.support.v4.app.NotificationCompat.WearableExtender}. +
+ +If you ever need to read wearable-specifc options at a later time, use the corresponding get +method for the option. This example calls the +{@link android.support.v4.app.NotificationCompat.WearableExtender#getHintHideIcon()} method to +get whether or not this notification hides the icon: +
+NotificationCompat.WearableExtender wearableExtender = + new NotificationCompat.WearableExtender(notif); +boolean hintHideIcon = wearableExtender.getHintHideIcon(); ++ +
When you want to deliver your notifications, always use the + {@link android.support.v4.app.NotificationManagerCompat} API instead of + {@link android.app.NotificationManager}:
+ ++// Get an instance of the NotificationManager service +NotificationManagerCompat notificationManager = + NotificationManagerCompat.from(mContext); + +// Issue the notification with notification manager. +notificationManager.notify(notificationId, notif); ++ +
If you use the framework's {@link android.app.NotificationManager}, some +features from {@link android.support.v4.app.NotificationCompat.WearableExtender} +do not work, so make sure to use {@link android.support.v4.app.NotificationCompat}. +
+ ++NotificationCompat.WearableExtender wearableExtender = + new NotificationCompat.WearableExtender(notif); +boolean hintHideIcon = wearableExtender.getHintHideIcon(); ++ +
The {@link android.support.v4.app.NotificationCompat.WearableExtender} APIs allow you to add +additional pages to notifications, stack notifications, and more. Continue to the following lessons +to learn about these features. +
\ No newline at end of file diff --git a/docs/html/training/wearables/notifications/index.jd b/docs/html/training/wearables/notifications/index.jd new file mode 100644 index 0000000000000..b9ed6fb9b9262 --- /dev/null +++ b/docs/html/training/wearables/notifications/index.jd @@ -0,0 +1,51 @@ +page.title=Adding Wearable Features to Notifications +@jd:body + +When an Android handheld (phone or tablet) and Android wearable are connected, the handheld +automatically shares notifications with the wearable. On the wearable, each +notification appears as a new card in the context stream.
+ +However, to give users the best experience, you should add wearable-specific functionality to the +notifications you already create. The following lessons show you how to +create notifications that are catered for handhelds and wearables at the same time. +
+ +
+
+Figure 1. The same notification displayed on a handheld and wearable.
+ +When you'd like to provide more information without requiring users +to open your app on their handheld device, you can +add one or more pages to the notification on the wearable. The additional pages +appear immediately to the right of the main notification card. +
+ +
+
+
+To create a notification with multiple pages:
+For example, here's some code that adds a second page to a notification:
+ +
+// Create builder for the main notification
+NotificationCompat.Builder notificationBuilder =
+ new NotificationCompat.Builder(this)
+ .setSmallIcon(R.drawable.new_message)
+ .setContentTitle("Page 1")
+ .setContentText("Short message")
+ .setContentIntent(viewPendingIntent);
+
+// Create a big text style for the second page
+BigTextStyle secondPageStyle = new NotificationCompat.BigTextStyle();
+secondPageStyle.setBigContentTitle("Page 2")
+ .bigText("A lot of text...");
+
+// Create second page notification
+Notification secondPageNotification =
+ new NotificationCompat.Builder(this)
+ .setStyle(secondPageStyle)
+ .build();
+
+// Add second page with wearable extender and extend the main notification
+Notification twoPageNotification =
+ new WearableExtender()
+ .addPage(secondPageNotification)
+ .extend(notificationBuilder)
+ .build();
+
+// Issue the notification
+ notificationManager =
+ NotificationManagerCompat.from(this);
+ notificationManager.notify(notificationId, twoPageNotification);
+
\ No newline at end of file
diff --git a/docs/html/wear/notifications/stacks.jd b/docs/html/training/wearables/notifications/stacks.jd
similarity index 54%
rename from docs/html/wear/notifications/stacks.jd
rename to docs/html/training/wearables/notifications/stacks.jd
index 3c3dc09c266bd..e71e74c098e34 100644
--- a/docs/html/wear/notifications/stacks.jd
+++ b/docs/html/training/wearables/notifications/stacks.jd
@@ -2,9 +2,21 @@ page.title=Stacking Notifications
@jd:body
-
-
+
+
When creating notifications for a handheld device, you should always aggregate similar
notifications into a single summary notification. For example, if your app creates notifications
for received messages, you should not show more than one notification
@@ -16,36 +28,25 @@ are not able to read details from each message on the wearable (they must open y
handheld to view more information). So for the wearable device, you should
group all the notifications together in a stack. The stack of notifications appears as a single
card, which users can expand to view the details from each notification separately. The new
-
-setGroup() method makes this possible while allowing you to still provide
-only one summary notification on the handheld device.
For details about designing notification stacks, see the -Design Principles of Android -Wear.
+To create a stack, call
-setGroup() for each notification you want in the stack and specify a
-group key. Then call notify() to send it to the wearable.
To create a stack, call {@link android.support.v4.app.NotificationCompat.Builder#setGroup setGroup()} +for each notification you want in the stack and specify a +group key. Then call {@link android.support.v4.app.NotificationManagerCompat#notify notify()} +to send it to the wearable.
final static String GROUP_KEY_EMAILS = "group_key_emails";
-// Build the notification
-NotificationCompat.Builder builder = new NotificationCompat.Builder(mContext)
+// Build the notification, setting the group appropriately
+Notification notif = new NotificationCompat.Builder(mContext)
.setContentTitle("New mail from " + sender1)
.setContentText(subject1)
.setSmallIcon(R.drawable.new_mail);
-
-// Set the group with WearableNotificationOptions.Builder and apply to the notification
-Notification notif1 = new WearableNotificationOptions.Builder()
.setGroup(GROUP_KEY_EMAILS)
- .build()
- .applyTo(builder)
.build();
// Issue the notification
@@ -56,31 +57,24 @@ notificationManager.notify(notificationId1, notif);
Later on, when you create another notification, specify
the same group key. When you call
-notify(),
+{@link android.support.v4.app.NotificationManagerCompat#notify notify()},
this notification appears in the same stack as the previous notification,
instead of as a new card:
-builder = new NotificationCompat.Builder(mContext)
+Notification notif2 = new NotificationCompat.Builder(mContext)
.setContentTitle("New mail from " + sender2)
.setContentText(subject2)
.setSmallIcon(R.drawable.new_mail);
-
-// Use the same group as the previous notification
-Notification notif2 = new WearableNotificationOptions.Builder()
.setGroup(GROUP_KEY_EMAILS)
- .build()
- .applyTo(builder)
.build();
-notificationManager.notify(notificationId2, notif);
+notificationManager.notify(notificationId2, notif2);
By default, notifications appear in the order in which you added them, with the most recent
- notification visible at the top. You can define a specific position in the group
- by passing an order position as the second parameter for
-setGroup().
+ notification visible at the top. You can order notifications in another fashion by calling
+ {@link android.support.v4.app.NotificationCompat.Builder#setSortKey setSortKey()}.
Add a Summary Notification
@@ -89,8 +83,8 @@ href="{@docRoot}reference/android/support/wearable/notifications/WearableNotific
It's important that you still provide a summary notification that appears on handheld devices.
So in addition to adding each unique notification to the same stack group, also add a summary
-notification, but set its order position to be GROUP_ORDER_SUMMARY.
+notification and call {@link android.support.v4.app.NotificationCompat.Builder#setGroupSummary setGroupSummary()}
+on the summary notification.
This notification does not appear in your stack of notifications on the wearable, but
appears as the only notification on the handheld device.
@@ -100,7 +94,7 @@ Bitmap largeIcon = BitmapFactory.decodeResource(getResources(),
R.drawable.ic_large_icon);
// Create an InboxStyle notification
-builder = new NotificationCompat.Builder(this)
+Notification summaryNotification = new NotificationCompat.Builder(mContext)
.setContentTitle("2 new messages")
.setSmallIcon(R.drawable.ic_small_icon)
.setLargeIcon(largeIcon)
@@ -108,13 +102,9 @@ builder = new NotificationCompat.Builder(this)
.addLine("Alex Faaborg Check this out")
.addLine("Jeff Chang Launch Party")
.setBigContentTitle("2 new messages")
- .setSummaryText("johndoe@gmail.com"));
-
-// Specify the notification to be the group summary
-Notification summaryNotification = new WearableNotificationOptions.Builder()
- .setGroupSummary(GROUP_KEY_EMAILS)
- .build()
- .applyTo(builder)
+ .setSummaryText("johndoe@gmail.com"))
+ .setGroup(GROUP_KEY_EMAILS)
+ .setGroupSummary(true)
.build();
notificationManager.notify(notificationId3, summaryNotification);
@@ -134,5 +124,31 @@ with HTML markup and
Styling
with Spannables.
-