DaVinci/Emmet – Créer une application Android Wear en moins de 10 minutes 1/2
Si vous avez lu mon tutoriel concernant le développement d’applications Android Wear http://tutos-android-france.com/developper-une-application-pour-les-montres-android-wear/ vous aurez pu remarquer que le développement d’un module Wear est assez fastidieux… En réponse à ces problématiques de synchronisation de données et d’images j’ai décidé de créer des librairies Android Wear permettant de gérer facilement les échanges de données :
- DaVinci, permettant le téléchargement et la mise en cache d’une image à la façon de Picasso
- Emmet, simplifiant l’échange de données entre Smartphone et Smartwatch, à la façon de Retrofit
https://github.com/florent37/DaVinci
https://github.com/florent37/Emmet
Regardons ensemble comment utiliser ces librairies, en reprenant le projet utilisé dans le précédent tutoriel
https://github.com/florent37/TutosAndroidFrance/tree/master/WearSample
DaVinci
DaVinci est disponible sur JCenter, c’est à dire qu’il est possible de l’importer depuis gradle en ajoutant dans votre fichier build.gradle
compile ('com.github.florent37:davinci:1.0.3@aar'){ transitive=true }
DaVinci est composée de 2 modules :
- DaVinci : à importer dans votre module Wear
- DaVinciDaemon :à importer dans votre module Smartphone (ou Tablette)
wear/build.gradle
compile ('com.github.florent37:davinci:1.0.3@aar'){ transitive=true }
mobile/build.gradle
compile ('com.github.florent37:davincidaemon:1.0.2@aar'){ transitive=true }
Utiliser DaVinci
Si vous êtes un adepte de Picasso, DaVinci sera facile à prendre en main, la syntaxe est exactement la même :
Pour charger une image depuis un PATH
DaVinci.with(context).load("/image/0").into(imageView);
Ou directement depuis une URL !
DaVinci.with(context).load("http://i.imgur.com/o3ELrbX.jpg").into(imageView);
N’oubliez pas d’activer l’écriture sur le disque pour bénéficier du cache
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
Pour simplifier son utilisation j’ai automatisé son utilisation depuis un GridViewPager, ce sera utile pour notre exemple
@Override public Drawable getBackgroundForRow(final int row) { return DaVinci.with(context).load("/image/" + row).into(this, row); }
Utiliser DaVinciDaemon
DaVinci a besoin de son DaVinciDaemon coté smartphone, qui a pour role de répondre aux requêtes du module wear et envoyer les bitmap demandées.
DaVinciDaemon a juste besoin d’écouter les messages reçus par le service wear sur smartphone :
Dans votre WearableListenerService
@Override public void onMessageReceived(MessageEvent messageEvent) { super.onMessageReceived(messageEvent); DaVinciDaemon.with(getApplicationContext()).handleMessage(messageEvent); ... }
Il est possible de pré-charger des images afin qu’elles soient directement disponibles sur la montre
(Cette étape n’est pas indispensable, mais elle accélère le temps de chargement des images)
Depuis le module mobile/
DaVinciDaemon.with(getApplicationContext()).load("http://i.imgur.com/o3ELrbX.jpg").send();
Emmet
Emmet permet un échange de données selon un protocole entre Wear et Smartphone. Cela veux dire que l’on va définir une façon de communiquer qui sera utilisée par nos 2 modules, dans notre cas il suffit de définit une interface sur lequel nous pourrons appeler des fonctions. Chaque appel de fonction depuis le module wear/ sera transmit au module mobile/ et inversement.
Envoyer un message de notre Wear vers le Smartphone
Dans l’exemple suivant, je vais envoyer un message sayHello depuis ma Smartwatch vers mon Smartphone :
1. Je crée un module librairie : wearprotocol
2. J’importe Emmet dans ce module
wearprotocol/build.gradle
apply plugin: 'com.android.library' android { compileSdkVersion 22 buildToolsVersion "22.0.1" defaultConfig { minSdkVersion 14 targetSdkVersion 22 versionCode 1 versionName "1.0" } buildTypes { release { minifyEnabled false proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro' } } } dependencies { compile fileTree(dir: 'libs', include: ['*.jar']) compile 'com.android.support:appcompat-v7:22.0.0' compile ('com.github.florent37:emmet:1.0.4@aar'){ transitive=true } }
3. Je définit mon protocole / interface
public interface SmartphoneProtocol{ public void sayHello(); }
4. Je relie mon activity à Emmet puis créé un Sender depuis mon module wear/
Ne pas oublier d’ajouter la dépendance au module wearprotocol
wear/build.gralde
dependencies{ compile project(':wearprotocol') }
wear/ MainActivity.java
public class MainActivity extends Activity { @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); Emmet.onCreate(this); SmartphoneProtocol smartphoneProtocol = Emmet.createSender(SmartphoneProtocol.class); } @Override protected void onDestroy() { super.onDestroy(); Emmet.onDestroy(); } }
5. J’appelle sayHello() sur mon Sender
smartphoneProtocol.sayHello();
Recevoir les messages coté Smartphone
1. Relier notre service à Emmet : Pour cela, le plus simple est d’étendre EmmetWearableListenerService
Ne pas oublier d’ajouter la dépendance au module wearprotocol
mobile/build.gralde
dependencies{ compile project(':wearprotocol') }
mobile/ WearService.java
public class WearService extends EmmetWearableListenerService implements WearProtocol { }
2. Enregistrer un Receiver : nous pouvons enregistrer directement le servie en Receiver en lui faisant implémenter SmartphoneProtocol
public class WearService extends EmmetWearableListenerService implements SmartphoneProtocol { @Override public void onCreate() { super.onCreate(); Emmet.registerReceiver(SmartphoneProtocol.class,this); } @Override public void sayHello() { //<---- appelé lors de la récéption du message sayHello() Log.d(TAG,"sayHello"); } }
Pas de crainte vous pouvez envoyer utiliser des fonctions contenant des paramètres, ils seront transmits.
Envoyer un message depuis notre Smartphone vers notre Wear
1. Cela se fait de la même manière, il suffit de définir un protocole, par exemple WearProtocole
public interface WearProtocol{ public void sayReceived(String text); }
2. Puis de créer un Sender coté Smartphone dans notre service et de lui appeler notre fonction sayReceived
public class WearService extends EmmetWearableListenerService implements SmartphoneProtocol { private WearProtocol wearProtocol; @Override public void onCreate() { super.onCreate(); Emmet.registerReceiver(SmartphoneProtocol.class,this); WearProtocol wearProtocol = Emmet.createSender(WearProtocol.class); } @Override public void sayHello() { //<---- appelé lors de la reception du message sayHello() Log.d(TAG,"sayHello"); wearProtocol.sayReceived("Yes I received it"); } }
3. Créer un Receiver coté Wear
public class MainActivity extends Activity implements WearProtocol{ @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); Emmet.onCreate(this); SmartphoneProtocol smartphoneProtocol = Emmet.createSender(SmartphoneProtocol.class); Emmet.registerReceiver(WearProtocol.class,this); } @Override protected void onDestroy() { super.onDestroy(); Emmet.onDestroy(); } @Override public void sayReceived(String text){ //<---- appelé lors de la reception du message sayReceived(txt) Log.d(TAG,"sayReceived "+text); } }