2010-03-20 3 views
7

У меня есть код для чтения контактных данных и чтения дней рождения. Но как мне получить список контактов в порядке их предстоящего дня рождения?Как получить контакты в порядке их предстоящих дней рождения?

Для одного контакта, идентифицированной id, я получаю информацию и день рождения, как это:

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

и код для чтения всех контактов:

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

ответ

1

Я сделал это в обратном порядке - выбор непосредственно в таблице данных, в которой хранится день рождения.

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; 

}

Оператор SELECT вызывается дважды - один вызов с сегодняшнего дня до 12/31 и второй звонок от 01/01 до сегодняшнего дня. Я ограничиваю возвращенные строки до 10, но это необязательно.

EDIT: Я обнаружил, что это не будет работать на всех телефонах Android, поскольку даты рождения хранятся в разных форматах. Таким образом, вы должны загружать все дни рождения (неупорядоченные), разбирать его и сортировать в памяти. #Fail

+0

Мне интересно, возвращает ли этот запрос дату рождения или дату юбилея? И он возвращает все ближайшие? Например: если я запрошу 25 декабря, он вернет людей, у которых есть юбилеи после 25-го и после 1 января? – Pentium10

+0

1) Он возвращает дату рождения в формате yyyy-MM-dd. Чтобы получить юбилейную дату, вы должны подстроить ее. 2) Я решил это, дважды вызвав запрос - проверьте отредактированный код. – krtek

-1

Изменение параметров сортировки в вашем вызове запроса() в getList(). В настоящее время установлено значение DISPLAY_NAME. Попробуйте TYPE_BIRTHDAY.

+0

Это не так просто. Эти два доступны двум различным провайдерам контента. Таким образом, я не хочу простого порядка по Днём рождения, я хочу, чтобы заказ был готов, поэтому кто-то с днем ​​рождения 23 марта будет первым, а в следующем году - в феврале. – Pentium10

0

Может быть, вы хотите использовать CursorJoiner как в следующем ответе: http://www.mail-archive.com/[email protected]/msg44317.html

У меня есть аналогичный вопрос, который я до сих пор не решена, так что я хотел бы знать, если вы можете получить эту работу.

+0

CursorJoiner требует, чтобы оба курсора отсортированы по соединению – Pentium10

1

Я думаю, что получим список, отсортированный по дню рождения, а затем скопируйте этот список во второй список, используя сегодняшнюю дату как «нулевую дату». Похоже, что было бы более чисто, чем пытаться выработать соответствующий запрос, хотя это может быть медленнее.

1

Я закончил с этим раствором

  • создал таблицу держателя данных в моей базе данных SQLite для хранения контактов идентификатора, имени, даты рождения
  • чтения контактов, день рождения набора
  • вставить контакты с день рождения в таблице
  • возвращение Курсор, что делает rawQuery, когда текущий день рождения рассчитывается в SQL

поэтому в финале у меня появился курсор с идентификатором контактов, отображаемым именем и днем ​​рождения из базы данных в том порядке, в котором я хотел