Slide 1

Slide 1 text

Android Wear 2.0 Next Level of Freedom for Your Action Royce Mars Organizer @ GDG Dnipro Senior Developer @ DataArt

Slide 2

Slide 2 text

A long time ago…

Slide 3

Slide 3 text

A long time ago… in the Lviv, not so far away :)

Slide 4

Slide 4 text

A long time ago… in the Lviv, not so far away :) We’ve been talking about...

Slide 5

Slide 5 text

#gdgceesummit Freedom of tethering BLE WiFi Cellular

Slide 6

Slide 6 text

#gdgceesummit And chances to get direct access to Play Store

Slide 7

Slide 7 text

And today...

Slide 8

Slide 8 text

No content

Slide 9

Slide 9 text

Developer Preview 3 Play Store and More Available since September 28

Slide 10

Slide 10 text

#gdgceesummit Play Store features ● multiple accounts, ● support of alpha and beta testing ● update or uninstall apps in “My apps” view ● install only the watch app ● phone apps are no longer necessary

Slide 11

Slide 11 text

You can now build and publish watch-only apps for users to discover on Google Play

Slide 12

Slide 12 text

#gdgceesummit android { publishNonDefault true // Allows you to reference product flavors in your phone's build.gradle defaultConfig { minSdkVersion 23 } // This is the minSdkVersion of the Wear 1.0 embedded app productFlavors { wear1 { /* Use the defaultConfig value */ } wear2 { minSdkVersion 24 } } } Flavors for supporting both 2.0 and 1.x

Slide 13

Slide 13 text

#gdgceesummit dependencies { ... wearApp project(path: ':wear', configuration: 'wear1Release') } Package only when build variant requires it

Slide 14

Slide 14 text

#gdgceesummit If no need in 1.x - simply publish MultiAPK

Slide 15

Slide 15 text

Hardware Key platform features and supported watches

Slide 16

Slide 16 text

#gdgceesummit Officially supported watches LG Watch Urbane 2nd Edition Huawei Watch

Slide 17

Slide 17 text

#gdgceesummit Officially supported watches LG Watch Urbane 2nd Edition Huawei Watch Display: 1.4 inches, 400 x 400 pixels (~286 ppi) CPU:Quad-core 1.2 GHz Cortex-A7 GPU: Adreno 305, Chipset: Qualcomm Snapdragon 400 Memory: 4 GB, 512 MB RAM Comm: Wi-Fi 802.11 b/g, Bluetooth v4.1 LE Network: No cellular connectivity Battery: 300 mAh (48h) Display: 1.38 inches, 480 x 480 pixels (~348 ppi) CPU: Quad-core 1.2 GHz Cortex-A7 GPU: Adreno 305, Chipset: Qualcomm Snapdragon 400 Memory: 4 GB, 768 MB RAM Comm: Wi-Fi 802.11 b/g, Bluetooth v4.1 LE, GPS, NFC Network: GSM, HSPA, LTE Battery: 570 mAh (60h)

Slide 18

Slide 18 text

Complications Personal expression and utility

Slide 19

Slide 19 text

#gdgceesummit Personal expression and utility Modern by LG Ranger by Zuhanden GoogleFit Today

Slide 20

Slide 20 text

#gdgceesummit Or simply an personal expression :) HeyKittyKitty by WatchMaster

Slide 21

Slide 21 text

#gdgceesummit Complications “any feature in a timepiece beyond the simple display of hours and minutes” (Wikipedia)

Slide 22

Slide 22 text

#gdgceesummit Complication types -Short text -Long text -Range of values -Icon (small picture) -Image (big picture)

Slide 23

Slide 23 text

Complications coding

Slide 24

Slide 24 text

#gdgceesummit New in Preview 3 com.google.android.wearable.permission.RECEIVE_COMPLICATION_DATA Request permission to access Complication Data

Slide 25

Slide 25 text

#gdgceesummit Runtime permissions. Wearable version:) Now required for accessing Complication Providers from WatchFace apps

Slide 26

Slide 26 text

#gdgceesummit Each position need to be identified private static final int LEFT_DIAL_COMPLICATION = 0; private static final int RIGHT_DIAL_COMPLICATION = 1; public static final int[] COMPLICATION_IDS = {LEFT_DIAL_COMPLICATION, RIGHT_DIAL_COMPLICATION}; Complication ID

Slide 27

Slide 27 text

#gdgceesummit Each position must be mapped with array of supported types // Left and right dial supported types. public static final int[][] COMPLICATION_SUPPORTED_TYPES = { {ComplicationData.TYPE_SHORT_TEXT}, {ComplicationData.TYPE_SHORT_TEXT} }; Complication supported types

Slide 28

Slide 28 text

#gdgceesummit Data Providers and system trigger .onComplicationDataUpdate() sometimes /* Called when there is updated data for a complication id. */ @Override public void onComplicationDataUpdate( int complicationId, ComplicationData complicationData) { Log.d(TAG, "onComplicationDataUpdate() id: " + complicationId); mActiveComplicationDataSparseArray.put(complicationId, complicationData); invalidate(); } ComplicationData receiving

Slide 29

Slide 29 text

#gdgceesummit .onDraw() is the moment of drawing. ComplicationData where stored earlier @Override public void onDraw(Canvas canvas, Rect bounds) { ComplicationData complicationData; for (int i = 0; i < COMPLICATION_IDS.length; i++) { complicationData = mActiveComplicationDataSparseArray .get(COMPLICATION_IDS[i]); // ... Complications rendering

Slide 30

Slide 30 text

#gdgceesummit Complication may be deactivated or contain wrong data type if ((complicationData != null) && (complicationData.isActive(currentTimeMillis)) && (complicationData.getType() == ComplicationData.TYPE_SHORT_TEXT)) { ComplicationText mainText = complicationData.getShortText(); CharSequence complicationMessage = mainText.getText(getApplicationContext(), currentTimeMillis); Complications rendering

Slide 31

Slide 31 text

#gdgceesummit Actual drawing is trivial canvas.drawText( complicationMessage, 0, complicationMessage.length(), complicationsX, mComplicationsY, mComplicationPaint); Complications rendering

Slide 32

Slide 32 text

Data Providers

Slide 33

Slide 33 text

#gdgceesummit Android Wear role in data exchange

Slide 34

Slide 34 text

#gdgceesummit Data Providers

Slide 35

Slide 35 text

Data Providers coding

Slide 36

Slide 36 text

#gdgceesummit Data Provider Service attributes Extend ComplicationProviderService

Slide 37

Slide 37 text

#gdgceesummit Data Provider declaration

Slide 38

Slide 38 text

#gdgceesummit Update period Data Provider declaration

Slide 39

Slide 39 text

#gdgceesummit @Override public void onComplicationActivated( int complicationId, int dataType, ComplicationManager complicationManager) { … } @Override public void onComplicationUpdate( int complicationId, int dataType, ComplicationManager complicationManager) { … } @Override public void onComplicationDeactivated(int complicationId) { … } Data Provider methods

Slide 40

Slide 40 text

#gdgceesummit @Override public void onComplicationUpdate(int complicationId, int dataType, ComplicationManager complicationManager) { // Retrieve or generate your data int randomNumber = (int) Math.floor(Math.random() * 10); String randomNumberText = String.format(Locale.getDefault(), "%d!", randomNumber); Exposing data to complications Called according to update period time

Slide 41

Slide 41 text

#gdgceesummit ComplicationData complicationData = null; switch (dataType) { case ComplicationData.TYPE_SHORT_TEXT: complicationData = new ComplicationData.Builder( ComplicationData.TYPE_SHORT_TEXT) .setShortText(ComplicationText.plainText(randomNumberText)) .build(); break; Exposing data to complications

Slide 42

Slide 42 text

#gdgceesummit @Override public void onComplicationUpdate( int complicationId, int dataType, ComplicationManager complicationManager) { … if (complicationData != null) { complicationManager.updateComplicationData( complicationId, complicationData); } Exposing data to complications

Slide 43

Slide 43 text

#gdgceesummit WatchFaceService.Engine.setDefaultComplicationProvider() Default Providers

Slide 44

Slide 44 text

Notifications updated

Slide 45

Slide 45 text

#gdgceesummit Notifications in Android Wear 1.X

Slide 46

Slide 46 text

#gdgceesummit Android Wear 2.0 Notifications Material Design for Wearables, Dark Theme

Slide 47

Slide 47 text

#gdgceesummit Notifications preview

Slide 48

Slide 48 text

#gdgceesummit Notifications messaging style

Slide 49

Slide 49 text

Notifications coding

Slide 50

Slide 50 text

#gdgceesummit Notification noti = new NotificationCompat.Builder() .setContentTitle(messages.length + " new messages with " + sender) .setContentText("subject") .setSmallIcon(R.drawable.new_message) // 2) set the style to MessagingStyle .setStyle(new NotificationCompat.MessagingStyle( getResources().getString(R.string.reply_name)) .addMessage(messages[0]) .addMessage(messages[1]); Notifications with modern MessagingStyle set MessagingStyle

Slide 51

Slide 51 text

#gdgceesummit NotificationCompat.Action action = new NotificationCompat.Action.Builder(R.drawable.ic_reply_icon, getString(R.string.label), replyPendingIntent) .addRemoteInput(remoteInput) .setAllowGeneratedReplies(true) .build(); Notifications with SmartReply Allow SmartReply Starting with Preview 3 SmartReply uses standalone machine, located on watch

Slide 52

Slide 52 text

#gdgceesummit NotificationCompat.Action action = new NotificationCompat.Action.Builder(R.drawable.ic_reply_icon, getString(R.string.label), replyPendingIntent) .addRemoteInput(remoteInput) .extend(new NotificationCompat.Action.WearableExtender() .setHintDisplayActionInline(true)) .build(); Inline Action, available directly from stream Set inline action

Slide 53

Slide 53 text

(Not new) Input Methods

Slide 54

Slide 54 text

#gdgceesummit New input methods

Slide 55

Slide 55 text

#gdgceesummit Voice input, Emoji

Slide 56

Slide 56 text

#gdgceesummit Keyboard, Handwriting

Slide 57

Slide 57 text

#gdgceesummit Wait, a Keyboard??? LG Watch Urbane 2nd Edition Display: 1.38 inches, 480 x 480 pixels (~348 ppi) CPU: Quad-core 1.2 GHz Cortex-A7 GPU: Adreno 305, Chipset: Qualcomm Snapdragon 400 Memory: 4 GB, 768 MB RAM Comm: Wi-Fi 802.11 b/g, Bluetooth v4.1, LE, GPS, NFC Network: GSM, HSPA, LTE Battery: 570 mAh (60h) Size x2 bigger than first phones

Slide 58

Slide 58 text

Material Design for Wearables

Slide 59

Slide 59 text

#gdgceesummit 1D Layout Do Don’t

Slide 60

Slide 60 text

#gdgceesummit UI Anatomy

Slide 61

Slide 61 text

#gdgceesummit Navigation Drawer

Slide 62

Slide 62 text

#gdgceesummit Action Drawer

Slide 63

Slide 63 text

#gdgceesummit Dark Theme

Slide 64

Slide 64 text

#gdgceesummit Brightness values 1 App color - Default color 2 Dark background - 15% 3 Lighter background - 30% 4 UI element - 40% 5 Lighter UI element - 65% 6 Accent - 100%

Slide 65

Slide 65 text

#gdgceesummit Applications list

Slide 66

Slide 66 text

#gdgceesummit WearableRecyclerView Since Preview 3 - .setCircularScrollingGestureEnabled(true) available

Slide 67

Slide 67 text

Some new Google Fit features for Android Wear

Slide 68

Slide 68 text

#gdgceesummit Upcoming APIs Beat to Beat API Goals API Profile API

Slide 69

Slide 69 text

#gdgceesummit Real Time Gym Activity Recognition

Slide 70

Slide 70 text

#gdgceesummit Recognized exercises

Slide 71

Slide 71 text

Q&A? Thank you! Royce Mars @RoyceMars