¿Los contactos de Android muestran el nombre y número (s) de teléfono en una consulta de base de datos única?

Estoy tratando de obtener una lista de contactos de la base de datos nativa con su nombre para mostrar y número de teléfono (alguno o todos). Hay muchos métodos para obtener esta información con varias consultas a la base de datos del teléfono, pero esto introduce una sobrecarga considerable.

Aquí está la consulta en la que he estado trabajando, pero resulta en

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

Y aquí está el error resultante.

 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) 

¿Pensamientos? Creo que se puede necesitar una unión para obtener todas las columnas en una sola consulta.

Prueba este código:

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

La API de contactos es extremadamente complicada y tiene varias combinaciones implícitas .

Lea ContactContract y ContactsProvider2 si puede permitirse el tiempo.

¿Qué deseas? Las tablas están encadenadas así:

  • Contacto 1 – * Contacto sin procesar
  • Contacto sin formato 1 – * Número de teléfono (tabla de datos)

La API funciona así: selecciona el elemento inferior (un número de teléfono) y se une implícitamente al elemento superior (contacto).

Desea utilizar el caso de URI de teléfono (ContactsProvider2 / line 4377). Esto debería seleccionar todos los números de teléfono y unirse al contacto.

Combina el uri PHONE con algo de magia UI (para agrupar), solicita el DISPLAY_NAME y el número de teléfono (DATA1?) Y deberías ser capaz de resolver el problema.

Los números de teléfono se almacenan en su propia tabla y deben consultarse por separado. Para consultar la tabla de números telefónicos, utilice el URI almacenado en la variable SDK ContactsContract.CommonDataKinds.Phone.CONTENT_URI. Use un condicional WHERE para obtener los números de teléfono del contacto especificado.

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

Realice una segunda consulta en la base de datos SQLite de los contactos de Android. Los números de teléfono se consultan contra el URI almacenado en ContactsContract.CommonDataKinds.Phone.CONTENT_URI. El ID de contacto se almacena en la tabla del teléfono como ContactsContract.CommonDataKinds.Phone.CONTACT_ID y la cláusula WHERE se usa para limitar los datos devueltos.