Accueil > Non classé > Android pour l’entreprise – 2 – Vous habitez chez vos parents ?

Android pour l’entreprise – 2 – Vous habitez chez vos parents ?

Cet article est la suite de Android pour l’entreprise – 1 – Premiers contacts. Il appartient à la série Android pour l’entreprise, dont le fil conducteur est la réalisation d’une application Android d’annuaire d’entreprise : YMCA.

Aujourd’hui, nous allons étendre la couverture fonctionnelle de YMCA, et utiliser de nouveaux services fournis par Android : l’ajout de contact, et l’intégration avec Google Maps.

Mais auparavant, un avant goût des articles à venir…

Teaser

Voici la liste non exhaustive des sujets que je souhaite aborder au cours des prochains articles sur le thème “Android pour l’entreprise” :

  • Mises à jour automatiques d’applications sans passer par le market
  • Fonctionnement offline, tâches asynchrones et bd locale
  • Tests unitaires et tests d’intégration
  • Mise en place de Maven et intégration avec Hudson
  • Intégration avec Jasig CAS
  • Création de bibliothèques (JARs) utilisant des classes d’Android
  • Injection de dépendances avec Google Guice

teasing

L’ordre n’est pas immuable, n’hésitez pas à indiquer dans les commentaires si certains sujets ont votre préférence pour être traités en priorité.

YMCA : évolution fonctionnelle

Voici le nouveau besoin :

  • lorsque l’utilisateur tapote un élément de la liste, une nouvel écran apparaît. Il s’agit d’une fiche de contact, qui donne accès aux informations suivantes : nom du contact, numéro de téléphone, adresse,
  • depuis cet écran, l’utilisateur peut réaliser les actions suivantes : appeler un contact, voir son adresse sur Google Maps, ajouter le contact à l’annuaire du téléphone.
YMCA : évolution des besoins fonctionnels

YMCA : évolution des besoins fonctionnels

Comme d’habitude, les sources du projet sont disponibles à la fin de cet article. Notez que le code de l’archive est très largement commenté.

Une nouvelle activité

Qui dit nouvel écran, dit nouvelle activité. Il suffit pour cela de créer la classe ContactDetailsActivity qui étend de Activity, et de l’enregistrer au sein du AndroidManifest.xml :


1
<activity android:name=".activity.ContactDetailsActivity" />

Puis on fait en sorte qu’un clic sur un contact dans la liste démarre cette activité. Il faut pour cela modifier le listener associé à la liste. Le contact sélectionné sera passé en paramètre, grâce à la notion d’extra dans un intent :


1
2
3
4
5
public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
    Intent i = new Intent(ContactListActivity.this, ContactDetailsActivity.class);
    i.putExtra(ContactDetailsActivity.CONTACT_EXTRA, contacts.get(position));
    ContactListActivity.this.startActivity(i);
}

Vous habitez chez vos parents ?

L’ajout d’un champ adress à la classe Contact est un jeu d’enfant. On en profite pour faire évoluer le fichier de contacts (contacts.txt), et le service chargé de le parser.

Plus intéressant, on souhaite demander d’afficher  cette adresse à l’application Google Maps :


1
2
Intent intent = new Intent(Intent.ACTION_VIEW, Uri.parse("geo:0,0?q=" + address));
startActivity(intent);

Simple n’est-ce pas ? Le principe est exactement le même que pour la composition de numéro, vu dans l’article précédent :


1
2
Intent intent = new Intent(Intent.ACTION_DIAL, Uri.parse("tel:" + phoneNumber));
startActivity(intent);

Donne moi ton numéro

L’ajout d’un contact au sein de l’annuaire du téléphone se révèle légèrement plus complexe, et nécessite l’utilisation d’un ContentResolver. Je ne rentrerai pas dans les détails du fonctionnement général d’un ContentResolver, je vous conseille cependant de lire la page de doc à ce sujet. Le principe est de transmettre au ContentResolver  des requêtes adressées à une URI donnée.

Il faut au préalable demander les permissions de lecture et modification de contacts au sein du fichier AndroidManifest.xml :


1
2
<uses-permission android:name="android.permission.WRITE_CONTACTS" />
<uses-permission android:name="android.permission.READ_CONTACTS" />

Vérifions dans un premier temps si le contact existe déjà :


1
2
3
4
5
6
7
8
9
10
String name = contact.getName() + " (YMCA)";

ContentResolver resolver = getContentResolver();
Cursor cur = resolver.query(People.CONTENT_URI, new String[] { Contacts.People._ID }, Contacts.People.NAME + "=?", new String[] { name }, null);
int nbContacts = cur.getCount();
cur.close();

if (nbContacts != 0) {
  return;
}

Il faut ensuite créer le contact, via l’utilisation d’une méthode helper qui fait un insert :


1
2
3
4
ContentValues personValues = new ContentValues();
personValues.put(Contacts.People.NAME, name);
personValues.put(Contacts.People.STARRED, 0); //Mettre 1 pour que le contact soit dans les favoris
Uri newPersonUri = Contacts.People.createPersonInMyContactsGroup(resolver, personValues);
Insertion du numéro de téléphone mobile :

1
2
3
4
5
Uri mobileUri = Uri.withAppendedPath(newPersonUri, Contacts.People.Phones.CONTENT_DIRECTORY);
ContentValues mobileValues = new ContentValues();
mobileValues.put(Contacts.Phones.NUMBER, contact.getPhoneNumber());
mobileValues.put(Contacts.Phones.TYPE, Contacts.Phones.TYPE_WORK);
resolver.insert(mobileUri, mobileValues);

Insertion de l’adresse postale du contact :


1
2
3
4
5
6
Uri addressUri = Uri.withAppendedPath(newPersonUri, Contacts.People.ContactMethods.CONTENT_DIRECTORY);
ContentValues addressValues = new ContentValues();
addressValues.put(Contacts.ContactMethods.KIND, Contacts.KIND_POSTAL);
addressValues.put(Contacts.ContactMethods.TYPE, Contacts.ContactMethods.TYPE_WORK);
addressValues.put(Contacts.ContactMethods.DATA, contact.getAddress());
resolver.insert(addressUri, addressValues);

Et voici le résultat, les contacts ajoutés sont dans l’annuaire :

ajout_contacts

Pour aller plus loin

Au cours de cet article, je vous ai présenté les points essentiels, sans livrer l’intégralité du code source.

Pour comprendre plus en détail le fonctionnement de YMCA, je vous propose de coder vous même une nouvelle fonctionnalité : l’ajout d’un champ email.

Un nouveau champ doit donc apparaître sur la page des détails d’un contact, et un clic sur ce champ doit ouvrir l’application d’envoi d’email.

Afin de modulariser le code, les différentes actions réalisables (appeler / voir sur Google Maps  / ajouter aux contacts) ont été encapsulées dans des commandes (cf design pattern command).


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
//L'interface Command
public interface Command { void execute(); }
//Une implémentation
public class DialPhoneNumberCommand implements Command {
   private final Context    context;
   private final String    phoneNumber;
   public DialPhoneNumberCommand(Context context, String phoneNumber) {
       this.context = context;
       this.phoneNumber = phoneNumber;
   }
   public void execute() {
       Intent intent = new Intent(Intent.ACTION_DIAL, Uri.parse("tel:" + phoneNumber));
       context.startActivity(intent);
   }
}

La page de détails d’un contact comprend une liste d’actions. A chaque action est associée un titre, un contenu, et une commande.

Le contenu de la liste est donné par un SimpleAdapter, et cet adapter est construit par un builder, créé pour l’occasion. La méthode ContactDetailsActivity.addContent() insère les éléments dans le builder :


1
2
3
4
5
// Composer un numéro de téléphone
title = getString(R.string.contact_details_call_text);
content = contact.getPhoneNumber();
command = new DialPhoneNumberCommand(this, contact.getPhoneNumber());
builderAndInvoker.addAction(title, content, command);

Si je résume, pour ajouter ce champ email, il faut :

  • ajouter un champ email à la classe Contact, dans le fichier de liste de contacts, et en tenir compte dans le service qui lit ce fichier distant,
  • créer la commande qui va bien,
  • insérer une nouvelle action dans le builder.

Alors, qu’attendez-vous ? Ah, peut-être vous manque t’il  une dernière clé : comment ouvrir l’application d’envoi d’email en lui donnant en paramètre l’adresse email ?

Cela fonctionne exactement comme pour voir une adresse sur Google Maps, si ce n’est que l’URI est différente :


1
2
Intent intent = new Intent(Intent.ACTION_VIEW, Uri.parse("mailto:" + emailAddress));
startActivity(intent);

Attention : cet intent ne fonctionnera pas si l’application d’email n’a pas été configurée au préalable. Pour cela, il suffit de lancer l’application “Email”, et de suivre les étapes de configuration.

Conclusion

Comme promis :

Notez que la solution pour l’envoi d’email fait partie des sources de l’article suivant : Android pour l’entreprise – 3 – Déploiement hors market.

Vous venez probablement de réaliser à quel point il est aisé de s’intégrer au sein de l’écosystème Android, en tout sécurité. Les applications d’entreprises y trouveront un terrain fertile pour répondre à leur besoins spécifiques.

ContactDetailsActivit
// Ajouter un contact à l’annuaire
title = getString(R.string.contact_details_add_text);
content = getString(R.string.contact_details_add_details);
command = new AddContactCommand(this, contact);
builderAndInvoker.addAction(title, content, command);
Share
  1. Alexis THOMAS
    27/01/2010 à 14:13 | #1

    L’article 1 mentionnait l’utilisation du “Build Target : Android 1.5″ lors de la création de l’AVD. On notera que pour l’article 2, faisant appel à Google Maps, il faut donc se servir d’un AVD avec un Build Target : Google APIs.

  1. 10/01/2010 à 19:12 | #1
  2. 21/01/2010 à 17:13 | #2