1

我觉得我可能在 ContactsContract API 中遗漏了一些东西。在我的应用程序中,我有几个 SQLite 表,其中引用了联系人或组(来自 ContactsContract API)。我这样做了,而不是用我自己的联系人和组表重新发明轮子。

然而,让查询一起工作变成了一场噩梦。假设我想使用来自特定组的所有联系人对我的 SQL 表执行操作。我必须查询 ContactsContract 以获取组成员的contact_id,将这些contact_id 加入字符串,然后将该字符串放入单独的查询中。(或者在循环中使用 SQL 查询。)

这是如此糟糕的 SQL,我觉得我一定做错了什么,但我找不到任何其他方法的参考。我即将维护自己的联系人列表。有任何想法吗?

4

1 回答 1

3

不,你没有处于任何错误的边缘。Contacts ContentProvider(以及我见过的几乎所有 ContentProvider)都与传统的 SQL 智慧相矛盾,哦,好吧。

如果要从多种类型的 ContactsContracts.CommonDataKinds 中获取数据,则需要检测您所在行的 mime-type 并确定它是哪种实体(或进行额外查询,我的首选解决方案是这一切都在一个查询中......)

屏住呼吸,这是我编写的一些代码示例。您应该能够看到不同的行如何可以是不同类型的实体,因此它们的通用列可以保存不同类型的数据,这就是我们使用 CommonDataKinds.* 类在上下文中引用它们的原因:

public class ContactsHelper {


    private static String[] PROJECTION = {
        Data.CONTACT_ID,
        Data.MIMETYPE,
        StructuredName.GIVEN_NAME,
        StructuredName.FAMILY_NAME,
        StructuredName.DISPLAY_NAME,
        StructuredName.MIDDLE_NAME,
        Email.ADDRESS
    };

    public static void readContacts(Context context) {
        ContentResolver resolver = context.getContentResolver();
        Uri contactsUri = ContactsContract.Data.CONTENT_URI;

        SQLiteDatabase conn = DatabaseHelper.openDatabase(context);

        Cursor cursor = resolver.query(contactsUri, PROJECTION, null, null, null);

        int idxContactId = cursor.getColumnIndex(Data.CONTACT_ID);
        int idxMimeType = cursor.getColumnIndex(Data.MIMETYPE);
        int idxGivenName = cursor.getColumnIndex(StructuredName.GIVEN_NAME);
        int idxFamilyName = cursor.getColumnIndex(StructuredName.FAMILY_NAME);
        int idxDisplayName = cursor.getColumnIndex(StructuredName.DISPLAY_NAME);
        int idxMiddleName = cursor.getColumnIndex(StructuredName.MIDDLE_NAME);
        int idxEmail = cursor.getColumnIndex(Email.ADDRESS);

        for (cursor.moveToFirst(); ! cursor.isAfterLast(); cursor.moveToNext()) {
            String mimeType = cursor.getString(idxMimeType);

            Integer contactId = cursor.getInt(idxContactId);

            if (StructuredName.CONTENT_ITEM_TYPE.equals(mimeType)) {
                String firstName = cursor.getString(idxGivenName);
                String middleName = cursor.getString(idxMiddleName);
                String lastName = cursor.getString(idxFamilyName);
                String displayName = cursor.getString(idxDisplayName);

                            Log.d(TAG, all the values ^^^);

            }


            if (Email.CONTENT_ITEM_TYPE.equals(mimeType)) {
                String emailName = cursor.getString(idxEmail);
                Log.d(TAG, all the values ^^^);
            }
        }

        DatabaseHelper.closeDatabase(conn);
        cursor.close();
    }   
}

是的,这个完全严肃的解决方案确实使用了字符串比较。如果有更好的方法,请告诉我!

于 2012-06-16T07:25:27.403 回答