Monday, May 19, 2014

Notifications Part 3: Android Wear Developer Preview

To wrap up the current set of posts about Android notifications, I will go over the Developers Preview for Wear. Wear is a standard Android based OS for wearable devices, namely wristwatches in this early stage, that will hopefully be expanded to other devices in the near future. More information on what Wear is can be found on Google's site.

That's cool and all, but what are the capabilities of Wear? So far the developer preview only allows for notifications to be sent to the watch emulator, and for some predefined interactions. Google has shown some currently unavailable features such as speech to text, and Wear is able to send messages back to an Android device through the use of lock screen remote view buttons (a subject deserving of its own post that I hope to get to) and intents. Given that a wristwatch device can trigger events on a phone, the possibilities become endless when matches up with cloud services or additional external hardware, such as Android Open Accessories.

Remote View Notification Button for controlling an audio service (awesome, right?)
The first thing that needs to be done in order to start using the Wear preview is to sign up here. Once that's all set, you'll receive an email within a day or two letting you know if you're in the beta, and where to download the Android Wear Preview app. Once the app is installed, go into the Android SDK manager and make sure you're using the latest Support Library, then create an Android Wear emulator using API 19+. You'll also need to download the wearable support library jar from Google (though it's also in the libs folder in the source code for this post). When that's done, connect your Android device to your computer through USB and in a terminal (CMD prompt for you Windows folks) type the following from your SDK platform-tools folder:

adb -d forward tcp:5601 tcp:5601

Assuming you opened the preview app and turned on allowing Wear to receive notifications, then we're ready to move on to the fun part of this post! As with my other posts, all of the source that I'll be talking about is available on GitHub.

All Wear notifications are essentially normal notification builder wrapped by WearableNotifications.Builder, which can then have additional features added to them. It should be noted that the original notification builder must use the Android support library version: NotificationCompat.Builder. Here is the code for wrapping the standard Builder with the WearNotifications Builder:

        NotificationCompat.Builder notificationBuilder = new NotificationCompat.Builder( getActivity() )
                .setSmallIcon( R.drawable.ic_launcher )
                .setLargeIcon( BitmapFactory.decodeResource( getResources(), R.drawable.batman_punching_shark ) )
                .setContentText( getString( R.string.big_content_summary ) )
                .setContentTitle( getString( R.string.notification_basic ) );

        Notification notification =
                new WearableNotifications.Builder( notificationBuilder )
                        .setHintHideIcon(true)
                        .build();


        mNotificationManager.notify( notificationId, notification );

Basic Android Wear Notification
Now that we're able to show notifications on Wear, let's move on to something a bit more useful: sending intents from Wear actions. This uses the same method as a standard Android notification for sending an intent: addAction. By calling addAction with a PendingIntent on the NotificationCompat.Builder, an additional screen is added to the Wear notification that sends the intent when clicked. In this example, the intent is a standard ACTION_VIEW that opens a browser to my blog.

        Intent intent = new Intent( Intent.ACTION_VIEW );
        intent.setData( Uri.parse( "http://ptrprograms.blogspot.com" ) );
        PendingIntent pendingIntent = PendingIntent.getActivity( getActivity(), 0, intent, 0 );

        NotificationCompat.Builder notificationBuilder = new NotificationCompat.Builder( getActivity() )
                .setSmallIcon( R.drawable.ic_launcher )
                .setLargeIcon( BitmapFactory.decodeResource( getResources(), R.drawable.batman_punching_shark ) )
                .setContentText( getString( R.string.big_content_summary ) )
                .setContentTitle( getString( R.string.notification_add_action ) )
                .addAction( R.drawable.ic_launcher, "Launch Blog", pendingIntent );

        Notification notification =
                new WearableNotifications.Builder( notificationBuilder )
                        .setHintHideIcon( true )
                        .build();

        mNotificationManager.notify( notificationId, notification );

Notification Action Item
The next kind of notification is called Quick Reply. By creating a RemoteInput object with a Strings array, and then calling addRemoteInputForContentIntent when building the WearableNotification, you can provide a list of up to five items to allow the user to easily respond to a notification.

        Intent intent = new Intent( getActivity(), MainActivity.class );
        PendingIntent pendingIntent = PendingIntent.getActivity( getActivity(), 0, intent, 0 );

        NotificationCompat.Builder notificationBuilder = new NotificationCompat.Builder( getActivity() )
                .setSmallIcon( R.drawable.ic_launcher )
                .setLargeIcon( BitmapFactory.decodeResource( getResources(), R.drawable.batman_punching_shark ) )
                .setContentText( getString( R.string.big_content_summary ) )
                .setContentTitle( getString( R.string.notification_quick_replies ) )
                .setContentIntent( pendingIntent );

        String replyLabel = "Transportation";
        String[] replyChoices = getResources().getStringArray( R.array.getting_around );

        RemoteInput remoteInput = new RemoteInput.Builder( "extra_replies" )
                .setLabel(replyLabel)
                .setChoices(replyChoices)
                .build();

        Notification notification =
                new WearableNotifications.Builder( notificationBuilder )
                        .setHintHideIcon( true )
                        .addRemoteInputForContentIntent( remoteInput )
                        .build();

        mNotificationManager.notify( notificationId, notification );
Action for Quick Replies
Quick Replies
The next kind of Wear notification uses multiple pages to present information to the user. The first page notification is built like the other notifications by constructing the Notification builder, and then additional notification pages can be constructed and built with optional styles.

        NotificationCompat.BigTextStyle additionalPageStyle = new NotificationCompat.BigTextStyle();
        additionalPageStyle.setBigContentTitle( "Page 2" );

        Notification secondPageNotification =
                new NotificationCompat.Builder( getActivity() )
                        .setStyle( additionalPageStyle )
                        .build();

The additional notifications are then added to a List of Notification objects, and added to the WearableNotification during construction with the .addPages( list ) method.

Page 2 of 4

The final type of notification for Android Wear are stackable notifications. These notifications are created by building WearNotifications, like the other examples, but with the additional .setGroup method with a standardized tag as the first parameter and a stack id value for the second parameter that must be different for each notification. At least one of the notifications should be a summary notification with an id of WearableNotifications.GROUP_ORDER_SUMMARY. Once all of these notifications are built, they can be posted using the NotificationManager.

Notification notification2 =
                new WearableNotifications.Builder( notificationBuilder )
                        .setHintHideIcon(true)
                        .setGroup( EXTRA_STACKED_GROUP, ++stackedId )
                        .build();

        Notification summaryNotification = new WearableNotifications.Builder( notificationBuilder )
                .setGroup( EXTRA_STACKED_GROUP, WearableNotifications.GROUP_ORDER_SUMMARY )
                .build();


Assuming Android Wear stays similar on release, it should be pretty straight forward and easy to integrate into any app, and the additional features of voice replies will make it even more useful.