Slide 1

Slide 1 text

Android Wear 101 A glimpse into the future

Slide 2

Slide 2 text

TWITTER @cyrilmottier ! WEBSITE cyrilmottier.com

Slide 3

Slide 3 text

No content

Slide 4

Slide 4 text

No content

Slide 5

Slide 5 text

No content

Slide 6

Slide 6 text

No content

Slide 7

Slide 7 text

Introducing Android Wear paradigms

Slide 8

Slide 8 text

Real life Get phone Use phone

Slide 9

Slide 9 text

No content

Slide 10

Slide 10 text

Micro interactions Reducing interactions to their minimum

Slide 11

Slide 11 text

Slide 12

Slide 12 text

wearable paradigms handheld paradigms ≠

Slide 13

Slide 13 text

Think different …or at least differently ?

Slide 14

Slide 14 text

Android Wear UX main principles

Slide 15

Slide 15 text

3 main principles Contextual

Slide 16

Slide 16 text

3 main principles Contextual | Glanceable

Slide 17

Slide 17 text

3 main principles Contextual | Glanceable Low interaction |

Slide 18

Slide 18 text

Contextual The right info at the right time

Slide 19

Slide 19 text

Context helpers Sensors Activity Time Location Devices Identity Calendar

Slide 20

Slide 20 text

Glanceable The essential info in a blink of an eye

Slide 21

Slide 21 text

No content

Slide 22

Slide 22 text

1 6 1 2 3 4 5 2 3

Slide 23

Slide 23 text

No content

Slide 24

Slide 24 text

Low interaction Design for big gestures

Slide 25

Slide 25 text

Low interaction Design for big gestures

Slide 26

Slide 26 text

No content

Slide 27

Slide 27 text

Favour non error-prone input fullscreen tap/swipe voice actions

Slide 28

Slide 28 text

Simplified Activity lifecycle Device goes to sleep → Activity destroyed

Slide 29

Slide 29 text

Think your app as a row of cards in a grid

Slide 30

Slide 30 text

No content

Slide 31

Slide 31 text

Understanding the Android Wear ecosystem

Slide 32

Slide 32 text

1 device - 1 OS

Slide 33

Slide 33 text

1 device - 1 OS No shared code No shared resources

Slide 34

Slide 34 text

Different code base Different applications 1 device - 1 OS

Slide 35

Slide 35 text

?

Slide 36

Slide 36 text

Google Play Services

Slide 37

Slide 37 text

No Play Store on Android Wear

Slide 38

Slide 38 text

Imbricated APKs for distribution An APK in an APK…

Slide 39

Slide 39 text

Play Store Wearable

Slide 40

Slide 40 text

Play Store Wearable

Slide 41

Slide 41 text

Play Store Wearable

Slide 42

Slide 42 text

Developing for Android Wear devices

Slide 43

Slide 43 text

2 possibilities Notifications Custom app |

Slide 44

Slide 44 text

If your app already uses notifications, you have nothing to do

Slide 45

Slide 45 text

If your app already uses notifications, you have nothing to do almost

Slide 46

Slide 46 text

final Intent detailsIntent = DetailsActivity.
 newIntent(this, travelId);
 final PendingIntent detailPendingIntent = PendingIntent.
 getActivity(this, 0, detailsIntent, 0);
 
 final NotificationCompat.Builder builder = new NotificationCompat.Builder(this).
 setSmallIcon(R.drawable.ic_status_capitaine).
 setContentTitle(travelTitle).
 setContentIntent(detailPendingIntent);
 
 final Notification notif = new NotificationCompat.BigTextStyle(builder).
 bigText(travelDescription).
 build();
 
 NotificationManagerCompat.from(this).notify(NOTIFICATION_ID, notif);

Slide 47

Slide 47 text

No content

Slide 48

Slide 48 text

Wearable specific notifications WearableExtender to the rescue

Slide 49

Slide 49 text

final Bitmap background = 
 BitmapFactory.decodeResource(
 getResources(), R.drawable.paris);
 
 builder.extend(new NotificationCompat.
 WearableExtender().setBackground(background));

Slide 50

Slide 50 text

Stacks setGroup() setSortKey() setGroupSummary()

Slide 51

Slide 51 text

Pages addPage(Notification)

Slide 52

Slide 52 text

Pages addPage(Notification)

Slide 53

Slide 53 text

Voice input RemoteInput

Slide 54

Slide 54 text

There are some case where notifications are not enough

Slide 55

Slide 55 text

From To

Slide 56

Slide 56 text

Wearable apps are fundamentally the same as apps built for other devices

Slide 57

Slide 57 text

android.webkit android.print android.app.backup android.appwidget android.hardware.usb Unsupported APIs

Slide 58

Slide 58 text

NodeApi Learn about local & connected nodes MessageApi Send messages on a “fire & forget” basis DataApi Sync data between nodes on the network

Slide 59

Slide 59 text

Handheld - ReminderService.java final Notification notification = new NotificationCompat.Builder(context).
 // ... setLocalOnly(true).
 // ...
 build();

Slide 60

Slide 60 text

if (mGoogleApiClient == null) {
 mGoogleApiClient = new GoogleApiClient.Builder(this).
 addApi(Wearable.API).
 addOnConnectionFailedListener(mOnConnectionFailedListener).
 addConnectionCallbacks(mConnectionCallbacks).
 build();
 }
 mGoogleApiClient.connect();
 
 private final GoogleApiClient.OnConnectionFailedListener mOnConnectionFailedListener
 = new GoogleApiClient.OnConnectionFailedListener() {
 @Override
 public void onConnectionFailed(ConnectionResult connectionResult) { /* ... */ }
 };
 
 private final GoogleApiClient.ConnectionCallbacks mConnectionCallbacks = 
 new GoogleApiClient.ConnectionCallbacks() {
 @Override
 public void onConnected(Bundle bundle) { /* TODO */ }
 
 @Override
 public void onConnectionSuspended(int i) { /* ... */ }
 }; Handheld - ReminderService.java

Slide 61

Slide 61 text

Handheld - ReminderService.java @Override
 public void onConnected(Bundle bundle) {
 
 final PutDataMapRequest request = PutDataMapRequest.
 create("/show-reminder/travel");
 final DataMap map = request.getDataMap();
 
 map.putString("departureStation", departureStation);
 map.putString("arrivalStation", arrivalStation);
 map.putString("barcodeData", barcodeData); // ...
 
 Wearable.DataApi.putDataItem(mGoogleApiClient, request.asPutDataRequest()).
 setResultCallback(new ResultCallback() {
 @Override
 public void onResult(DataApi.DataItemResult dataItemResult) {
 if (!dataItemResult.getStatus().isSuccess()) {
 // Deal with errors
 }
 }
 });
 }

Slide 62

Slide 62 text

Wearable - ReminderReceiverService.java public class ReminderReceiverService extends WearableListenerService {
 
 @Override
 public void onDataChanged(DataEventBuffer dataEvents) {
 super.onDataChanged(dataEvents);
 for (DataEvent dataEvent : dataEvents) {
 final Uri uri = dataEvent.getDataItem().getUri();
 final DataMap dataMap = DataMapItem. fromDataItem(dataEvent.getDataItem()).getDataMap();
 switch (dataEvent.getType()) {
 case DataEvent.TYPE_CHANGED:
 onDataEventChanged(uri, dataMap);
 break;
 
 case DataEvent.TYPE_DELETED:
 onDataEventDeleted(uri, dataMap);
 break;
 }
 }
 }
 
 protected void onDataEventChanged(Uri uri, DataMap dataMap) { /* TODO */ }
 protected void onDataEventDeleted(Uri uri, DataMap dataMap) { /* TODO */ }
 }

Slide 63

Slide 63 text

Wearable - ReminderReceiverService.java @Override
 protected void onDataEventChanged(Uri uri, DataMap dataMap) {
 final List segments = uri.getPathSegments();
 if (segments != null && segments.size() > 1 && "show-reminder".equals(segments.get(0))) {
 final String notificationId = segments.get(1);
 
 final String departureStation = dataMap.getString("departureStation");
 final String arrivalStation = dataMap.getString("arrivalStation");
 final String barcodeData = dataMap.getString("barcodeData");
 // ...
 
 final Notification notification = new NotificationCompat.Builder(this).
 setLocalOnly(true).
 // ...
 build();
 
 mNotificationManager.notify(notificationId, NOTIFICATION_ID, notification);
 }
 }

Slide 64

Slide 64 text

Wearable - ReminderReceiverService.java @Override
 protected void onDataEventDeleted(Uri uri, DataMap dataMap) {
 final List segments = uri.getPathSegments();
 if (segments != null && segments.size() > 1 && "show-reminder".equals(segments.get(0))) {
 final String notificationId = segments.get(1);
 mNotificationManager.cancel(notificationId, REMINDER_NOTIFICATION_ID);
 }
 }

Slide 65

Slide 65 text

android {
 // ...
 }
 
 dependencies { // ...
 wearApp project(':wearable')
 } Packaging wearable apps a simple Gradle dependency

Slide 66

Slide 66 text

Design from scratch Do not create a small version of your handheld app. Start a completely new design process

Slide 67

Slide 67 text

Think “cards” first Always think about the notification cards pattern first. The wear app pattern is a fallback

Slide 68

Slide 68 text

Keep simplicity in mind Your wearables apps should be as rudimentary as interactions with these devices are

Slide 69

Slide 69 text

Thank you! @cyrilmottier cyrilmottier.com

Slide 70

Slide 70 text

Fonts Source Sans Pro Menlo Resources Dressed for Iceland • Cécile Bernard Moelwynion, Eryri, Cymru • Marc Poppleton