Telephony.Sms.Inbox.PERSON utiliza Contacts.People._ID obsoletos
Premio Bounty – La recompensa se otorgará a una respuesta que obtiene de un valor poblado de Telephony.Sms.Inbox.PERSON
, al Contact
asociado usando sólo las tablas ContractsContact
.
Desde que comencé la recompensa, he resuelto cómo hacer esto, pero pensé que dejaría la recompensa abierta para darle a alguien una oportunidad de ganarla, antes de publicar la solución.
- Android .setColor para Icono grande
- Longitud máxima del método PutExtra de Intención? (Cierre de la fuerza)
- ActionBar con el icono y el texto en modo retrato
- Cómo solucionar NetworkonMainThreadException en Android?
- Android: ¿Cómo ignorar o desactivar savedInstanceState?
Estoy leyendo mensajes SMS de la manera estándar en mi aplicación:
final String[] projection = {Telephony.Sms.Inbox.BODY, Telephony.Sms.Inbox.ADDRESS, Telephony.Sms.Inbox.READ, Telephony.Sms.Inbox.DATE, Telephony.Sms.Inbox.PERSON}; final Cursor cursor = ctx.getContentResolver().query(Telephony.Sms.Inbox.CONTENT_URI, projection, null, null, Telephony.Sms.Inbox.DEFAULT_SORT_ORDER);
Cuando se rellena, el id devuelto desde el índice Telephony.Sms.Inbox.PERSON
relaciona con el identificador de la Contacts.People._ID
obsoleto y se puede utilizar para consultar información de contacto adicional de la siguiente manera:
final String[] projection = {Contacts.People.DISPLAY_NAME}; final String[] selectionArgs = {contactId}; final Cursor cursor = ctx.getContentResolver().query(Contacts.People.CONTENT_URI, projection, Contacts.People._ID + " = ?", selectionArgs, null);
¿Por qué la relativamente nueva API de telefonía utiliza tablas obsoletas , en lugar de ContactsContract ?
La documentación de Telephony.Sms.Inbox.PERSON establece:
Tipo: INTEGER (referencia al elemento en el contenido: // contactos / personas)
He intentado sin éxito (pero no es de esperar?) Para encontrar una asignación a la identificación en cualquiera de los campos de ID ContactsContract
, por lo que estoy dejando tener que usar APIs obsoletas con el fin de resolver las consultas que tengo que realizar rápidamente.
Tales consultas incluyen la búsqueda de mensajes por un contacto en particular, para lo cual sólo tengo el nombre. El contacto puede tener varios números, que pueden no estar en el formato correcto para coincidir con las entradas de Telephony.Sms.Inbox.ADDRESS
…..
La solución de usar Telephony.Sms.Inbox.ADDRESS
y ContactsContract.PhoneLookup no es el fin del mundo cuando va desde el número al contacto, pero sigo sintiendo que debo estar perdiendo algo aquí ?
Este es el proceso que estoy usando para obtener los mensajes de 'Joe Bloggs'.
1) Consulta la tabla ContactsContract
para confirmar que existe un contacto con el nombre de Joe Bloggs en el dispositivo o para obtener una coincidencia cercana si el contacto aparece en la lista de ' Blogs de Joe'.
2) Utilizando el nombre confirmado, consulta la tabla de Contact.People
obsoleta para obtener todos los identificadores asociados para el contacto de la siguiente manera:
final String selection = Contacts.People.DISPLAY_NAME + " LIKE ?"; final String[] projection = {Contacts.People.DISPLAY_NAME, Contacts.People._ID}; final String[] selectionArgs = {contactName}; final Cursor cursor = ctx.getContentResolver().query(Contacts.People.CONTENT_URI, projection, selection, selectionArgs, null);
3) Usando la lista de identificadores de contacto obsoletos, consulta la tabla de mensajes de la siguiente manera:
final String[] referredArgs = new String[contactIdArray.size()]; for (int i = 0; i < contactIdArray.size(); i++) { referredArgs[i] = contactIdArray.get(i); } final String referredSelection = Telephony.Sms.Inbox.PERSON + " IN " + "(" + TextUtils.join(",", referredArgs) + ")"; final String[] projection = {Telephony.Sms.Inbox.BODY, Telephony.Sms.Inbox.ADDRESS, Telephony.Sms.Inbox.READ, Telephony.Sms.Inbox.DATE, Telephony.Sms.Inbox.PERSON}; final Cursor cursor = ctx.getContentResolver().query(Telephony.Sms.Inbox.CONTENT_URI, projection, referredSelection, null, Telephony.Sms.Inbox.DEFAULT_SORT_ORDER);
Espero que alguien me diga que voy alrededor de las casas aquí y hay una solución más obvia utilizando las API actuales. No considero iterating la tabla entera del mensaje usando ContactsContract.PhoneLookup
una solución optimizada.
Gracias por adelantado.
- Android: consumo de memoria constante / dumpGfxInfo ()
- Actividad vacía de Android y actividad en blanco
- Comunicación con Java socket de Android con Socket.IO
- Escopetas en Dagger 2
- Project.properties en el proyecto android
- EXCEPCIÓN FATAL: main java.lang.RuntimeException: El contenido tiene vista con el atributo id 'android.R.id.list' que no es una clase ListView
- Instalación del complemento ADT en Eclipse kepler
- Estados dibujables con colores (no dibujables)
No usaría el campo Telephony.Sms.Inbox.PERSON
, y definitivamente no haría una consulta a las People
desaprobadas apis si yo fuera tú. Las People
apis habían sido obsoletas durante tanto tiempo que no se puede contar con todos los dispositivos de nuestro allí para apoyar adecuadamente más.
La primera cosa que usted necesita entender es que no hay un acoplamiento uno-a-uno entre los sms y los contactos. Un SMS puede provenir de un número de teléfono sin contacto, un solo contacto, múltiples contactos, una mezcla de contactos y no contactos, identificaciones alfanuméricas e incluso otras opciones más raras.
A continuación, debe leer cuidadosamente el código de stock y cómo maneja un correctamente llamado "Recipient ID" que puede obtener de la colección de SMS, hay una colección llamada canonical-addresses
(o canonical-address
) que sirve como una correlación entre un Número de teléfono (o una lista de teléfonos separados por comas) y un identificador de destinatario. El código realiza una sola consulta al iniciar para almacenar en caché toda la tabla en memoria y, a continuación, la utiliza para correlacionar entre los teléfonos y los identificadores de destinatarios.
Aquí está la clase de mapeo
¿Por qué la relativamente nueva API de telefonía utiliza tablas obsoletas, en lugar de ContactsContract?
Lo que usted se está refiriendo no es nuevo. En Telephony.java , verá que se basa en el content://sms
existente content://sms
proveedor de content://sms
:
public static final class Inbox implements BaseColumns, TextBasedSmsColumns { /** * The {@code content://} style URL for this table. */ public static final Uri CONTENT_URI = Uri.parse("content://sms/inbox");
Ya estaba allí en Donut (y probablemente antes, pero no lo hice).
Lo nuevo en Kitkat es la posibilidad de cambiar la aplicación de SMS .
No entiendo su preocupación correctamente, pero estoy trabajando en un proyecto similar, aquí está el código básico, y las columnas básicas, importantes para buscar y mostrar un mensaje:
ContentResolver contentResolver = getContentResolver(); final String[] projection = new String[]{"*"}; Cursor SMSL = contentResolver.query(Telephony.Sms.CONTENT_URI, projection, null, null, "date ASC"); int msgscount = SMSL.getCount(); if (msgscount>0) { msgs = new String[SMSL.getCount()][msgs_column_count]; int i = 0; while (SMSL.moveToNext()) { progress.setProgress(i); msgs[i][0] = SMSL.getString(SMSL.getColumnIndex("address")); msgs[i][1] = SMSL.getString(SMSL.getColumnIndex("date_sent")); msgs[i][2] = SMSL.getString(SMSL.getColumnIndex("date")); msgs[i][3] = SMSL.getString(SMSL.getColumnIndex("type")); msgs[i][4] = SMSL.getString(SMSL.getColumnIndex("body")); msgs[i][5] = SMSL.getString(SMSL.getColumnIndex("read")); if (SMSL.getString(SMSL.getColumnIndex("service_center")) != null){ msgs[i][6] = SMSL.getString(SMSL.getColumnIndex("service_center")); }else{ msgs[i][6] = ""; } i++; } SMSL.close(); }else{ msgs = new String[0][0]; Toast.makeText(getApplicationContext(),"No messages found!",Toast.LENGTH_LONG).show(); }
Si desea ayuda con esto o recoja mensajes, avíseme.
- Robolectric inflar vistas personalizadas para pruebas
- ¿Cómo puedo mejorar la calidad de los datos de depuración cuando mi aplicación se bloquea en estado salvaje?