Domanda

Ho il codice per leggere i dettagli di contatto e leggere i compleanni.Ma come posso ottenere un elenco di contatti in ordine di compleanno imminente?

Per un singolo contatto identificato da id, ottengo dettagli e compleanno in questo modo:

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 il codice per leggere tutti i contatti è:

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;
    }
È stato utile?

Soluzione

L'ho fatto il contrario -. Una selezione direttamente alla tabella dati che memorizza compleanno

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;

}

Il SELECT viene chiamato due volte - una chiamata da oggi al 12/31 e seconda chiamata dal 01/01 ad oggi. Sono tornato limite righe da 10, ma questo non è necesarry.

Modifica ho scoperto che questo non funziona su tutti i telefoni Android come le date di compleanno sono memorizzati in molti formato diverso. Quindi devi caricare tutti i compleanni (non ordinato), analizzarlo e ordinare nella memoria. #Fail

Altri suggerimenti

Credo che avrei avuto l'elenco ordinato per compleanno, quindi copiare tale elenco in una seconda lista, con data di oggi come la "data zero". Sembra che sarebbe stato più pulito di farlo in questo modo piuttosto che cercare di martello fuori una query appropriata, anche se potrebbe essere un tocco più lento.

Ho finito con questa soluzione

  • ho creato una tabella dei titolari dei dati nel mio database SQLite per contenere ID contatto, nome, data di compleanno
  • leggere i contatti a cui è stata impostata la data di nascita
  • inserire nella tabella i contatti con il compleanno
  • restituisce un cursore, che esegue una rawQuery quando il compleanno corrente viene calcolato nell'SQL

quindi alla fine ho ottenuto un cursore con ID contatti, nome visualizzato e compleanno dal database nell'ordine che volevo

Forse, si desidera utilizzare un CursorJoiner come nel seguente risposta: http://www.mail-archive.com/android- developers@googlegroups.com/msg44317.html

Ho un problema simile non l'ho ancora risolto, quindi mi piacerebbe sapere se è possibile ottenere questo al lavoro.

Modificare il parametro di ordinamento nella invocazione di query () in getList (). Attualmente è impostato su DISPLAY_NAME. Prova TYPE_BIRTHDAY.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top