Share
Embed
GDG Central & Eastern Europe Leads Summit - Warsaw, Poland 2016 - Android Wear 2.0
Royce Mars
October 10, 2016
Transcript
71 slides
-
Android Wear 2.0 Next Level of Freedom for Your Action
Royce Mars Organizer @ GDG Dnipro Senior Developer @ DataArt -
A long time ago… in the Lviv, not so far
away :) We’ve been talking about... -
#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 -
You can now build and publish watch-only apps for users
to discover on Google Play -
#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 -
#gdgceesummit dependencies { ... wearApp project(path: ':wear', configuration: 'wear1Release') }
Package only when build variant requires it -
#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) -
#gdgceesummit Personal expression and utility Modern by LG Ranger by
Zuhanden GoogleFit Today -
#gdgceesummit Complications “any feature in a timepiece beyond the simple
display of hours and minutes” (Wikipedia) -
#gdgceesummit Complication types -Short text -Long text -Range of values
-Icon (small picture) -Image (big picture) -
#gdgceesummit Runtime permissions. Wearable version:) Now required for accessing Complication
Providers from WatchFace apps -
#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 -
#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 -
#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 -
#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 -
#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 -
#gdgceesummit Actual drawing is trivial canvas.drawText( complicationMessage, 0, complicationMessage.length(), complicationsX,
mComplicationsY, mComplicationPaint); Complications rendering -
#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 -
#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 -
#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 -
#gdgceesummit @Override public void onComplicationUpdate( int complicationId, int dataType, ComplicationManager
complicationManager) { … if (complicationData != null) { complicationManager.updateComplicationData( complicationId, complicationData); } Exposing data to complications -
#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 -
#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 -
#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 -
#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 -
#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%