DaVinci/Emmet – Créer une application Android Wear en moins de 10 minutes 1/2

davinci_new

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

Capture d’écran 2015-05-02 à 19.59.00

Capture d’écran 2015-05-02 à 19.59.41

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);
    }
}

Laisser un commentaire

Votre adresse de messagerie ne sera pas publiée. Les champs obligatoires sont indiqués avec *