SlideShare a Scribd company logo
1 of 68
Download to read offline
Android Wear
Mobile Software Engineer en
Redbooth Inc. (formerly Teambox).

!
Organizador del GDG Barcelona
(Google Developer Group).

!
Previously: UAB (Universidad
A u t o n o m a d e B a rc e l o n a ) y
Citigroup.
¿Quien soy?
Twitter: @Nescafemix

About.me: about.me/joan.fuentes.hernandez
Google+: plus.google.com/+JoanFuentesHernández
•Versión de Android para wearables (Lollipop actualmente)

!
•Pretende facilitarnos la vida reduciendo tiempo de interacción
con el móvil

!
!
!
!
!
!
!
•Debe mostrar información concisa y útil.

¿Qué es Android Wear?
VIDA REAL
INTERACCIÓN DISPOSITIVO
!
SECOND SCREEN + FAST ACTIONS
Nuevo paradigma
Visión creativa
•Ejecutado automáticamente
Visión creativa
•Ejecutado automáticamente

•1 mirada basta (Glanceable)
Visión creativa
•Ejecutado automáticamente

•1 mirada basta (Glanceable)

•Todo sobre sugerir (stream) y
demandar (cue card)
Visión creativa
•Ejecutado automáticamente

•1 mirada basta (Glanceable)

•Todo sobre sugerir (stream y
demandar (cue card)

•Cero o poca interacción
Principios de diseño
•No detengas al usuario. Déjalo seguir con su vida
Principios de diseño
•Diseña para grandes gestos
Principios de diseño
•Piensa en stream cards
Principios de diseño
•Haz 1 cosa, y hazla rápido
Principios de diseño
•Diseña para un vistazo
Principios de diseño
•No seas troll, no molestes constantemente al usuario
¿Qué NO debería ser Android Wear?
¿Qué NO debería ser Android Wear?
¿Qué NO debería ser Android Wear?
¿Qué NO debería ser Android Wear?
¿Que necesitan nuestras apps para wear?
NADA
¿Que necesitan nuestras apps para wear?
NADA
¿Que necesitan nuestras apps para wear?
NADA
¿Que necesitan nuestras apps para wear?
NADA
CASI
¿Que necesitan nuestras apps para wear?
Programando para Wear - tipos
!
•Notificaciones de sistema con funcionalidad de Wear
!
!
!
!
•Aplicaciones de Wear
!
Programando para Wear - tipos
!
•Watch faces
Notificaciones de sistema con funcionalidad de Wear
!
•Cualquier notificación básica por defecto aparecerá en Wear
int notificationId = 001;
!
NotificationCompat.Builder notificationBuilder = new NotificationCompat.Builder(this)
.setSmallIcon(R.drawable.ic_launcher)
.setContentTitle("Default title")
.setContentText("Default text.”)
.setTicker("New notification!");
!
NotificationManagerCompat notificationManager = NotificationManagerCompat.from(this);
notificationManager.notify(notificationId, notificationBuilder.build());
Notificaciones de sistema con funcionalidad de Wear
!
•Añadiendo una simple imagen de fondo
Extendiendo a Wear
int notificationId = 001;
!
NotificationCompat.Extender extender = new NotificationCompat.WearableExtender()
.setHintHideIcon(true)
.setBackground(BitmapFactory.decodeResource(getResources(), R.drawable.trollface));
!
NotificationCompat.Builder notificationBuilder = new NotificationCompat.Builder(this)
.setSmallIcon(R.drawable.ic_launcher)
.setContentTitle("Default title")
.setContentText("Default text.”)
.setTicker("New notification!")
.extend(extender);
!
NotificationManagerCompat notificationManager = NotificationManagerCompat.from(this);
notificationManager.notify(notificationId, notificationBuilder.build());
Notificaciones de sistema con funcionalidad de Wear
Extendiendo a Wear
•Pages
Notificaciones de sistema con funcionalidad de Wear
Extendiendo a Wear
// Create a second page notification
Notification secondPageNotification = new NotificationCompat.Builder(this)
.setContentTitle("Second Page title”)
.setContentText("Default second page text”)
.build();
•Pages
// Specific extender to show only background in this notification page
NotificationCompat.Extender extenderOnlyImage = new
NotificationCompat.WearableExtender()
.setHintShowBackgroundOnly(true);
!
// Create a third page notification with only background
Notification thirdPageNotification = new NotificationCompat.Builder(this)
.extend(extenderOnlyImage)
.build();
Notificaciones de sistema con funcionalidad de Wear
Extendiendo a Wear
•Pages
Notificaciones de sistema con funcionalidad de Wear
Extendiendo a Wear
NotificationCompat.Extender extender = new NotificationCompat.WearableExtender()
.setBackground(BitmapFactory.decodeResource(getResources(), R.drawable.trollface))
.addPage(secondPageNotification)
.addPage(thirdPageNotification);
NotificationCompat.Builder notificationBuilder = new NotificationCompat.Builder(this)
.setSmallIcon(R.drawable.ic_launcher)
.setContentTitle("Default title”)
.setContentText("Default text.”)
.setTicker("New notification!");
.extend(extender);
!
NotificationManagerCompat notificationManager = NotificationManagerCompat.from(this);
notificationManager.notify(notificationId, notificationBuilder.build());
•Pages
Notificaciones de sistema con funcionalidad de Wear
Extendiendo a Wear
•Pages con otro estilo
BigTextStyle
InboxStyle
BigPictureStyle
Notificaciones de sistema con funcionalidad de Wear
Extendiendo a Wear
•Pages con otro estilo
// Create a big text style for the second page
NotificationCompat.BigTextStyle secondPageStyle = new NotificationCompat.BigTextStyle()
.setBigContentTitle("BigTextStyle title")
.bigText(getString(R.string.a_very_large_text));
!
// Create second page notification
Notification secondPageNotification = new NotificationCompat.Builder(this)
.setStyle(secondPageStyle)
.build();
!
NotificationCompat.Extender extender = new NotificationCompat.WearableExtender()
.addPage(secondPageNotification)
!
NotificationCompat.Builder notificationBuilder = new NotificationCompat.Builder(this)
.setSmallIcon(R.drawable.ic_launcher)
.setContentTitle("Default title")
.setContentText("Default text.")
.setTicker("New notification!")
.extend(extender);
BigTextStyle
Notificaciones de sistema con funcionalidad de Wear
Extendiendo a Wear
•Pages con otro estilo
InboxStyle
// Create a Inbox style for the third page
NotificationCompat.InboxStyle thirdPageStyle = new NotificationCompat.InboxStyle()
.setBigContentTitle("InboxStyle title”)
.addLine("Line 1”)
.addLine("Line 2”)
.addLine("Line 3");
!
// Create third page notification
Notification thirdPageNotification = new NotificationCompat.Builder(this)
.setStyle(thirdPageStyle)
.build();
!
NotificationCompat.Extender extender = new NotificationCompat.WearableExtender()
.addPage(thirdPageNotification)
!
NotificationCompat.Builder notificationBuilder = new NotificationCompat.Builder(this)
.setSmallIcon(R.drawable.ic_launcher)
.setContentTitle("Default title")
.setContentText("Default text.")
.setTicker("New notification!")
.extend(extender);
Notificaciones de sistema con funcionalidad de Wear
Extendiendo a Wear
•Pages con otro estilo
PigPictureStyle
// Create a BigPicture style for the fourth page
NotificationCompat.BigPictureStyle fourthPageStyle = new NotificationCompat.BigPictureStyle()
.setBigContentTitle("BigPictureStyle title”)
.bigPicture(BitmapFactory.decodeResource(getResources(), R.drawable.trollface));
!
// Create third page notification
Notification fourthPageNotification = new NotificationCompat.Builder(this)
.setStyle(fourthPageStyle)
.build();
!
NotificationCompat.Extender extender = new NotificationCompat.WearableExtender()
.addPage(fourthPageNotification)
!
NotificationCompat.Builder notificationBuilder = new NotificationCompat.Builder(this)
.setSmallIcon(R.drawable.ic_launcher)
.setContentTitle("Default title")
.setContentText("Default text.")
.setTicker("New notification!")
.extend(extender);
Notificaciones de sistema con funcionalidad de Wear
Extendiendo a Wear
•Actions
Notificaciones de sistema con funcionalidad de Wear
Extendiendo a Wear
•Actions
// Create an intent to open DetailActivity action
Intent actionIntent = new Intent(this, DetailActivity.class);
PendingIntent actionPendingIntent = PendingIntent.getActivity(
this,
requestCode,
actionIntent,
PendingIntent.FLAG_UPDATE_CURRENT);
!
// Create the action
NotificationCompat.Action action = new NotificationCompat.Action.Builder(
android.R.drawable.ic_menu_view,
"Open detail”,
actionPendingIntent)
.build();
!
NotificationCompat.Builder notificationBuilder = new NotificationCompat.Builder(this)
.setSmallIcon(R.drawable.ic_launcher)
.setContentTitle("Default title”)
.setContentText("Default text.”)
.setTicker("New notification!”)
.setContentIntent(actionPendingIntent)
.addAction(action)
.extend(extender);
Notificaciones de sistema con funcionalidad de Wear
Extendiendo a Wear
•Actions : Entrada por voz en una notificación
Notificaciones de sistema con funcionalidad de Wear
Extendiendo a Wear
•Actions : Entrada por voz en una notificación
1) Definimos la entrada de voz con un RemoteInput
public static final String EXTRA_VOICE_REPLY = "extra_voice_reply";
!
RemoteInput voiceRemoteInput = new RemoteInput.Builder(EXTRA_VOICE_REPLY)
.setLabel("Reply by voice")
.setChoices(getResources().getStringArray(R.array.reply_choices))
.build();
<string-array name="reply_choices">
<item>Yes</item>
<item>No</item>
<item>Maybe</item>
<item>Lo que diga la rubia</item>
<item>1 segundo</item>
<item>Estoy detrás de ti</item>
</string-array>
Notificaciones de sistema con funcionalidad de Wear
Extendiendo a Wear
•Actions : Entrada por voz en una notificación
2) Añadimos el RemoteInput a una acción de la notificación
// Create an intent to open the ShowMessageActivity action
Intent showMessageIntent = new Intent(this, ShowMessageActivity.class);
!
PendingIntent showMessagePendingIntent = PendingIntent.getActivity(this, ++requestCode,
showMessageIntent, PendingIntent.FLAG_UPDATE_CURRENT);
!
// Create the ReplyByVoiceAction and add the remote input
NotificationCompat.Action replyVoiceAction = new NotificationCompat.Action.Builder(
android.R.drawable.ic_menu_add,
"Speak now”,
showMessagePendingIntent)
.addRemoteInput(voiceRemoteInput)
.build();
Notificaciones de sistema con funcionalidad de Wear
Extendiendo a Wear
•Actions : Entrada por voz en una notificación
3) Creamos nueva activity que reciba el dato y lo muestre
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_show_message);
!
TextView messageTextView = (TextView) findViewById(R.id.message);
!
CharSequence message = "";
Intent intent = getIntent();
if (intent != null) {
message = getMessageText(intent);
}
messageTextView.setText(message);
}
!
private CharSequence getMessageText(Intent intent) {
Bundle remoteInput = RemoteInput.getResultsFromIntent(intent);
if (remoteInput != null) {
return remoteInput.getCharSequence(EXTRA_VOICE_REPLY);
}
return null;
}
Notificaciones de sistema con funcionalidad de Wear
Extendiendo a Wear
•Actions : Entrada por voz en una notificación
4) Añadimos la acción a la notificación - Sólo para Wear
NotificationCompat.Extender extender = new
NotificationCompat.WearableExtender()
.setBackground(BitmapFactory.decodeResource(getResources(),
R.drawable.trollface))
.addAction(replyVoiceAction);
Notificaciones de sistema con funcionalidad de Wear
Extendiendo a Wear
•Stack de notificaciones
Notificaciones de sistema con funcionalidad de Wear
Extendiendo a Wear
•Stack de notificaciones
1) Añadimos el grupo al que pertenece a cada notificación
private static final String GROUP_KEY_WORKSHOP_WEAR = "group_key_workshop_wear";
!
!
int notification1Id = 1;
!
NotificationCompat.Builder notification1Builder = new NotificationCompat.Builder(this)
.setSmallIcon(R.drawable.ic_launcher)
.setContentTitle("Default title 1")
.setContentText("Default text 1.")
.setTicker("New notification: 1!")
.setGroup(GROUP_KEY_WORKSHOP_WEAR);
!
NotificationManagerCompat notificationManager = NotificationManagerCompat.from(this);
notificationManager.notify(notification1Id, notification1Builder.build());
Notificaciones de sistema con funcionalidad de Wear
Extendiendo a Wear
•Stack de notificaciones
2) Creamos una notificación “resumen” para el móvil/tablet
private static final String GROUP_KEY_WORKSHOP_WEAR = "group_key_workshop_wear";
!
!
int notificationSummaryId = 3;
!
NotificationCompat.Builder notificationSummaryBuilder = new NotificationCompat.Builder(this)
.setSmallIcon(R.drawable.ic_launcher)
.setContentTitle("Summary title")
.setContentText("Sumary description")
.setTicker("New notification!")
.setGroup(GROUP_KEY_WORKSHOP_WEAR)
.setGroupSummary(true);
!
NotificationManagerCompat notificationManager = NotificationManagerCompat.from(this);
notificationManager.notify(notificationSummaryId, notificationSummaryBuilder.build());
Notificaciones de sistema con funcionalidad de Wear
Extendiendo a Wear
•Stack de notificaciones
Aplicaciones de Wear
Aplicaciones de Wear
Aplicaciones de Wear
Aplicaciones de Wear
Aplicaciones de Wear
SÓLO CON CLAVE DE RELEASE
Aplicaciones de Wear
Consideraciones
Aplicaciones de Wear
• Bajas especificaciones (procesador, batería, conectividad):

• Operaciones costosas, se ejecutan en el móvil/tablet

• Operaciones de red se ejecutan en el móvil/tablet

!
• Pantalla pequeña + dedos grandes
¿Cómo se ejecutan las aplicaciones?
Aplicaciones de Wear
• Por comando de voz • Mediante el menu Start
¿Cómo se ejecutan las aplicaciones?
Aplicaciones de Wear
• Por comando de voz, tan simple como añadir label en la activity que
queremos iniciar
<application
android:allowBackup="true"
android:icon="@drawable/ic_launcher"
android:label="@string/app_name"
android:theme="@android:style/Theme.DeviceDefault" >
!
<meta-data
android:name="com.google.android.gms.version"
android:value="@integer/google_play_services_version" />
!
<activity
android:name="com.droids4dev.wearapp.MainActivity"
android:label="@string/app_name" >
<intent-filter>
<action android:name="android.intent.action.MAIN" />
!
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
</application>
¿Cómo se ejecutan las aplicaciones?
Aplicaciones de Wear
• Por comando de voz, tan simple como añadir label en la activity que
queremos iniciar
<application
android:allowBackup="true"
android:icon="@drawable/ic_launcher"
android:label="@string/app_name"
android:theme="@android:style/Theme.DeviceDefault" >
!
<meta-data
android:name="com.google.android.gms.version"
android:value="@integer/google_play_services_version" />
!
<activity
android:name="com.droids4dev.wearapp.MainActivity"
android:label="@string/app_name" >
<intent-filter>
<action android:name="android.intent.action.MAIN" />
!
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
</application>
• Listado de librerías necesarias
• Módulo mobile:
• Librería de soporte (v4 o v7) si es necesario:
	 compile ‘com.android.support:appcompat-v7:21.0.2'
• Wearable Data Layer (incluida en Google Play Services)
	 compile ‘com.google.android.gms:play-services:6.1.71’
!
• Módulo wear:
• Librería de soporte (v4 o v7)
• Wearable Data Layer (incluida en Google Play Services)
	compile ‘com.google.android.gms:play-services-wearable:6.1.71'
• Wearable UI support library (unofficial)
	 compile 'com.google.android.support:wearable:1.0.0'
Aplicaciones de Wear
• referencia a la aplicación de Wear en build.gradle de la app de móvil/tablet
	 dependencies {

	 	 compile fileTree(dir: 'libs', include: ['*.jar'])

	 	 wearApp project(':wear')

	 	 compile 'com.android.support:appcompat-v7:21.0.2'

	 	 compile 'com.google.android.gms:play-services:6.1.71'

	 }

!
• si nos comunicamos con el móvil/tablet, añadir la version de Google Play
Services como meta-data en nuestro Manifest (dentro de Application)
<meta-data
android:name="com.google.android.gms.version"
android:value="@integer/google_play_services_version" />
Aplicaciones de Wear
Wearable UI Library:
• BoxInsetLayout
• CardFragment
• CircledImageView
• ConfirmationActivity
• DismissOverlayView
• GridViewPager
• GridPagerAdapter
• FragmentGridPagerAdapter
• WatchViewStub
• WearableListView
Aplicaciones de Wear
Aplicaciones de Wear
Envio de mensajes entre dispositivo-wearable
Aplicaciones de Wear
Sincronización de datos entre dispositivo-wearable
Caso de estudio:
Crear una Android que envíe un mensaje de texto a otra app de
nuestro Wearable, y este muestre dicho mensaje en una Custom
screen.
Aplicaciones de Wear
1) Creamos un cliente de Google Play Services en la app del
móvil/tablet. Un ejemplo sería crearlo en la propia Activity,
aunque no es la mejor.
2) Añadir métodos de Callback para la DATA LAYER y los eventos
del ciclo de vida
3) Definir una Asynctask (o clases que extienda de Thread) que
envíe tu mensaje a todos los nodos actualmente conectados
Aplicaciones de Wear
4) En la aplicación de Wear, crearemos un Listener service para
recibir los mensajes.
• Añadir el servicio en el Manifest
• Crear un servicio que extienda de WearableListenerService
!
5) Reenviar el mensaje a la Activity que necesita el dato. (Intent,
LocalBroadcastManager, … depende del caso)
Aplicaciones de Wear
Tips de configuración
•Si usas emulador: para conectar con el emulador hay que redireccionar el
puerto de comunicaciones del AVD al dispositivo, cada vez que se conecta
el dispositivo.
adb -d forward tcp:5601 tcp:5601
o
adb -s identificador forward tcp:5601 tcp:5601
+Info
Código de las aplicaciones de ejemplo:
https://github.com/Nescafemix/workshop-android-wear-notifications
https://github.com/Nescafemix/workshop-android-wear-app
¡MUCHAS GRACIAS!
Twitter: @Nescafemix

About.me: about.me/joan.fuentes.hernandez
Google+: plus.google.com/+JoanFuentesHernández
¿PREGUNTAS?
Twitter: @Nescafemix

About.me: about.me/joan.fuentes.hernandez
Google+: plus.google.com/+JoanFuentesHernández

More Related Content

Similar to Presentación de Android Wear impartida en el GDG Devfest Barcelona 2015

Java ME (Micro Edition)
Java ME (Micro Edition) Java ME (Micro Edition)
Java ME (Micro Edition) Anderson Rubio
 
Taller livetrackingandroid
Taller livetrackingandroidTaller livetrackingandroid
Taller livetrackingandroidsantiagohiguera
 
Realidad Aumentada más allá de Glass - Droidcon 2014
Realidad Aumentada más allá de Glass - Droidcon 2014Realidad Aumentada más allá de Glass - Droidcon 2014
Realidad Aumentada más allá de Glass - Droidcon 2014Fernando Gallego
 
LabAndroid: Taller "Mi Primera Aplicación Android"
LabAndroid: Taller "Mi Primera Aplicación Android"LabAndroid: Taller "Mi Primera Aplicación Android"
LabAndroid: Taller "Mi Primera Aplicación Android"Alberto Ruibal
 
Tutorial Nro 1 de Desarrollo de Aplicaciones Móviles con Android
Tutorial Nro 1 de Desarrollo de Aplicaciones Móviles con AndroidTutorial Nro 1 de Desarrollo de Aplicaciones Móviles con Android
Tutorial Nro 1 de Desarrollo de Aplicaciones Móviles con AndroidLuis Ernesto Castillo Alfaro
 
Sesion 11 Teoria.pdf
Sesion 11 Teoria.pdfSesion 11 Teoria.pdf
Sesion 11 Teoria.pdfDianaSullcav
 
Taller de programación
Taller de programaciónTaller de programación
Taller de programaciónRafa Perez
 
Unidad jme-02--ingbarcia-final
Unidad jme-02--ingbarcia-finalUnidad jme-02--ingbarcia-final
Unidad jme-02--ingbarcia-finalOrlando Barcia
 
Realidad aumentada
Realidad aumentadaRealidad aumentada
Realidad aumentadaPato Lara
 
Appcircus Academy: Integración de Social Media en Android
Appcircus Academy: Integración de Social Media en AndroidAppcircus Academy: Integración de Social Media en Android
Appcircus Academy: Integración de Social Media en AndroidAlberto Ruibal
 
Manual de android
Manual de androidManual de android
Manual de android481200619
 
Microsoft Virtual Academy - Xamarin iOS
Microsoft Virtual Academy - Xamarin iOSMicrosoft Virtual Academy - Xamarin iOS
Microsoft Virtual Academy - Xamarin iOSenriqueaguilar
 

Similar to Presentación de Android Wear impartida en el GDG Devfest Barcelona 2015 (20)

Java ME (Micro Edition)
Java ME (Micro Edition) Java ME (Micro Edition)
Java ME (Micro Edition)
 
Taller livetrackingandroid
Taller livetrackingandroidTaller livetrackingandroid
Taller livetrackingandroid
 
Realidad Aumentada más allá de Glass - Droidcon 2014
Realidad Aumentada más allá de Glass - Droidcon 2014Realidad Aumentada más allá de Glass - Droidcon 2014
Realidad Aumentada más allá de Glass - Droidcon 2014
 
LabAndroid: Taller "Mi Primera Aplicación Android"
LabAndroid: Taller "Mi Primera Aplicación Android"LabAndroid: Taller "Mi Primera Aplicación Android"
LabAndroid: Taller "Mi Primera Aplicación Android"
 
Tutorial Nro 1 de Desarrollo de Aplicaciones Móviles con Android
Tutorial Nro 1 de Desarrollo de Aplicaciones Móviles con AndroidTutorial Nro 1 de Desarrollo de Aplicaciones Móviles con Android
Tutorial Nro 1 de Desarrollo de Aplicaciones Móviles con Android
 
Manual marichuy
Manual marichuyManual marichuy
Manual marichuy
 
Manual marichuy
Manual marichuyManual marichuy
Manual marichuy
 
Sesion 11 Teoria.pdf
Sesion 11 Teoria.pdfSesion 11 Teoria.pdf
Sesion 11 Teoria.pdf
 
Taller de programación
Taller de programaciónTaller de programación
Taller de programación
 
Android
AndroidAndroid
Android
 
Expo kinect
Expo kinectExpo kinect
Expo kinect
 
Unidad jme-02--ingbarcia-final
Unidad jme-02--ingbarcia-finalUnidad jme-02--ingbarcia-final
Unidad jme-02--ingbarcia-final
 
Presentacion proyecto
Presentacion proyectoPresentacion proyecto
Presentacion proyecto
 
Realidad aumentada
Realidad aumentadaRealidad aumentada
Realidad aumentada
 
DotNetDom: El futuro de Xamarin
DotNetDom: El futuro de XamarinDotNetDom: El futuro de Xamarin
DotNetDom: El futuro de Xamarin
 
Appcircus Academy: Integración de Social Media en Android
Appcircus Academy: Integración de Social Media en AndroidAppcircus Academy: Integración de Social Media en Android
Appcircus Academy: Integración de Social Media en Android
 
Manual de android
Manual de androidManual de android
Manual de android
 
Microsoft Virtual Academy - Xamarin iOS
Microsoft Virtual Academy - Xamarin iOSMicrosoft Virtual Academy - Xamarin iOS
Microsoft Virtual Academy - Xamarin iOS
 
Curso android studio
Curso android studioCurso android studio
Curso android studio
 
Curso android studio
Curso android studioCurso android studio
Curso android studio
 

Presentación de Android Wear impartida en el GDG Devfest Barcelona 2015

  • 2. Mobile Software Engineer en Redbooth Inc. (formerly Teambox). ! Organizador del GDG Barcelona (Google Developer Group). ! Previously: UAB (Universidad A u t o n o m a d e B a rc e l o n a ) y Citigroup. ¿Quien soy? Twitter: @Nescafemix About.me: about.me/joan.fuentes.hernandez Google+: plus.google.com/+JoanFuentesHernández
  • 3. •Versión de Android para wearables (Lollipop actualmente) ! •Pretende facilitarnos la vida reduciendo tiempo de interacción con el móvil ! ! ! ! ! ! ! •Debe mostrar información concisa y útil. ¿Qué es Android Wear? VIDA REAL INTERACCIÓN DISPOSITIVO
  • 4. ! SECOND SCREEN + FAST ACTIONS Nuevo paradigma
  • 7. Visión creativa •Ejecutado automáticamente •1 mirada basta (Glanceable) •Todo sobre sugerir (stream) y demandar (cue card)
  • 8. Visión creativa •Ejecutado automáticamente •1 mirada basta (Glanceable) •Todo sobre sugerir (stream y demandar (cue card) •Cero o poca interacción
  • 9. Principios de diseño •No detengas al usuario. Déjalo seguir con su vida
  • 10. Principios de diseño •Diseña para grandes gestos
  • 12. Principios de diseño •Haz 1 cosa, y hazla rápido
  • 14. Principios de diseño •No seas troll, no molestes constantemente al usuario
  • 15. ¿Qué NO debería ser Android Wear?
  • 16. ¿Qué NO debería ser Android Wear?
  • 17. ¿Qué NO debería ser Android Wear?
  • 18. ¿Qué NO debería ser Android Wear?
  • 19. ¿Que necesitan nuestras apps para wear?
  • 20. NADA ¿Que necesitan nuestras apps para wear?
  • 21. NADA ¿Que necesitan nuestras apps para wear?
  • 22. NADA ¿Que necesitan nuestras apps para wear?
  • 24. Programando para Wear - tipos ! •Notificaciones de sistema con funcionalidad de Wear ! ! ! ! •Aplicaciones de Wear !
  • 25. Programando para Wear - tipos ! •Watch faces
  • 26. Notificaciones de sistema con funcionalidad de Wear ! •Cualquier notificación básica por defecto aparecerá en Wear int notificationId = 001; ! NotificationCompat.Builder notificationBuilder = new NotificationCompat.Builder(this) .setSmallIcon(R.drawable.ic_launcher) .setContentTitle("Default title") .setContentText("Default text.”) .setTicker("New notification!"); ! NotificationManagerCompat notificationManager = NotificationManagerCompat.from(this); notificationManager.notify(notificationId, notificationBuilder.build());
  • 27. Notificaciones de sistema con funcionalidad de Wear ! •Añadiendo una simple imagen de fondo Extendiendo a Wear int notificationId = 001; ! NotificationCompat.Extender extender = new NotificationCompat.WearableExtender() .setHintHideIcon(true) .setBackground(BitmapFactory.decodeResource(getResources(), R.drawable.trollface)); ! NotificationCompat.Builder notificationBuilder = new NotificationCompat.Builder(this) .setSmallIcon(R.drawable.ic_launcher) .setContentTitle("Default title") .setContentText("Default text.”) .setTicker("New notification!") .extend(extender); ! NotificationManagerCompat notificationManager = NotificationManagerCompat.from(this); notificationManager.notify(notificationId, notificationBuilder.build());
  • 28. Notificaciones de sistema con funcionalidad de Wear Extendiendo a Wear •Pages
  • 29. Notificaciones de sistema con funcionalidad de Wear Extendiendo a Wear // Create a second page notification Notification secondPageNotification = new NotificationCompat.Builder(this) .setContentTitle("Second Page title”) .setContentText("Default second page text”) .build(); •Pages
  • 30. // Specific extender to show only background in this notification page NotificationCompat.Extender extenderOnlyImage = new NotificationCompat.WearableExtender() .setHintShowBackgroundOnly(true); ! // Create a third page notification with only background Notification thirdPageNotification = new NotificationCompat.Builder(this) .extend(extenderOnlyImage) .build(); Notificaciones de sistema con funcionalidad de Wear Extendiendo a Wear •Pages
  • 31. Notificaciones de sistema con funcionalidad de Wear Extendiendo a Wear NotificationCompat.Extender extender = new NotificationCompat.WearableExtender() .setBackground(BitmapFactory.decodeResource(getResources(), R.drawable.trollface)) .addPage(secondPageNotification) .addPage(thirdPageNotification); NotificationCompat.Builder notificationBuilder = new NotificationCompat.Builder(this) .setSmallIcon(R.drawable.ic_launcher) .setContentTitle("Default title”) .setContentText("Default text.”) .setTicker("New notification!"); .extend(extender); ! NotificationManagerCompat notificationManager = NotificationManagerCompat.from(this); notificationManager.notify(notificationId, notificationBuilder.build()); •Pages
  • 32. Notificaciones de sistema con funcionalidad de Wear Extendiendo a Wear •Pages con otro estilo BigTextStyle InboxStyle BigPictureStyle
  • 33. Notificaciones de sistema con funcionalidad de Wear Extendiendo a Wear •Pages con otro estilo // Create a big text style for the second page NotificationCompat.BigTextStyle secondPageStyle = new NotificationCompat.BigTextStyle() .setBigContentTitle("BigTextStyle title") .bigText(getString(R.string.a_very_large_text)); ! // Create second page notification Notification secondPageNotification = new NotificationCompat.Builder(this) .setStyle(secondPageStyle) .build(); ! NotificationCompat.Extender extender = new NotificationCompat.WearableExtender() .addPage(secondPageNotification) ! NotificationCompat.Builder notificationBuilder = new NotificationCompat.Builder(this) .setSmallIcon(R.drawable.ic_launcher) .setContentTitle("Default title") .setContentText("Default text.") .setTicker("New notification!") .extend(extender); BigTextStyle
  • 34. Notificaciones de sistema con funcionalidad de Wear Extendiendo a Wear •Pages con otro estilo InboxStyle // Create a Inbox style for the third page NotificationCompat.InboxStyle thirdPageStyle = new NotificationCompat.InboxStyle() .setBigContentTitle("InboxStyle title”) .addLine("Line 1”) .addLine("Line 2”) .addLine("Line 3"); ! // Create third page notification Notification thirdPageNotification = new NotificationCompat.Builder(this) .setStyle(thirdPageStyle) .build(); ! NotificationCompat.Extender extender = new NotificationCompat.WearableExtender() .addPage(thirdPageNotification) ! NotificationCompat.Builder notificationBuilder = new NotificationCompat.Builder(this) .setSmallIcon(R.drawable.ic_launcher) .setContentTitle("Default title") .setContentText("Default text.") .setTicker("New notification!") .extend(extender);
  • 35. Notificaciones de sistema con funcionalidad de Wear Extendiendo a Wear •Pages con otro estilo PigPictureStyle // Create a BigPicture style for the fourth page NotificationCompat.BigPictureStyle fourthPageStyle = new NotificationCompat.BigPictureStyle() .setBigContentTitle("BigPictureStyle title”) .bigPicture(BitmapFactory.decodeResource(getResources(), R.drawable.trollface)); ! // Create third page notification Notification fourthPageNotification = new NotificationCompat.Builder(this) .setStyle(fourthPageStyle) .build(); ! NotificationCompat.Extender extender = new NotificationCompat.WearableExtender() .addPage(fourthPageNotification) ! NotificationCompat.Builder notificationBuilder = new NotificationCompat.Builder(this) .setSmallIcon(R.drawable.ic_launcher) .setContentTitle("Default title") .setContentText("Default text.") .setTicker("New notification!") .extend(extender);
  • 36. Notificaciones de sistema con funcionalidad de Wear Extendiendo a Wear •Actions
  • 37. Notificaciones de sistema con funcionalidad de Wear Extendiendo a Wear •Actions // Create an intent to open DetailActivity action Intent actionIntent = new Intent(this, DetailActivity.class); PendingIntent actionPendingIntent = PendingIntent.getActivity( this, requestCode, actionIntent, PendingIntent.FLAG_UPDATE_CURRENT); ! // Create the action NotificationCompat.Action action = new NotificationCompat.Action.Builder( android.R.drawable.ic_menu_view, "Open detail”, actionPendingIntent) .build(); ! NotificationCompat.Builder notificationBuilder = new NotificationCompat.Builder(this) .setSmallIcon(R.drawable.ic_launcher) .setContentTitle("Default title”) .setContentText("Default text.”) .setTicker("New notification!”) .setContentIntent(actionPendingIntent) .addAction(action) .extend(extender);
  • 38. Notificaciones de sistema con funcionalidad de Wear Extendiendo a Wear •Actions : Entrada por voz en una notificación
  • 39. Notificaciones de sistema con funcionalidad de Wear Extendiendo a Wear •Actions : Entrada por voz en una notificación 1) Definimos la entrada de voz con un RemoteInput public static final String EXTRA_VOICE_REPLY = "extra_voice_reply"; ! RemoteInput voiceRemoteInput = new RemoteInput.Builder(EXTRA_VOICE_REPLY) .setLabel("Reply by voice") .setChoices(getResources().getStringArray(R.array.reply_choices)) .build(); <string-array name="reply_choices"> <item>Yes</item> <item>No</item> <item>Maybe</item> <item>Lo que diga la rubia</item> <item>1 segundo</item> <item>Estoy detrás de ti</item> </string-array>
  • 40. Notificaciones de sistema con funcionalidad de Wear Extendiendo a Wear •Actions : Entrada por voz en una notificación 2) Añadimos el RemoteInput a una acción de la notificación // Create an intent to open the ShowMessageActivity action Intent showMessageIntent = new Intent(this, ShowMessageActivity.class); ! PendingIntent showMessagePendingIntent = PendingIntent.getActivity(this, ++requestCode, showMessageIntent, PendingIntent.FLAG_UPDATE_CURRENT); ! // Create the ReplyByVoiceAction and add the remote input NotificationCompat.Action replyVoiceAction = new NotificationCompat.Action.Builder( android.R.drawable.ic_menu_add, "Speak now”, showMessagePendingIntent) .addRemoteInput(voiceRemoteInput) .build();
  • 41. Notificaciones de sistema con funcionalidad de Wear Extendiendo a Wear •Actions : Entrada por voz en una notificación 3) Creamos nueva activity que reciba el dato y lo muestre @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_show_message); ! TextView messageTextView = (TextView) findViewById(R.id.message); ! CharSequence message = ""; Intent intent = getIntent(); if (intent != null) { message = getMessageText(intent); } messageTextView.setText(message); } ! private CharSequence getMessageText(Intent intent) { Bundle remoteInput = RemoteInput.getResultsFromIntent(intent); if (remoteInput != null) { return remoteInput.getCharSequence(EXTRA_VOICE_REPLY); } return null; }
  • 42. Notificaciones de sistema con funcionalidad de Wear Extendiendo a Wear •Actions : Entrada por voz en una notificación 4) Añadimos la acción a la notificación - Sólo para Wear NotificationCompat.Extender extender = new NotificationCompat.WearableExtender() .setBackground(BitmapFactory.decodeResource(getResources(), R.drawable.trollface)) .addAction(replyVoiceAction);
  • 43. Notificaciones de sistema con funcionalidad de Wear Extendiendo a Wear •Stack de notificaciones
  • 44. Notificaciones de sistema con funcionalidad de Wear Extendiendo a Wear •Stack de notificaciones 1) Añadimos el grupo al que pertenece a cada notificación private static final String GROUP_KEY_WORKSHOP_WEAR = "group_key_workshop_wear"; ! ! int notification1Id = 1; ! NotificationCompat.Builder notification1Builder = new NotificationCompat.Builder(this) .setSmallIcon(R.drawable.ic_launcher) .setContentTitle("Default title 1") .setContentText("Default text 1.") .setTicker("New notification: 1!") .setGroup(GROUP_KEY_WORKSHOP_WEAR); ! NotificationManagerCompat notificationManager = NotificationManagerCompat.from(this); notificationManager.notify(notification1Id, notification1Builder.build());
  • 45. Notificaciones de sistema con funcionalidad de Wear Extendiendo a Wear •Stack de notificaciones 2) Creamos una notificación “resumen” para el móvil/tablet private static final String GROUP_KEY_WORKSHOP_WEAR = "group_key_workshop_wear"; ! ! int notificationSummaryId = 3; ! NotificationCompat.Builder notificationSummaryBuilder = new NotificationCompat.Builder(this) .setSmallIcon(R.drawable.ic_launcher) .setContentTitle("Summary title") .setContentText("Sumary description") .setTicker("New notification!") .setGroup(GROUP_KEY_WORKSHOP_WEAR) .setGroupSummary(true); ! NotificationManagerCompat notificationManager = NotificationManagerCompat.from(this); notificationManager.notify(notificationSummaryId, notificationSummaryBuilder.build());
  • 46. Notificaciones de sistema con funcionalidad de Wear Extendiendo a Wear •Stack de notificaciones
  • 52. SÓLO CON CLAVE DE RELEASE Aplicaciones de Wear
  • 53. Consideraciones Aplicaciones de Wear • Bajas especificaciones (procesador, batería, conectividad): • Operaciones costosas, se ejecutan en el móvil/tablet • Operaciones de red se ejecutan en el móvil/tablet ! • Pantalla pequeña + dedos grandes
  • 54. ¿Cómo se ejecutan las aplicaciones? Aplicaciones de Wear • Por comando de voz • Mediante el menu Start
  • 55. ¿Cómo se ejecutan las aplicaciones? Aplicaciones de Wear • Por comando de voz, tan simple como añadir label en la activity que queremos iniciar <application android:allowBackup="true" android:icon="@drawable/ic_launcher" android:label="@string/app_name" android:theme="@android:style/Theme.DeviceDefault" > ! <meta-data android:name="com.google.android.gms.version" android:value="@integer/google_play_services_version" /> ! <activity android:name="com.droids4dev.wearapp.MainActivity" android:label="@string/app_name" > <intent-filter> <action android:name="android.intent.action.MAIN" /> ! <category android:name="android.intent.category.LAUNCHER" /> </intent-filter> </activity> </application>
  • 56. ¿Cómo se ejecutan las aplicaciones? Aplicaciones de Wear • Por comando de voz, tan simple como añadir label en la activity que queremos iniciar <application android:allowBackup="true" android:icon="@drawable/ic_launcher" android:label="@string/app_name" android:theme="@android:style/Theme.DeviceDefault" > ! <meta-data android:name="com.google.android.gms.version" android:value="@integer/google_play_services_version" /> ! <activity android:name="com.droids4dev.wearapp.MainActivity" android:label="@string/app_name" > <intent-filter> <action android:name="android.intent.action.MAIN" /> ! <category android:name="android.intent.category.LAUNCHER" /> </intent-filter> </activity> </application>
  • 57. • Listado de librerías necesarias • Módulo mobile: • Librería de soporte (v4 o v7) si es necesario: compile ‘com.android.support:appcompat-v7:21.0.2' • Wearable Data Layer (incluida en Google Play Services) compile ‘com.google.android.gms:play-services:6.1.71’ ! • Módulo wear: • Librería de soporte (v4 o v7) • Wearable Data Layer (incluida en Google Play Services) compile ‘com.google.android.gms:play-services-wearable:6.1.71' • Wearable UI support library (unofficial) compile 'com.google.android.support:wearable:1.0.0' Aplicaciones de Wear
  • 58. • referencia a la aplicación de Wear en build.gradle de la app de móvil/tablet dependencies { compile fileTree(dir: 'libs', include: ['*.jar']) wearApp project(':wear') compile 'com.android.support:appcompat-v7:21.0.2' compile 'com.google.android.gms:play-services:6.1.71' } ! • si nos comunicamos con el móvil/tablet, añadir la version de Google Play Services como meta-data en nuestro Manifest (dentro de Application) <meta-data android:name="com.google.android.gms.version" android:value="@integer/google_play_services_version" /> Aplicaciones de Wear
  • 59. Wearable UI Library: • BoxInsetLayout • CardFragment • CircledImageView • ConfirmationActivity • DismissOverlayView • GridViewPager • GridPagerAdapter • FragmentGridPagerAdapter • WatchViewStub • WearableListView Aplicaciones de Wear
  • 60. Aplicaciones de Wear Envio de mensajes entre dispositivo-wearable
  • 61. Aplicaciones de Wear Sincronización de datos entre dispositivo-wearable
  • 62. Caso de estudio: Crear una Android que envíe un mensaje de texto a otra app de nuestro Wearable, y este muestre dicho mensaje en una Custom screen. Aplicaciones de Wear
  • 63. 1) Creamos un cliente de Google Play Services en la app del móvil/tablet. Un ejemplo sería crearlo en la propia Activity, aunque no es la mejor. 2) Añadir métodos de Callback para la DATA LAYER y los eventos del ciclo de vida 3) Definir una Asynctask (o clases que extienda de Thread) que envíe tu mensaje a todos los nodos actualmente conectados Aplicaciones de Wear
  • 64. 4) En la aplicación de Wear, crearemos un Listener service para recibir los mensajes. • Añadir el servicio en el Manifest • Crear un servicio que extienda de WearableListenerService ! 5) Reenviar el mensaje a la Activity que necesita el dato. (Intent, LocalBroadcastManager, … depende del caso) Aplicaciones de Wear
  • 65. Tips de configuración •Si usas emulador: para conectar con el emulador hay que redireccionar el puerto de comunicaciones del AVD al dispositivo, cada vez que se conecta el dispositivo. adb -d forward tcp:5601 tcp:5601 o adb -s identificador forward tcp:5601 tcp:5601
  • 66. +Info Código de las aplicaciones de ejemplo: https://github.com/Nescafemix/workshop-android-wear-notifications https://github.com/Nescafemix/workshop-android-wear-app
  • 67. ¡MUCHAS GRACIAS! Twitter: @Nescafemix About.me: about.me/joan.fuentes.hernandez Google+: plus.google.com/+JoanFuentesHernández