How to get contacts in order of their upcoming birthdays?

后端 未结 5 1219
误落风尘
误落风尘 2020-12-15 12:45

I have code to read contact details and to read birthdays. But how do I get a list of contacts in order of their upcoming birthday?

For a single contact identified b

相关标签:
5条回答
  • 2020-12-15 12:50

    I think I'd get the list sorted by birthday, then copy that list into a second list, using today's date as the "zero date." Seems like it would be cleaner to do it that way than to try to hammer out an appropriate query, although it might be a touch slower.

    0 讨论(0)
  • 2020-12-15 12:59

    Perhaps, you want to use a CursorJoiner as in the following answer: http://www.mail-archive.com/android-developers@googlegroups.com/msg44317.html

    I have a similar issue I haven't solved yet, so I would love to know if you can get this to work.

    0 讨论(0)
  • I ended up with this solution

    • created a data holder table in my SQLite database to hold contact id,name, birthday date
    • read contacts that have birthday set
    • insert the contacts with birthday into table
    • return a Cursor, that does a rawQuery when the current birthday is calculated in the SQL

    so in the final I ended up having a Cursor with contacts id, display name, and birthday from the database in the order I wanted

    0 讨论(0)
  • 2020-12-15 13:04

    I did this the other way round - a selection directly to Data table which stores birthday.

    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;
    

    }

    The SELECT is called twice - one call from today to 12/31 and second call from 01/01 to today. I limit returned rows to 10 but this is not necesarry.

    EDIT: I found that this won't work on all Android phones as birthday dates are stored in many different format. So you have to load all birthdays (unordered), parse it and sort it in memory. #Fail

    0 讨论(0)
  • 2020-12-15 13:12

    Modify the sort parameter in your invocation of query() in getList(). Currently it is set to DISPLAY_NAME. Try TYPE_BIRTHDAY.

    0 讨论(0)
提交回复
热议问题