Pergunta

Tenho código para ler os detalhes de contato e ler aniversários. Mas como faço para obter uma lista de contatos em ordem de seu próximo aniversário?

Para um único contato identificado por id, Recebo detalhes e aniversário como este:

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

E o código para ler todos os contatos é:

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;
    }
Foi útil?

Solução

Fiz isso de outra maneira - uma seleção diretamente para a tabela de dados que armazena aniversário.

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;

}

A seleção é chamada duas vezes - uma chamada de hoje a 31/12 e a segunda chamada de 01/01 a hoje. Limitei linhas devolvidas a 10, mas isso não é necessário.

EDITAR: Descobri que isso não funcionará em todos os telefones Android, pois as datas de aniversário são armazenadas em muitos formatos diferentes. Portanto, você precisa carregar todos os aniversários (não ordenados), analisá -lo e classificá -lo na memória. #Falhou

Outras dicas

Acho que eu resolveria a lista classificada por aniversário e copiaria essa lista em uma segunda lista, usando a data de hoje como a "data zero". Parece que seria mais limpo fazê -lo dessa maneira do que tentar martelar uma consulta apropriada, embora possa ser um toque mais lento.

Acabei com esta solução

  • Criou uma tabela de titular de dados no meu banco de dados SQLite para manter o ID de contato, nome, data de aniversário
  • Leia os contatos com conjunto de aniversário
  • Insira os contatos com o aniversário na mesa
  • Devolva um cursor, que faz um RawQuery quando o aniversário atual for calculado no SQL

Então, na final, acabei tendo um cursor com ID de contatos, nome de exibição e aniversário do banco de dados na ordem que eu queria

Talvez você queira usar um cursorJoiner como na seguinte resposta:http://www.mail-archive.com/android-developers@googlegroups.com/msg44317.html

Eu tenho um problema semelhante que ainda não resolvi, então adoraria saber se você pode fazer isso funcionar.

Modifique o parâmetro de classificação em sua invocação de query () em getList (). Atualmente, ele está definido para exibir_name. Tente type_birthday.

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top