2015-07-11 76 views
3

我想要做的是查询Android ContentProvider的联系人。RxJava:减少或合并或合并

光标返回包含联系人,他们可能有一个以上的注册号对他们CONTACT_ID)

到目前为止,我质疑的DB,和我通过游标行遍历多个副本。 我映射()这些行,并将它们转换成ValueObjects

接下来,我想通过VO的全部名单,并合并具有相同CONTACT_ID的那些(在VO将存储标签&数字阵列)

但是,我卡住了,我不知道如何执行最后一部分,我如何循环访问ValueObjects列表,将重复项合并为一个,然后处理不需要的项。

这是由ContentProvider的返回游标的示例:

86 { 
    _id=5190 
    contact_id=2167 
    display_name=John Doe 
    data1=+44 20 7123 7890 
    data2=3 
    data3=null 
    photo_thumb_uri=content://com.android.contacts/contacts/2167/photo 
    lookup=731i7g4b3e9879f40515 
} 
87 { 
    _id=5191 
    contact_id=2167 
    display_name=John Doe 
    data1=+44 7967 123 789 
    data2=2 
    data3=null 
    photo_thumb_uri=content://com.android.contacts/contacts/2167/photo 
    lookup=731i7g4b3e9879f40515 
} 
88 { 
    _id=5192 
    contact_id=2167 
    display_name=John Doe 
    data1=+44 208 123 7890 
    data2=1 
    data3=null 
    photo_thumb_uri=content://com.android.contacts/contacts/2167/photo 
    lookup=731i7g4b3e9879f40515 
} 

样的功能

public static Observable<List<ContactVO>> fetchAllContacts(final Context context) { 
    allContactsQuery(context); 
    return ContentObservable.fromCursor(allContactsQuery(context)) 

      .map(mapToContactVO()) 

      .toList() 

      // I am stuck 
} 

private static Cursor allContactsQuery(Context context) { 
    final String[] CONTACTS = new String[]{ 
      Phone._ID,      //.....0 
      Phone.CONTACT_ID,    //.....1 
      Contacts.DISPLAY_NAME_PRIMARY, //.....2 
      Phone.NUMBER,     //.....3 
      Phone.TYPE,     //.....4 
      Phone.LABEL,     //.....5 
      Contacts.PHOTO_THUMBNAIL_URI, //.....6 
      Contacts.LOOKUP_KEY,   //.....7 
    }; 

    String SELECTION = Contacts.DISPLAY_NAME_PRIMARY + 
      "<>''" + " AND " + Contacts.IN_VISIBLE_GROUP + "=1" + 
      " AND " + Contacts.HAS_PHONE_NUMBER + "=1"; 
    final String[] SELECTION_ARGS = null; 
    final String SORT_ORDER = Contacts.SORT_KEY_PRIMARY; 

    Cursor cursor = context.getContentResolver().query(
      Phone.CONTENT_URI, 
      CONTACTS, 
      SELECTION, 
      SELECTION_ARGS, 
      SORT_ORDER); 
    return cursor; 
} 

@NonNull 
private static Func1<Cursor, ContactVO> mapToContactVO() { 
    return cursor -> { 
     int len = cursor.getCount(); 

     final ContactVO contact = new ContactVO(); 
     contact.contactId = cursor.getString(CONTACT_ID); 
     contact.displayName = cursor.getString(DISPLAY_NAME); 
     contact.photoThumbnailUri = cursor.getString(PHOTO_THUMBNAIL_URI); 
     contact.lookUp = cursor.getString(LOOK_UP); 
     contact.addData(
       new Pair<String, String>(
         cursor.getString(PHONE_TYPE), 
         cursor.getString(PHONE_NUMBER) 
       ) 
     ); 
     return contact; 
    }; 
} 

public final static int CONTACT_ID = 1; 
public final static int DISPLAY_NAME = 2; 
public final static int PHONE_NUMBER = 3; 
public final static int PHONE_TYPE = 4; 
public final static int PHONE_LABEL = 5; 
public final static int PHOTO_THUMBNAIL_URI = 6; 
public final static int LOOK_UP = 7; 
+0

为什么这么复杂?请参阅http://stackoverflow.com/a/26820544/2252830关于如何在一次迭代中获取所有电话和电子邮件 – pskink

+1

,因为我想与Rx一起玩,并想了解如何执行此操作:) – Mannox

回答

3

使用groupBy的具有相同contactId在一起,然后flatMapreduce得到记录合并记录

ContentObservable.fromCursor(allContactsQuery(context)) 
    .map(mapToContactVO()) 
    .groupBy(contact -> contact.contactId) 
    .flatMap(g -> g.reduce(mergeContacts())); 
+0

完美工作,我甚至尝试'.groupBy()',但无法弄清楚我以后需要做什么,谢谢 – Mannox

+0

很高兴听到它,没有后顾之忧 –