Android联系人在单个数据库查询中显示姓名和电话号码?
我试图从本地数据库中获取显示名称和电话号码(任意或全部)的联系人列表。 有很多方法可以通过查询手机的数据库来获取这些信息,但这会带来相当大的开销。
这是我一直在处理的查询,但结果是
Uri uri = ContactsContract.Contacts.CONTENT_URI; String[] projection = new String[] { ContactsContract.Contacts._ID, ContactsContract.Contacts.DISPLAY_NAME, ContactsContract.CommonDataKinds.Phone.NUMBER}; String selection = ContactsContract.Contacts.HAS_PHONE_NUMBER + " = '1'"; String[] selectionArgs = null; String sortOrder = ContactsContract.Contacts.DISPLAY_NAME + " COLLATE LOCALIZED ASC"; Cursor people = getContentResolver().query(uri, projection, selection, selectionArgs, sortOrder); int index_id = people.getColumnIndex(ContactsContract.Contacts._ID); int indexName = people.getColumnIndex(ContactsContract.Contacts.DISPLAY_NAME); int indexNumber = people.getColumnIndex(ContactsContract.CommonDataKinds.Phone.NUMBER); people.moveToFirst(); do { String _id = people.getString(index_id); String name = people.getString(indexName); String number = people.getString(indexNumber); // Do work... } while (people.moveToNext());
这是由此产生的错误。
E/AndroidRuntime(21549): Caused by: java.lang.IllegalArgumentException: Invalid column data1 E/AndroidRuntime(21549): at android.database.DatabaseUtils.readExceptionFromParcel(DatabaseUtils.java:144) E/AndroidRuntime(21549): at android.database.DatabaseUtils.readExceptionFromParcel(DatabaseUtils.java:114) E/AndroidRuntime(21549): at android.content.ContentProviderProxy.bulkQueryInternal(ContentProviderNative.java:372) E/AndroidRuntime(21549): at android.content.ContentProviderProxy.query(ContentProviderNative.java:408) E/AndroidRuntime(21549): at android.content.ContentResolver.query(ContentResolver.java:264)
思考? 我相信可能需要一个连接来获取单个查询中的所有列。
试试这个代码:
Uri uri = ContactsContract.CommonDataKinds.Phone.CONTENT_URI; String[] projection = new String[] {ContactsContract.CommonDataKinds.Phone.DISPLAY_NAME, ContactsContract.CommonDataKinds.Phone.NUMBER}; Cursor people = getContentResolver().query(uri, projection, null, null, null); int indexName = people.getColumnIndex(ContactsContract.CommonDataKinds.Phone.DISPLAY_NAME); int indexNumber = people.getColumnIndex(ContactsContract.CommonDataKinds.Phone.NUMBER); if(people.moveToFirst()) { do { String name = people.getString(indexName); String number = people.getString(indexNumber); // Do work... } while (people.moveToNext()); }
联系人API非常棘手,并有几个隐式联接 。
如果您可以负担得起,请阅读ContactContract和ContactsProvider2 。
你想要什么? 桌子是这样链接的:
- 联系人1 – *原始联系人
- 原始联系人1 – *电话号码(数据表)
API的工作原理是这样的:您select最底部的元素(电话号码)和隐式join到最上面的元素(联系人)。
你想使用PHONE URI的情况下(ContactsProvider2 / 4377行)。 这应该select所有电话号码并join联系人。
将PHONE uri与一些UI魔术(用于分组)联系起来,请求DISPLAY_NAME和PHONE号码(DATA1?),你应该可以解决这个问题。
电话号码存储在自己的表中,需要单独查询。 要查询电话号码表,请使用存储在SDKvariablesContactsContract.CommonDataKinds.Phone.CONTENT_URI中的URI。 使用WHERE条件获取指定联系人的电话号码。
private String displayName(Uri contactUri) { HashSet detail = ContactDetail.getInstance().getContactArray(); Log.d("ITEM", contactUri.toString()); String[] projection = new String[]{ContactsContract.CommonDataKinds.Phone.DISPLAY_NAME, ContactsContract.CommonDataKinds.Phone.NUMBER}; Cursor queryCursor = getActivity().getContentResolver() .query(contactUri, null, null, null, null); queryCursor.moveToFirst(); String name = queryCursor.getString(queryCursor.getColumnIndex("display_name")); String id = queryCursor.getString( queryCursor.getColumnIndex(ContactsContract.Contacts._ID)); if (Integer.parseInt(queryCursor.getString(queryCursor.getColumnIndex(ContactsContract.Contacts.HAS_PHONE_NUMBER))) > 0) { Cursor pCur = getActivity().getContentResolver().query( ContactsContract.CommonDataKinds.Phone.CONTENT_URI, null, ContactsContract.CommonDataKinds.Phone.CONTACT_ID + " = ?", new String[]{id}, null); while (pCur.moveToNext()) { String number = pCur.getString(pCur.getColumnIndex("data1")); Log.d("Contact Name: ", number); } pCur.close(); } return name; }
对Android联系人SQLite数据库执行第二个查询。 电话号码是根据存储在ContactsContract.CommonDataKinds.Phone.CONTENT_URI中的URI来查询的。 联系人ID作为ContactsContract.CommonDataKinds.Phone.CONTACT_ID存储在电话表中,WHERE子句用于限制返回的数据。