2009-02-09 21 views
19

trato el código siguiente para quitar el contacto con un número especificado:Cómo eliminar un contacto mediante programación en Android

private void removeContact(Context context, String phone) { 
    //context.getContentResolver().delete(Contacts.Phones.CONTENT_URI, phone, null); 
    context.getContentResolver().delete(Contacts.Phones.CONTENT_URI, 
      Contacts.PhonesColumns.NUMBER+"=?", new String[] {phone}); 
} 

pero me da esta excepción:

java.lang.UnsupportedOperationException: Cannot delete that URL: content://contacts/phones 
    at android.database.DatabaseUtils.readExceptionFromParcel(DatabaseUtils.java:130) 
    at android.database.DatabaseUtils.readExceptionFromParcel(DatabaseUtils.java:110) 
    at android.content.ContentProviderProxy.delete(ContentProviderNative.java:362) 
    at android.content.ContentResolver.delete(ContentResolver.java:386) 

¿Puede por favor cómo decirle para arreglar mi problema?

Gracias.

Respuesta

9

¿Tiene los permisos apropiados declarados en su manifiesto?

Tendrá etiquetas de permisos utiliza el android.permission.READ_CONTACTS y android.permission.WRITE_CONTACTS antes de Android que le permitirá meterse con el proveedor de contactos:

<manifest xmlns:android="http://schemas.android.com/apk/res/android" 
      package="com.android.app.myapp" > 

    <uses-permission android:name="android.permission.READ_CONTACTS" /> 
    <uses-permission android:name="android.permission.WRITE_CONTACTS" /> 

</manifest> 
+1

problemas de permisos son lo que me matan a la mayoría. Hubo una vez que fui una semana tratando de descubrir por qué mi código de vibración seguía cayendo hasta que descubrí que necesitabas un permiso para vibrar ... – num1

7

Una respuesta tardía, pero tal vez le ayuda de todos modos:

Si mira el source code of ContactsProvider y busca "matcher.addURI" (no te sorprendas si deja de cargar en el medio ... se reanuda la carga después de un minuto o dos), entonces ves que tiene un conjunto finito de Esquemas de URI que puede manejar. Tiene un controlador para "teléfonos/#" pero no para "teléfonos", que es lo que necesitaría.

Esto significa que simplemente no hay un código para eliminar todos los números de teléfono, primero debe obtener los ID de todos los números y luego eliminar cada uno a la vez. Por supuesto, esto requiere mucho más recursos de CPU y memoria, pero al menos funciona.

El siguiente código elimina un número específico. Tenga en cuenta que no probé este código, pero es 90% idéntico al código que uso para eliminar todos los números de una persona determinada, que necesita un tratamiento similar porque Android no puede eliminar "personas/#/teléfonos", pero " personas/#/teléfonos/# "

EDITAR:Me acabo de dar cuenta de que he entendido mal la pregunta. Pensé que le gustaría eliminar el número de teléfono, que mi código hace. Pero ahora veo que quieres eliminar el contactante.

private void deletePhoneNumber(Uri peopleUri, String numberToDelete) { 

    Uri.Builder builder = peopleUri.buildUpon(); 
    builder.appendEncodedPath(People.Phones.CONTENT_DIRECTORY); 
    Uri phoneNumbersUri = builder.build(); 


    String[] mPhoneNumberProjection = { People.Phones._ID, People.Phones.NUMBER }; 
    Cursor cur = resolver.query(phoneNumbersUri, mPhoneNumberProjection, 
      null, null, null); 

    ArrayList<String> idsToDelete = new ArrayList<String>(); 

    if (cur.moveToFirst()) { 
     final int colId = cur.getColumnIndex(People.Phones._ID); 
     final int colNumber = cur.getColumnIndex(People.Phones.NUMBER); 

     do { 
      String id = cur.getString(colId); 
      String number = cur.getString(colNumber); 
      if(number.equals(numberToDelete)) 
       idsToDelete.add(id); 
     } while (cur.moveToNext()); 
    } 
    cur.close(); 

    for (String id : idsToDelete) { 
     builder.encodedPath(People.Phones.CONTENT_DIRECTORY + "/" + id); 
     phoneNumbersUri = builder.build(); 
     resolver.delete(phoneNumbersUri, "1 = 1", null); 
    } 
} 

El código es un poco prolijo, ya que hace dos suposiciones:

  • podría haber múltiples líneas de eliminar (por ejemplo, el número se almacena en dos ocasiones)
  • que podría no ser seguro para llegar un cursor, borrar una fila, y seguir usando el cursor

Ambos supuestos son manejados por primera almacenar el idsToDelete en un ArrayList y luego eliminar.

También puede considerar para normalizar el número que busca y, en su lugar, utilice la columna People.Phones.NUMBER_KEY, porque contiene los números en forma normalizada.

+0

Tal vez fui yo el estúpido, pero me tomó un tiempo darme cuenta de que una llamada para esta función debe ser como deletePhoneNumber (Contacts.CONTENT_URI, "555"); trabajar. De lo contrario, una gran respuesta, ¡gracias! – pgsandstrom

19

Para eliminar todos los contactos utilizan el siguiente código:

ContentResolver cr = getContentResolver(); 
    Cursor cur = cr.query(ContactsContract.Contacts.CONTENT_URI, 
      null, null, null, null); 
    while (cur.moveToNext()) { 
     try{ 
      String lookupKey = cur.getString(cur.getColumnIndex(ContactsContract.Contacts.LOOKUP_KEY)); 
      Uri uri = Uri.withAppendedPath(ContactsContract.Contacts.CONTENT_LOOKUP_URI, lookupKey); 
      System.out.println("The uri is " + uri.toString()); 
      cr.delete(uri, null, null); 
     } 
     catch(Exception e) 
     { 
      System.out.println(e.getStackTrace()); 
     } 
    } 

Para eliminar cualquier contacto específico modificar la consulta

cr.delete(uri, null, null); 

espero que ayude!

+0

Sí, está funcionando, pero el problema es que no está eliminando el contacto de la tabla 'datos' de la base de datos contact2.db (base de datos android). – Vivek

+1

modificar la consulta a qué? – CHarris

+0

'java.lang.IllegalStateException: No se pudo leer la fila 1323, col 16 de CursorWindow. Asegúrese de que el Cursor esté inicializado correctamente antes de acceder a los datos del mismo. Después de cada 1323 eliminación de contactos, estoy tratando de eliminar aproximadamente 100k contactos del dispositivo. – Omkar

15

Esto es todo lo que necesitamos. Para eliminar contacto con número de teléfono y nombre dado

public static boolean deleteContact(Context ctx, String phone, String name) { 
    Uri contactUri = Uri.withAppendedPath(PhoneLookup.CONTENT_FILTER_URI, Uri.encode(phone)); 
    Cursor cur = ctx.getContentResolver().query(contactUri, null, null, null, null); 
    try { 
     if (cur.moveToFirst()) { 
      do { 
       if (cur.getString(cur.getColumnIndex(PhoneLookup.DISPLAY_NAME)).equalsIgnoreCase(name)) { 
        String lookupKey = cur.getString(cur.getColumnIndex(ContactsContract.Contacts.LOOKUP_KEY)); 
        Uri uri = Uri.withAppendedPath(ContactsContract.Contacts.CONTENT_LOOKUP_URI, lookupKey); 
        ctx.getContentResolver().delete(uri, null, null); 
        return true; 
       } 

      } while (cur.moveToNext()); 
     } 

    } catch (Exception e) { 
     System.out.println(e.getStackTrace()); 
    } finally { 
     cur.close(); 
    } 
    return false; 
} 

y recordar a añadir lectura/escritura permiso de contacto

<uses-permission android:name="android.permission.READ_CONTACTS" /> 
<uses-permission android:name="android.permission.WRITE_CONTACTS" /> 
+0

Si el contacto no tiene ningún teléfono, no puede eliminarlo con esta función. – AliSh

+0

¿Hay alguna manera de que esto se pueda modificar para eliminar solo el contacto basado en el nombre? – TW80000

0
ContentResolver cr = getContentResolver(); 
Cursor cur = cr.query(ContactsContract.Contacts.CONTENT_URI, 
     null, null, null, null); 
while (cur.moveToNext()) { 
    try{ 
     String lookupKey = cur.getString(cur.getColumnIndex(ContactsContract.Contacts.LOOKUP_KEY)); 
     Uri uri = Uri.withAppendedPath(ContactsContract.Contacts.CONTENT_LOOKUP_URI, lookupKey); 
     System.out.println("The uri is " + uri.toString()); 
     cr.delete(uri, null, null); 
    } 
    catch(Exception e) 
    { 
     System.out.println(e.getStackTrace()); 
    } 
} 

he utilizado este código para eliminar contacts.It va a eliminar contactos sim así como los contactos del teléfono o solo los contactos almacenados en el almacenamiento del teléfono.

+0

gracias por compartir. Por cierto, olvidaste cerrar el cursor – user1546570

+1

Ten cuidado con el código anterior. En su forma actual, creo que eliminará todos los contactos en su teléfono. – CHarris

+0

¡Este código acaba de borrar todo de mis contactos telefónicos! ¡Ten cuidado muchachos! – JPerk

0

Una mejor manera de eliminar un contacto es mediante la eliminación de todos los contactos primas que utilizan Contact ID

final ArrayList ops = new ArrayList(); 
    final ContentResolver cr = getContentResolver(); 
    ops.add(ContentProviderOperation 
      .newDelete(ContactsContract.RawContacts.CONTENT_URI) 
      .withSelection(
        ContactsContract.RawContacts.CONTACT_ID 
          + " = ?", 
        new String[] { allId.get(i) }) 
      .build()); 

     try { 
      cr.applyBatch(ContactsContract.AUTHORITY, ops); 
      int deletecontact = serialList.get(allId.get(i)); 

     } catch (RemoteException e) { 
      e.printStackTrace(); 
     } catch (OperationApplicationException e) { 
      e.printStackTrace(); 
     } 
     //background_process(); 
     ops.clear(); 
    } 

y no se olvide de agregar permisos

 <uses-permission android:name="android.permission.READ_CONTACTS"/> 
     <uses-permission android:name="android.permission.WRITE_CONTACTS"/> 
Cuestiones relacionadas