Novidades sobre produtos
Seletor de contatos: compartilhamento de contatos com foco na privacidade
Leitura de 4 minutos
A privacidade e o controle do usuário continuam sendo o foco da experiência do Android. Assim como o seletor de fotos tornou o compartilhamento de mídia seguro e fácil de implementar, agora estamos trazendo o mesmo nível de privacidade, simplicidade e ótima experiência do usuário para a seleção de contatos.
Um novo padrão para a privacidade de contatos
Historicamente, os aplicativos que exigiam acesso aos contatos de um usuário específico dependiam da permissão READ_CONTACTS. Embora funcional, essa abordagem geralmente concedia aos apps mais dados do que o necessário. O novo seletor de contatos do Android, introduzido no Android 17, muda essa dinâmica, fornecendo uma interface padronizada, segura e pesquisável para a seleção de contatos.
Esse recurso permite que os usuários concedam aos apps acesso apenas aos contatos específicos que escolherem, alinhando-se ao compromisso do Android com a transparência de dados e a minimização das permissões.
Como funciona
Os desenvolvedores podem integrar o seletor de contatos usando a intent Intent.ACTION_PICK_CONTACTS. Essa API atualizada oferece vários recursos avançados:
- Solicitações de dados granulares:os apps podem especificar exatamente quais campos precisam, como números de telefone ou endereços de e-mail, em vez de receber o registro de contato inteiro.
- Suporte à seleção múltipla:o seletor oferece suporte a seleções de contato únicas e múltiplas, oferecendo aos desenvolvedores mais flexibilidade para recursos como convites de grupo.
- Limites de seleção:os desenvolvedores podem definir limites personalizados para o número de contatos que um usuário pode selecionar de uma só vez.
- Acesso temporário:após a seleção, o sistema retorna um URI de sessão que fornece acesso de leitura temporário aos dados solicitados, garantindo que o acesso não persista por mais tempo do que o necessário.
- Acesso a outros perfis : ao usar essa nova intent, a interface vai permitir que os usuários selecionem conteúdo de outros perfis de usuário, como um perfil de trabalho, um perfil clonado ou um espaço particular.
- Performance otimizada: O seletor de contatos retorna um único URI que permite a consulta de resultados coletivos, eliminando a necessidade de consultar o URI de contato individual separadamente, conforme exigido por
ACTION_PICK. Essa eficiência reduz ainda mais a sobrecarga do sistema usando uma única transaçãoBinder.
Compatibilidade com versões anteriores e implementação
Para dispositivos com o Android 17 ou mais recente, o sistema atualiza automaticamente as intents ACTION_PICK legadas que especificam tipos de dados de contato para a nova interface mais segura. No entanto, para aproveitar ao máximo os recursos avançados, como a seleção múltipla, os desenvolvedores são incentivados a atualizar o código de implementação e usar o ContentResolver para consultar o URI de sessão retornado.
Integrar o seletor de contatosPara integrar o seletor de contatos, os desenvolvedores usam a intent ACTION_PICK_CONTACTS. Confira abaixo um exemplo de código que demonstra como iniciar o seletor e solicitar campos de dados específicos, como e-mail e números de telefone.
// State to hold the list of selected contacts var contacts by remember { mutableStateOf<List>(emptyList()) } // Launcher for the Contact Picker intent val pickContact = rememberLauncherForActivityResult(StartActivityForResult()) { if (it.resultCode == Activity.RESULT_OK) { val resultUri = it.data?.data ?: return@rememberLauncherForActivityResult // Process the result URI in a background thread coroutine.launch { contacts = processContactPickerResultUri(resultUri, context) } } } // Define the specific contact data fields you need val requestedFields = arrayListOf( Email.CONTENT_ITEM_TYPE, Phone.CONTENT_ITEM_TYPE, ) // Set up the intent for the Contact Picker val pickContactIntent = Intent(ACTION_PICK_CONTACTS).apply { putExtra(EXTRA_PICK_CONTACTS_SELECTION_LIMIT, 5) putStringArrayListExtra( EXTRA_PICK_CONTACTS_REQUESTED_DATA_FIELDS, requestedFields ) putExtra(EXTRA_PICK_CONTACTS_MATCH_ALL_DATA_FIELDS, false) } // Launch the picker pickContact.launch(pickContactIntent)
Depois que o usuário faz uma seleção, o app processa o resultado consultando o URI de sessão retornado para extrair as informações de contato solicitadas.
// Data class representing a parsed Contact with selected details data class Contact(val id: String, val name: String, val email: String?, val phone: String?) // Helper function to query the content resolver with the URI returned by the Contact Picker. // Parses the cursor to extract contact details such as name, email, and phone number private suspend fun processContactPickerResultUri( sessionUri: Uri, context: Context ): List<Contact> = withContext(Dispatchers.IO) { // Define the columns we want to retrieve from the ContactPicker ContentProvider val projection = arrayOf( ContactsContract.Contacts._ID, ContactsContract.Contacts.DISPLAY_NAME_PRIMARY, ContactsContract.Data.MIMETYPE, // Type of data (e.g., email or phone) ContactsContract.Data.DATA1, // The actual data (Phone number / Email string) ) val results = mutableListOf<Contact>() // Note: The Contact Picker Session Uri doesn't support custom selection & selectionArgs. context.contentResolver.query(sessionUri, projection, null, null, null)?.use { cursor -> // Get the column indices for our requested projection val contactIdIdx = cursor.getColumnIndex(ContactsContract.Contacts._ID) val mimeTypeIdx = cursor.getColumnIndex(ContactsContract.Data.MIMETYPE) val nameIdx = cursor.getColumnIndex(ContactsContract.Contacts.DISPLAY_NAME_PRIMARY) val data1Idx = cursor.getColumnIndex(ContactsContract.Data.DATA1) while (cursor.moveToNext()) { val contactId = cursor.getString(contactIdIdx) val mimeType = cursor.getString(mimeTypeIdx) val name = cursor.getString(nameIdx) ?: "" val data1 = cursor.getString(data1Idx) ?: "" // Determine if the current row represents an email or a phone number val email = if (mimeType == Email.CONTENT_ITEM_TYPE) data1 else null val phone = if (mimeType == Phone.CONTENT_ITEM_TYPE) data1 else null // Add the parsed contact to our results list results.add(Contact(contactId, name, email, phone)) } } return@withContext results }
Confira a documentação completa aqui.
Práticas recomendadas para desenvolvedores
Para oferecer a melhor experiência do usuário e manter altos padrões de segurança, recomendamos o seguinte:
- Minimização de dados:solicite apenas os campos de dados específicos (por exemplo, e-mail) de que seu app precisa.
- Persistência imediata:persista os dados selecionados imediatamente, já que o acesso ao URI de sessão é temporário.
Continuar lendo
-
Novidades sobre produtos
O seletor de fotos incorporado: uma maneira mais simples de solicitar fotos e vídeos particulares no seu app.
Roxanna Aliabadi Walker, Yacine Rezgui • Leitura de 8 minutos
-
Novidades sobre produtos
O fluxo de trabalho e as necessidades de IA de cada desenvolvedor são únicos, e é importante poder escolher como a IA ajuda no desenvolvimento. Em janeiro, apresentamos a capacidade de escolher qualquer modelo de IA local ou remoto para ativar a funcionalidade de IA no Android Studio.
Matthew Warner • Leitura de 2 minutos
-
Novidades sobre produtos
O Android Studio Panda 3 agora é estável e está pronto para uso na produção. Essa versão oferece ainda mais controle e personalização sobre seus fluxos de trabalho com tecnologia de IA, facilitando a criação de apps Android de alta qualidade.
Matt Dyor • Leitura de 3 minutos
Fique por dentro
Receba os insights mais recentes sobre o desenvolvimento do Android na sua caixa de entrada semanalmente.