Saltar al contenido principal

Política de Contactos de Google Play 2027: Guía Capacitor

La política de permisos de contactos de Google Play limitará READ_CONTACTS desde enero de 2027. Descubre qué cambia para las apps con Capacitor y cómo usar el Contact Picker.

Política de Contactos de Google Play 2027: Guía Capacitor

La política de permisos de contactos de Google Play implica que, desde el 27 de enero de 2027, las apps orientadas a Android 17 (API nivel 37) o superior solo podrán solicitar READ_CONTACTS si el Android Contact Picker no puede soportar una función principal, lo cual debe justificarse con una declaración en Play Console. Para la mayoría de las apps Capacitor que leen contactos para invitar amigos, compartir archivos o rellenar un número, la solución es usar el Contact Picker y eliminar el permiso. Esta guía explica la política y cómo hacerlo con @capgo/capacitor-contacts, y explica qué hacer si realmente necesitas la agenda de contactos completa.

Qué dice la política

Google anunció la política el 15 de abril de 2026 como parte de una serie de actualizaciones de privacidad. Puntos clave según la ayuda de Play Console:

  • Alcance: apps que apunten a Android 17 (API 37) o superior y soliciten READ_CONTACTS.
  • Regla: solo puedes solicitar READ_CONTACTS si el Android Contact Picker no es suficiente para una funcionalidad principal de tu app.
  • Declaración: las apps que mantengan el permiso deben completar una declaración en Play Console describiendo qué funciones lo requieren y por qué el picker no es suficiente.
  • Cronograma: Play Console empezó a mostrar avisos a las apps que declaran READ_CONTACTS en septiembre de 2026. El cumplimiento es obligatorio el 27 de enero de 2027. Google menciona una extensión de 30 días en Play Console.
  • Exenciones: las apps privadas y de gestión de dispositivos empresariales quedan fuera del alcance.
  • Datos: los datos de contactos son personales y sensibles según la política de User Data; no puedes publicar datos de contactos no públicos sin autorización de las personas implicadas.

Casos de uso que pueden mantener READ_CONTACTS

Google enumera funciones principales como apps de gestión de contactos, marcadores y SMS, historial y filtrado de llamadas, CRM, accesibilidad, asistentes personales, matching de amigos, backup y restore, y teclados o autocomplete.

Casos de uso que deben cambiar al picker

Invitar o referir a alguien, compartir archivos, colaborar o elegir un contacto para enviar dinero. Si esa es la razón por la que tu app lee contactos, la declaración será rechazada. Usa el picker.

Qué cambia en Android 17

Android 17 incluye un nuevo Contact Picker del sistema. Las apps reciben un URI de sesión temporal de solo lectura que solo expone los contactos y campos seleccionados por el usuario, sin necesidad de permisos. Para apps que apunten a Android 17, el sistema actualiza automáticamente el clásico Intent.ACTION_PICK contacts intent a este nuevo picker. Las apps también pueden solicitar campos de datos específicos (teléfono, email, dirección postal) y selección múltiple mediante una nueva acción de intent.

En versiones antiguas de Android, seleccionar una fila de datos específica (por ejemplo, un número de teléfono) mediante el selector de contactos siempre devolvía una URI que la app podía leer sin READ_CONTACTS. Eso es lo que permite un flujo sin permisos en cualquier versión de Android.

Por qué “pick a contact” solía requerir READ_CONTACTS

Muchos plugins de Capacitor implementan “pick contact” abriendo el selector para un contacto completo y luego consultando la agenda para obtener sus números y emails. Esa segunda consulta requiere READ_CONTACTS. Así, incluso las apps que solo querían un número de teléfono terminaban declarando el permiso, que es exactamente lo que la política busca evitar.

La solución es pedir al selector el campo específico que necesitas, para que la URI resultante ya contenga los datos.

Selecciona teléfono, email o dirección sin READ_CONTACTS

@capgo/capacitor-contacts añadió una property opción en la versión 8.1.0. Al activarla, Android abre el selector sobre la tabla de teléfonos, emails o direcciones postales y lee la fila seleccionada desde la URI concedida. No se requiere READ_CONTACTS en ninguna versión de Android. En iOS, el selector del sistema nunca necesita permisos de contactos.

bun add @capgo/capacitor-contacts
bunx cap sync
import { CapacitorContacts, ContactProperty } from '@capgo/capacitor-contacts';

export async function pickPhoneNumber(): Promise<string | undefined> {
  const { contacts } = await CapacitorContacts.pickContacts({
    property: ContactProperty.PhoneNumber,
  });
  const picked = contacts[0];
  return picked?.phoneNumbers?.[0]?.value;
}

export async function pickEmail(): Promise<string | undefined> {
  const { contacts } = await CapacitorContacts.pickContacts({
    property: ContactProperty.EmailAddress,
  });
  return contacts[0]?.emailAddresses?.[0]?.value;
}

Con property, el resultado contiene el contacto id, displayName y solo la propiedad seleccionada. Se ignora la selección múltiple; la selección de propiedades siempre devuelve un único valor. Si el usuario cancela, verifica si el array está vacío.

El plugin no declara READ_CONTACTS o WRITE_CONTACTS en su propio manifiesto, así que si solo usas la selección de propiedades, tu manifiesto combinado se mantiene limpio.

Cuando aún necesites READ_CONTACTS

Estos métodos del plugin leen la agenda de contactos y siguen requiriendo el permiso:

  • pickContacts() o pickContact() sin property, cuando quieras el registro de contacto completo
  • getContacts(), getContactById(), countContacts()
  • getGroups(), getGroupById(), getAccounts()

Si tu app es un CRM, una herramienta de backup o una función de búsqueda de amigos, es un uso principal legítimo. Añade el permiso tú mismo y presenta la declaración:

<!-- android/app/src/main/AndroidManifest.xml -->
<uses-permission android:name="android.permission.READ_CONTACTS" />
import { CapacitorContacts } from '@capgo/capacitor-contacts';

const perm = await CapacitorContacts.requestPermissions({ permissions: ['readContacts'] });
if (perm.readContacts === 'granted' || perm.readContacts === 'limited') {
  const { contacts } = await CapacitorContacts.getContacts({
    fields: ['displayName', 'phoneNumbers'],
    limit: 200,
    offset: 0,
  });
  console.log(contacts.length);
}

La política se enfoca en READ_CONTACTS. Escribir contactos con WRITE_CONTACTS (para createContact, updateContactById, deleteContactById) no es el objeto de esta política; añádela solo si usas esos métodos.

Plan de migración para una app Capacitor

  1. Audita el manifest fusionado. Genera tu release y abre android/app/build/intermediates/merged_manifest/ (o usa la pestaña Merged Manifest de Android Studio). Algunos plugins añaden READ_CONTACTS sin que te des cuenta. Si un plugin la añade y no la necesitas, elimínala con tools:node="remove":

    <manifest xmlns:android="http://schemas.android.com/apk/res/android"
        xmlns:tools="http://schemas.android.com/tools">
        <uses-permission android:name="android.permission.READ_CONTACTS" tools:node="remove" />
    </manifest>
  2. Lista cada lugar donde accedas a contactos. Para cada uno, decide: un picker con una propiedad o la agenda completa.

  3. Reemplaza los flujos de invitación y compartir con pickContacts({ property }).

  4. Mantén el permiso solo para funciones core, y prepara el texto de la declaración: qué funcionalidad es, por qué el picker no es suficiente y un video si la función es difícil de encontrar.

  5. Lanza un Native Build. Los cambios en el Manifest y en los plugins requieren una nueva versión en Play. Si usas CI, Capgo Build puedes generar builds de Android firmados, y el generador de Android keystore te ayuda si estás configurando la firma por primera vez.

  6. Lanza cambios de UI vía OTA. Una vez que el nuevo plugin nativo esté activo, los ajustes de texto y flujo del picker pueden enviarse mediante Live Updates de Capgo.

Migración desde otro plugin de contactos

Si usas @capacitor-community/contacts (8.0.0 al momento de escribir), su Android pickContact solicita el grupo de permisos de contactos antes de abrir el selector y luego lee el contacto completo de la agenda. No tiene modo de propiedad. Los nombres de los métodos también varían (getContact frente a getContactById, objetos de proyección frente a un fields array). Nuestra comparativa entre el plugin de contactos de la comunidad y el plugin Capgo mapea cada llamada.

Si aún usas un plugin de contactos de Cordova dentro de Capacitor, ahora es un buen momento para reemplazarlo. Mira migrar de Cordova a Capacitor.

Solución de problemas

El selector devuelve un contacto sin número de teléfono. Llamaste a pickContacts() sin property y la app no tiene READ_CONTACTS. Solo id y displayName (y en Android 17+, campos permitidos por el picker) se recuperan. Añade property.

Play Console sigue diciendo que la app declara READ_CONTACTS. Una librería lo añade. Revisa el manifest fusionado y elimínalo con tools:node="remove". También revisa versiones antiguas en otros tracks; cada artefacto activo cuenta.

Declaración rechazada. Invitaciones, referidos y compartir se listan como casos para el picker. Rediseña la función o explica claramente por qué la lista completa es esencial (por ejemplo, un matching de amigos que consulta toda la agenda).

iOS solicita permiso de contactos. Llamas a un método que lee la agenda. El picker nunca lo necesita. Elimina NSContactsUsageDescription si solo eliges.

Fechas clave

Fecha Qué sucede
15 de abril de 2026 Anuncio de la política
Septiembre de 2026 Play Console solicita a las apps que declaren READ_CONTACTS presentar una declaración
27 de enero de 2027 Cumplimiento obligatorio para apps con Android 17 (API 37) o superior

Consulta la ayuda de Play Console sobre la política antes de enviar; Google puede cambiar plazos y términos.

Live Updates para apps de Capacitor

Si hay un bug en la capa web, publica el fix con Capgo en lugar de esperar días a la aprobación de la app store. Los usuarios reciben la actualización en segundo plano mientras los cambios nativos siguen el proceso de revisión normal.

Lo último de nuestro blog

Capgo te da los mejores insights para crear una app móvil realmente profesional.