Question

Je code pour lire les détails de contact et de lire les anniversaires. Mais comment puis-je obtenir une liste de contacts afin de leur anniversaire à venir?

Pour un contact unique identifié par id, je reçois des détails et anniversaire comme ceci:

Cursor c = null;
  try {
   Uri uri = ContentUris.withAppendedId(
     ContactsContract.Contacts.CONTENT_URI, id);
   c = ctx.getContentResolver().query(uri, null, null, null, null);
   if (c != null) {
    if (c.moveToFirst()) {
     DatabaseUtils.cursorRowToContentValues(c, data);
    }

   }
   c.close();

   // read birthday
   c = ctx.getContentResolver()
     .query(
       Data.CONTENT_URI,
       new String[] { Event.DATA },
       Data.CONTACT_ID + "=" + id + " AND "
         + Data.MIMETYPE + "= '"
         + Event.CONTENT_ITEM_TYPE + "' AND "
         + Event.TYPE + "=" + Event.TYPE_BIRTHDAY,
       null, Data.DISPLAY_NAME);
   if (c != null) {
    try {
     if (c.moveToFirst()) {
      this.setBirthday(c.getString(0));
     }
    } finally {
     c.close();
    }
   }

   return super.load(id);
  } catch (Exception e) {
   Log.v(TAG(), e.getMessage(), e);
   e.printStackTrace();
   return false;
  } finally {
   if (c != null)
    c.close();
  }

et le code à lire tous les contacts est:

public Cursor getList() {
        // Get the base URI for the People table in the Contacts content
        // provider.
        Uri contacts = ContactsContract.Contacts.CONTENT_URI;
        // Make the query.
        ContentResolver cr = ctx.getContentResolver();
        // Form an array specifying which columns to return.
        String[] projection = new String[] { ContactsContract.Contacts._ID,
                ContactsContract.Contacts.DISPLAY_NAME };

        Cursor managedCursor = cr.query(contacts, projection, null, null,
                ContactsContract.Contacts.DISPLAY_NAME
                        + " COLLATE LOCALIZED ASC");
        return managedCursor;
    }
Était-ce utile?

La solution

Je l'ai fait dans l'autre sens -. Directement une sélection à la table de données qui stocke anniversaire

private static final int UPCOMING_COUNT = 10;


public static List<BContact> upcomingBirthday(Context ctx) {
    String today = new SimpleDateFormat("MM-dd").format(new Date());        
    List<BContact> firstPart = upcomingBirthday(ctx, today, "12-31", UPCOMING_COUNT);
    if (firstPart.size() < UPCOMING_COUNT) {
        firstPart.addAll(upcomingBirthday(ctx, "01-01", today, UPCOMING_COUNT - firstPart.size()));
    }
    return firstPart;
}


public static List<BContact> upcomingBirthday(Context ctx, String fromDate, String toDate, int rows) {

  Uri dataUri = ContactsContract.Data.CONTENT_URI;

  String[] projection = new String[] { ContactsContract.Contacts.DISPLAY_NAME,                         
            ContactsContract.CommonDataKinds.Event.CONTACT_ID,
            ContactsContract.CommonDataKinds.Event.START_DATE
            };


  Cursor c = ctx.getContentResolver().query(
       dataUri,
       projection, 
       ContactsContract.Data.MIMETYPE + "= ? AND " + 
       ContactsContract.CommonDataKinds.Event.TYPE + "=" + ContactsContract.CommonDataKinds.Event.TYPE_BIRTHDAY + 
       " AND substr(" + ContactsContract.CommonDataKinds.Event.START_DATE + ",6) >= ?" + 
       " AND substr(" + ContactsContract.CommonDataKinds.Event.START_DATE + ",6) <= ?" ,
       new String[] {ContactsContract.CommonDataKinds.Event.CONTENT_ITEM_TYPE, fromDate, toDate}, 
       "substr("+ ContactsContract.CommonDataKinds.Event.START_DATE +",6)");
  List<BContact> result = new ArrayList<BContact>();
  int i=0;
  while (c.moveToNext() && i<rows) {
      result.add(new BContact(c.getString(0), c.getString(1), c.getString(2)));
      i++;
  }
  c.close();
  return result;

}

Le SELECT est appelé deux fois - un appel à partir d'aujourd'hui à 12/31 et le deuxième appel de 01/01 à aujourd'hui. Je limite les lignes renvoyées à 10, mais ce n'est pas necesarry.

EDIT: Je trouve que cela ne fonctionnera pas sur tous les téléphones Android comme les dates d'anniversaire sont stockés dans de nombreux formats différents. Donc, vous devez charger tous les anniversaires () désordonnées, analyser et trier en mémoire. #Fail

Autres conseils

Je pense que j'obtenir la liste triée par anniversaire, puis copiez cette liste dans une deuxième liste, en utilisant la date d'aujourd'hui comme la « date zéro ». On dirait que ce serait plus propre de le faire de cette façon que d'essayer de marteler une requête appropriée, bien qu'il puisse être un peu plus lent.

J'ai fini avec cette solution

  • a créé une table de support de données dans ma base de données SQLite pour tenir le contact id, nom, date de naissance
  • lire les contacts qui se sont fixés d'anniversaire
  • insérer les contacts avec l'anniversaire dans la table
  • retour d'un curseur, qui fait un rawQuery lorsque l'anniversaire courant est calculé dans le SQL

dans la finale, je fini par avoir un curseur avec l'identifiant de contacts, le nom d'affichage, et l'anniversaire de la base de données dans l'ordre que je voulais

Peut-être, vous voulez utiliser un CursorJoiner comme dans la réponse suivante: http://www.mail-archive.com/android- developers@googlegroups.com/msg44317.html

J'ai un problème similaire, je ne l'ai pas encore résolu, donc j'aimerais savoir si vous pouvez obtenir ce travail.

Modifier le paramètre de tri dans votre appel de requête () dans getList (). À l'heure actuelle, il est réglé sur DISPLAY_NAME. Essayez TYPE_BIRTHDAY.

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top