Questa guida per gli sviluppatori spiega come migliorare la tua app per usare i contatti i dati del profilo di lavoro. Se non hai utilizzato le API dei contatti di Android in precedenza, leggi il Fornitore di Contatti per acquisire familiarità con le API.
Panoramica
I dispositivi con profili di lavoro archiviano i contatti in locali per il profilo personale e quello di lavoro. Per impostazione predefinita, quando un'app viene eseguita profilo personale, non vengono visualizzati i contatti di lavoro. Tuttavia, un'app può accedere alle informazioni di contatto dal profilo di lavoro. Ad esempio, un'app che si tratta dell'app Contatti di Google per Android che mostra dati personali contatti della directory di lavoro nei risultati di ricerca.
Gli utenti spesso vogliono utilizzare i propri dispositivi e le proprie app personali per lavoro. Utilizzando contatti del profilo di lavoro, la tua app può diventare parte della giornata lavorativa dell'utente.
Esperienza utente
Valuta come la tua app potrebbe presentare i dati di contatto del profilo di lavoro. L'approccio migliore dipende dalla natura della tua app e dal motivo per cui le persone usala, ma tieni in considerazione quanto segue:
- Se l'app include i contatti del profilo di lavoro per impostazione predefinita o l'utente deve attivare?
- In che modo la combinazione o la separazione dei contatti del profilo personale e di lavoro influisce sulla il flusso dell'utente?
- Quali sono le conseguenze di un tocco involontario di un contatto del profilo di lavoro?
- Cosa succede all'interfaccia dell'app quando i contatti del profilo di lavoro non sono presenti disponibili?
La tua app deve indicare chiaramente un contatto del profilo di lavoro. Magari puoi applicare il badge il contatto utilizzando un'icona di lavoro nota, come una valigetta.
.Ad esempio, l'app Contatti Google (mostrata nella Figura 1) esegue le seguenti operazioni per elenca una combinazione di contatti del profilo personale e di lavoro:
- Inserisce un sottotitolo per separare le sezioni di lavoro e personali dell'elenco.
- Le medaglie per i contatti di lavoro sono contrassegnate da un'icona a forma di valigetta.
- Apre un contatto di lavoro nel profilo di lavoro quando lo tocchi.
Se la persona che utilizza il dispositivo disattiva il profilo di lavoro, l'app non sarà in grado di cercare i dati di contatto dal profilo di lavoro o dal telecomando dell'organizzazione directory dei contatti. A seconda di come utilizzi i contatti del profilo di lavoro, puoi escludi automaticamente questi contatti oppure potresti dover disattivare l'interfaccia utente i controlli di sicurezza.
Autorizzazioni
Se la tua app funziona già con i contatti dell'utente, avrai i suoi
READ_CONTACTS
(o probabilmente
WRITE_CONTACTS
) che hai richiesto in
del file manifest dell'app. Perché la stessa persona usa il profilo personale e il profilo di lavoro
profilo, non sono necessarie ulteriori autorizzazioni per accedere ai dati di contatto dal lavoro
profilo.
Un amministratore IT può blocca il profilo di lavoro condivide le informazioni di contatto con il profilo personale. Se un team IT L'amministratore blocca l'accesso. Le ricerche dei contatti vengono restituite come risultati vuoti. Il tuo non deve gestire errori specifici se l'utente ha disattivato il lavoro profilo. Il fornitore di contenuti della directory continua a restituire informazioni sull'oggetto directory di contatto di lavoro dell'utente (vedi la sezione Directory). Per testare queste autorizzazioni, visita la pagina Sviluppo e test .
Ricerche dei contatti
Puoi recuperare i contatti dal profilo di lavoro utilizzando le stesse API e gli stessi processi che che la tua app usa per recuperare i contatti nel profilo personale. L'URI aziendale per di contatti è supportato in Android 7.0 (livello API 24) o versioni successive. Devi rendere le seguenti modifiche all'URI:
- Imposta l'URI del fornitore di contenuti su
Contacts.ENTERPRISE_CONTENT_FILTER_URI
, e fornisce il nome del contatto come stringa di query. - Imposta una directory di contatti in cui eseguire la ricerca. Ad esempio:
ENTERPRISE_DEFAULT
trova contatti nel lavoro negozio locale del profilo.
La modifica dell'URI funziona con qualsiasi meccanismo del fornitore di contenuti, ad esempio un
CursorLoader
: è ideale per caricare i dati di contatto nelle interfacce utente perché
l'accesso ai dati avviene su un thread di lavoro. Per semplicità, gli esempi riportati
chiamata di guida ContentResolver.query()
. Ecco come individuare
contatti nella directory dei contatti locali del profilo di lavoro:
Kotlin
// First confirm the device user has given permission for the personal profile. // There isn't a separate work permission, but an IT admin can block access. val readContactsPermission = ContextCompat.checkSelfPermission(getBaseContext(), Manifest.permission.READ_CONTACTS) if (readContactsPermission != PackageManager.PERMISSION_GRANTED) { return } // Fetch Jackie, James, & Jason (and anyone else whose names begin with "ja"). val nameQuery = Uri.encode("ja") // Build the URI to look up work profile contacts whose name matches. Query // the default work profile directory which is the locally-stored contacts. val contentFilterUri = ContactsContract.Contacts.ENTERPRISE_CONTENT_FILTER_URI .buildUpon() .appendPath(nameQuery) .appendQueryParameter( ContactsContract.DIRECTORY_PARAM_KEY, ContactsContract.Directory.ENTERPRISE_DEFAULT.toString() ) .build() // Query the content provider using the generated URI. var cursor = getContentResolver() .query( contentFilterUri, arrayOf( ContactsContract.Contacts._ID, ContactsContract.Contacts.LOOKUP_KEY, ContactsContract.Contacts.DISPLAY_NAME_PRIMARY ), null, null, null ) // Print any results found using the work profile contacts' display name. cursor?.use { while (it.moveToNext()) { Log.i(TAG, "Work profile contact: ${it.getString(2)}") } }
Java
// First confirm the device user has given permission for the personal profile. // There isn't a separate work permission, but an IT admin can block access. int readContactsPermission = ContextCompat.checkSelfPermission( getBaseContext(), Manifest.permission.READ_CONTACTS); if (readContactsPermission != PackageManager.PERMISSION_GRANTED) { return; } // Fetch Jackie, James, & Jason (and anyone else whose names begin with "ja"). String nameQuery = Uri.encode("ja"); // Build the URI to look up work profile contacts whose name matches. Query // the default work profile directory which is the locally stored contacts. Uri contentFilterUri = ContactsContract.Contacts.ENTERPRISE_CONTENT_FILTER_URI .buildUpon() .appendPath(nameQuery) .appendQueryParameter(ContactsContract.DIRECTORY_PARAM_KEY, String.valueOf(ContactsContract.Directory.ENTERPRISE_DEFAULT)) .build(); // Query the content provider using the generated URI. Cursor cursor = getContentResolver().query( contentFilterUri, new String[] { ContactsContract.Contacts._ID, ContactsContract.Contacts.LOOKUP_KEY, ContactsContract.Contacts.DISPLAY_NAME_PRIMARY }, null, null, null); if (cursor == null) { return; } // Print any results found using the work profile contacts' display name. try { while (cursor.moveToNext()) { Log.i(TAG, "Work profile contact: " + cursor.getString(2)); } } finally { cursor.close(); }
Elenchi
Molte organizzazioni utilizzano directory remote, come Microsoft Exchange o LDAP,
contenenti dati di contatto dell'intera organizzazione. La tua app può aiutarti
gli utenti comunicano e condividono con i colleghi che si trovano nell'infrastruttura
. Tieni presente che queste directory contengono in genere migliaia di contatti,
e anche la tua app richiede una connessione di rete attiva per eseguire ricerche. Puoi utilizzare
il fornitore di contenuti Directory
per ottenere le directory utilizzate
account utente e ottenere ulteriori informazioni su una singola directory.
Esegui una query su Directory.ENTERPRISE_CONTENT_URI
.
fornitore di contenuti per ottenere le directory dal profilo personale e
viene restituito insieme. La ricerca nelle directory del profilo di lavoro è supportata
Android 7.0 (livello API 24) o versioni successive. L'app deve comunque concedere all'utente
Autorizzazioni di READ_CONTACTS
per lavorare con il proprio contatto
.
Poiché Android memorizza i dati di contatto in diversi tipi di
directory remote, la classe Directory
offre metodi che puoi chiamare per trovare
informazioni su una directory:
isEnterpriseDirectoryId()
- Chiama questo metodo per sapere se la directory proviene da un account del profilo di lavoro.
Ricorda che il fornitore di contenuti
ENTERPRISE_CONTENT_URI
restituisce il contatto per il profilo personale e per quello di lavoro. isRemoteDirectoryId()
- Chiama questo metodo per sapere se la directory è remota. Directory remote possono essere i negozi dei contatti aziendali o i social network dell'utente.
L'esempio seguente mostra come utilizzare questi metodi per filtrare il profilo di lavoro directory:
Kotlin
// First, confirm the device user has given READ_CONTACTS permission. // This permission is still needed for directory listings ... // Query the content provider to get directories for BOTH the personal and // work profiles. val cursor = getContentResolver() .query( ContactsContract.Directory.ENTERPRISE_CONTENT_URI, arrayOf(ContactsContract.Directory._ID, ContactsContract.Directory.PACKAGE_NAME), null, null, null ) // Print the package name of the work profile's local or remote contact directories. cursor?.use { while (it.moveToNext()) { val directoryId = it.getLong(0) if (ContactsContract.Directory.isEnterpriseDirectoryId(directoryId)) { Log.i(TAG, "Directory: ${it.getString(1)}") } } }
Java
// First, confirm the device user has given READ_CONTACTS permission. // This permission is still needed for directory listings ... // Query the content provider to get directories for BOTH the personal and // work profiles. Cursor cursor = getContentResolver().query( ContactsContract.Directory.ENTERPRISE_CONTENT_URI, new String[]{ ContactsContract.Directory._ID, ContactsContract.Directory.PACKAGE_NAME }, null, null, null); if (cursor == null) { return; } // Print the package name of the work profile's local or remote contact directories. try { while (cursor.moveToNext()) { long directoryId = cursor.getLong(0); if (ContactsContract.Directory.isEnterpriseDirectoryId(directoryId)) { Log.i(TAG, "Directory: " + cursor.getString(1)); } } } finally { cursor.close(); }
L'esempio recupera l'ID e il nome del pacchetto per la directory. Per visualizzare un utente
che aiuta gli utenti a scegliere una sorgente
della directory dei contatti, potrebbe essere necessario
recuperare altre informazioni sulla directory. Per visualizzare altri campi di metadati
potrebbe essere disponibile, leggi il riferimento alla classe Directory
.
Ricerche telefono
Le app possono inviare query
PhoneLookup.CONTENT_FILTER_URI
per
cercare dati di contatto per un numero di telefono. Puoi ottenere risultati di ricerca da
il fornitore di contatti del profilo personale e di lavoro se sostituisci questo URI con
PhoneLookup.ENTERPRISE_CONTENT_FILTER_URI
Questo URI dei contenuti del profilo di lavoro è disponibile in Android 5.0 (livello API 21) oppure
in alto.
L'esempio seguente mostra un'app che esegue query sull'URI dei contenuti del profilo di lavoro per configura l'interfaccia utente per una chiamata in arrivo:
Kotlin
fun onCreateIncomingConnection( connectionManagerPhoneAccount: PhoneAccountHandle, request: ConnectionRequest ): Connection { var request = request // Get the telephone number from the incoming request URI. val phoneNumber = this.extractTelephoneNumber(request.address) var displayName = "Unknown caller" var isCallerInWorkProfile = false // Look up contact details for the caller in the personal and work profiles. val lookupUri = Uri.withAppendedPath( ContactsContract.PhoneLookup.ENTERPRISE_CONTENT_FILTER_URI, Uri.encode(phoneNumber) ) val cursor = getContentResolver() .query( lookupUri, arrayOf( ContactsContract.PhoneLookup._ID, ContactsContract.PhoneLookup.DISPLAY_NAME, ContactsContract.PhoneLookup.CUSTOM_RINGTONE ), null, null, null ) // Use the first contact found and check if they're from the work profile. cursor?.use { if (it.moveToFirst() == true) { displayName = it.getString(1) isCallerInWorkProfile = ContactsContract.Contacts.isEnterpriseContactId(it.getLong(0)) } } // Return a configured connection object for the incoming call. val connection = MyAudioConnection() connection.setCallerDisplayName(displayName, TelecomManager.PRESENTATION_ALLOWED) // Our app's activity uses this value to decide whether to show a work badge. connection.setIsCallerInWorkProfile(isCallerInWorkProfile) // Configure the connection further ... return connection }
Java
public Connection onCreateIncomingConnection ( PhoneAccountHandle connectionManagerPhoneAccount, ConnectionRequest request) { // Get the telephone number from the incoming request URI. String phoneNumber = this.extractTelephoneNumber(request.getAddress()); String displayName = "Unknown caller"; boolean isCallerInWorkProfile = false; // Look up contact details for the caller in the personal and work profiles. Uri lookupUri = Uri.withAppendedPath( ContactsContract.PhoneLookup.ENTERPRISE_CONTENT_FILTER_URI, Uri.encode(phoneNumber)); Cursor cursor = getContentResolver().query( lookupUri, new String[]{ ContactsContract.PhoneLookup._ID, ContactsContract.PhoneLookup.DISPLAY_NAME, ContactsContract.PhoneLookup.CUSTOM_RINGTONE }, null, null, null); // Use the first contact found and check if they're from the work profile. if (cursor != null) { try { if (cursor.moveToFirst() == true) { displayName = cursor.getString(1); isCallerInWorkProfile = ContactsContract.Contacts.isEnterpriseContactId(cursor.getLong(0)); } } finally { cursor.close(); } } // Return a configured connection object for the incoming call. MyConnection connection = new MyConnection(); connection.setCallerDisplayName(displayName, TelecomManager.PRESENTATION_ALLOWED); // Our app's activity uses this value to decide whether to show a work badge. connection.setIsCallerInWorkProfile(isCallerInWorkProfile); // Configure the connection further ... return connection; }
Ricerche email
L'app può recuperare i dati di contatto personali o di lavoro relativi a un indirizzo email inviando una query
Email.ENTERPRISE_CONTENT_LOOKUP_URI
Quando si esegue una query su questo URL, viene prima cercata una corrispondenza esatta nei contatti personali. Se
il fornitore non corrisponde ad alcun contatto personale, quindi cerca
contatti di lavoro per trovare una corrispondenza. Questo URI è disponibile in Android 6.0 (livello API 23)
o superiore.
Per cercare i dati di contatto di un indirizzo email, procedi nel seguente modo:
Kotlin
// Build the URI to look up contacts from the personal and work profiles that // are an exact (case-insensitive) match for the email address. val emailAddress = "somebody@example.com" val contentFilterUri = Uri.withAppendedPath( ContactsContract.CommonDataKinds.Email.ENTERPRISE_CONTENT_LOOKUP_URI, Uri.encode(emailAddress) ) // Query the content provider to first try to match personal contacts and, // if none are found, then try to match the work contacts. val cursor = contentResolver.query( contentFilterUri, arrayOf( ContactsContract.CommonDataKinds.Email.CONTACT_ID, ContactsContract.CommonDataKinds.Email.ADDRESS, ContactsContract.Contacts.DISPLAY_NAME ), null, null, null ) ?: return // Print the name of the matching contact. If we want to work-badge contacts, // we can call ContactsContract.Contacts.isEnterpriseContactId() with the ID. cursor.use { while (it.moveToNext()) { Log.i(TAG, "Matching contact: ${it.getString(2)}") } }
Java
// Build the URI to look up contacts from the personal and work profiles that // are an exact (case-insensitive) match for the email address. String emailAddress = "somebody@example.com"; Uri contentFilterUri = Uri.withAppendedPath( ContactsContract.CommonDataKinds.Email.ENTERPRISE_CONTENT_LOOKUP_URI, Uri.encode(emailAddress)); // Query the content provider to first try to match personal contacts and, // if none are found, then try to match the work contacts. Cursor cursor = getContentResolver().query( contentFilterUri, new String[]{ ContactsContract.CommonDataKinds.Email.CONTACT_ID, ContactsContract.CommonDataKinds.Email.ADDRESS, ContactsContract.Contacts.DISPLAY_NAME }, null, null, null); if (cursor == null) { return; } // Print the name of the matching contact. If we want to work-badge contacts, // we can call ContactsContract.Contacts.isEnterpriseContactId() with the ID. try { while (cursor.moveToNext()) { Log.i(TAG, "Matching contact: " + cursor.getString(2)); } } finally { cursor.close(); }
Mostra un contatto di lavoro
Le app eseguite nel profilo personale possono mostrare una scheda contatto nel profilo di lavoro.
Chiama
ContactsContract.QuickContact.showQuickContact()
pollici
Android 5.0 o versioni successive per avviare l'app Contatti nel profilo di lavoro e visualizzare
carta del contatto.
Per generare un URI corretto per il profilo di lavoro, devi chiamare
ContactsContract.Contacts.getLookupUri()
e trasmetti un
l'ID contatto e la chiave di ricerca. L'esempio seguente mostra come ottenere l'URI
e poi mostrare la scheda:
Kotlin
// Query the content provider using the ENTERPRISE_CONTENT_FILTER_URI address. // We use the _ID and LOOKUP_KEY columns to generate a work-profile URI. val cursor = getContentResolver() .query( contentFilterUri, arrayOf(ContactsContract.Contacts._ID, ContactsContract.Contacts.LOOKUP_KEY), null, null ) // Show the contact details card in the work profile's Contacts app. The URI // must be created with getLookupUri(). cursor?.use { if (it.moveToFirst() == true) { val uri = ContactsContract.Contacts.getLookupUri(it.getLong(0), it.getString(1)) ContactsContract.QuickContact.showQuickContact( activity, Rect(20, 20, 100, 100), uri, ContactsContract.QuickContact.MODE_LARGE, null ) } }
Java
// Query the content provider using the ENTERPRISE_CONTENT_FILTER_URI address. // We use the _ID and LOOKUP_KEY columns to generate a work-profile URI. Cursor cursor = getContentResolver().query( contentFilterUri, new String[] { ContactsContract.Contacts._ID, ContactsContract.Contacts.LOOKUP_KEY, }, null, null, null); if (cursor == null) { return; } // Show the contact details card in the work profile's Contacts app. The URI // must be created with getLookupUri(). try { if (cursor.moveToFirst() == true) { Uri uri = ContactsContract.Contacts.getLookupUri( cursor.getLong(0), cursor.getString(1)); ContactsContract.QuickContact.showQuickContact( getActivity(), new Rect(20, 20, 100, 100), uri, ContactsContract.QuickContact.MODE_LARGE, null); } } finally { cursor.close(); }
Disponibilità
La tabella seguente riassume le versioni di Android che supportano il profilo di lavoro dati di contatto nel profilo personale:
Versione di Android | Assistenza |
---|---|
5.0 (livello API 21) | Cerca i nomi dei contatti di lavoro per i numeri di telefono utilizzando PhoneLookup.ENTERPRISE_CONTENT_FILTER_URI . |
6.0 (livello API 23) | Cerca i nomi dei contatti di lavoro per gli indirizzi email utilizzando Email.ENTERPRISE_CONTENT_LOOKUP_URI . |
7.0 (livello API 24) | Esegui una query sui nomi dei contatti di lavoro dalle directory di lavoro utilizzando Contacts.ENTERPRISE_CONTENT_FILTER_URI .Elenca tutte le directory nel profilo di lavoro e personale utilizzando Directory.ENTERPRISE_CONTENT_URI . |
Sviluppo e test
Per creare un profilo di lavoro:
- Installa la nostra app DPC di test.
- Apri l'app Set up Test DPC (Configura l'app di test DPC) (non l'icona dell'app Test DPC).
- Segui le istruzioni sullo schermo per configurare un profilo gestito.
- Nel profilo di lavoro, apri l'app Contatti e aggiungi alcuni contatti di esempio.
Per simulare il blocco dell'accesso ai contatti del profilo di lavoro da parte di un amministratore IT, segui questi passaggi:
- Nel profilo di lavoro, apri l'app DPC di test.
- Cerca l'impostazione Disattiva la ricerca di contatti tra più profili o la Disattiva l'impostazione ID chiamante tra più profili.
- Imposta l'opzione su On.
Per scoprire di più su come testare l'app con i profili di lavoro, leggi l'articolo Testare l'app per Compatibilità con i profili di lavoro.
Risorse aggiuntive
Per scoprire di più sui contatti o sul profilo di lavoro, consulta queste risorse:
- Profili di lavoro contiene altre best practice per il lavoro profili.
- Recuperare un elenco di contatti illustra i passaggi necessari per elencare i contatti in un'app.
- Provider di Contatti spiega le della struttura del database dei contatti.