Panduan developer ini menjelaskan cara meningkatkan kualitas aplikasi Anda untuk menggunakan kontak data dari profil kerja. Jika Anda belum menggunakan API kontak Android sebelumnya, baca Penyedia Kontak untuk memahami API.
Ringkasan
Perangkat dengan profil kerja menyimpan kontak di kontak lokal terpisah direktori untuk profil kerja dan pribadi. Secara default, saat aplikasi berjalan di profil pribadi, tidak akan menampilkan kontak bisnis. Namun, aplikasi dapat mengakses informasi kontak dari profil kerja. Misalnya, aplikasi yang melakukan ini adalah aplikasi Kontak Android Google yang menampilkan data pribadi dan kontak direktori kerja di hasil penelusuran.
Pengguna sering kali ingin menggunakan perangkat dan aplikasi pribadi mereka untuk bekerja. Dengan menggunakan kontak profil kerja, aplikasi Anda dapat menjadi bagian dari hari kerja pengguna.
Pengalaman pengguna
Pertimbangkan bagaimana aplikasi dapat menyajikan informasi kontak dari profil kerja. Pendekatan terbaik bergantung pada sifat aplikasi Anda dan alasan pengguna menggunakannya, tetapi pertimbangkan hal-hal berikut:
- Haruskah aplikasi Anda menyertakan kontak profil kerja secara default atau apakah pengguna harus memilih ikut serta?
- Bagaimana mencampur atau memisahkan kontak kerja dan profil pribadi akan mempengaruhi di alur pengguna?
- Apa dampak mengetuk kontak profil kerja secara tidak sengaja?
- Yang terjadi pada antarmuka aplikasi jika kontak profil kerja tidak tersedia?
Aplikasi Anda harus menunjukkan kontak profil kerja dengan jelas. Mungkin Anda dapat memasang badge kontak menggunakan ikon kerja yang familier—seperti koper.
Sebagai contoh, aplikasi Google Kontak (ditunjukkan pada gambar 1) melakukan hal berikut untuk mencantumkan campuran kontak profil kerja dan pribadi:
- Menyisipkan subheader untuk memisahkan bagian pekerjaan dan pribadi dari daftar.
- Lencana kontak kerja dengan ikon koper.
- Membuka kontak kerja di profil kerja saat diketuk.
Jika pengguna perangkat menonaktifkan profil kerja, aplikasi Anda tidak dapat mencari informasi kontak dari profil kerja atau jarak jauh organisasi direktori kontak. Bergantung pada cara Anda menggunakan kontak profil kerja, Anda dapat mengabaikan kontak ini secara diam-diam atau Anda mungkin perlu menonaktifkan antarmuka pengguna kontrol.
Izin
Jika aplikasi Anda sudah berfungsi dengan kontak pengguna, Anda akan mendapatkan
READ_CONTACTS
(atau mungkin
WRITE_CONTACTS
) yang Anda minta di
file manifes aplikasi Anda. Karena orang yang sama menggunakan profil pribadi dan pekerjaannya
profil ini, Anda tidak memerlukan izin lebih lanjut untuk mengakses data kontak dari kantor
untuk profil.
Admin IT dapat blokir profil kerja yang berbagi informasi kontak dengan profil pribadi. Jika staf IT jika admin memblokir akses, penelusuran kontak Anda ditampilkan sebagai hasil kosong. Nama aplikasi tidak perlu menangani error tertentu jika pengguna mematikan pekerjaan untuk profil. Penyedia konten direktori terus mengembalikan informasi tentang direktori kontak kerja pengguna (lihat bagian Direktori). Untuk menguji izin ini, lihat Pengembangan dan pengujian bagian.
Penelusuran kontak
Anda dapat memperoleh kontak dari profil kerja menggunakan API dan proses yang sama seperti yang digunakan aplikasi Anda untuk mendapatkan kontak di profil pribadi. URI perusahaan untuk kontak didukung dalam Android 7.0 (API level 24) atau yang lebih tinggi. Anda perlu membuat penyesuaian berikut pada URI:
- Menetapkan URI penyedia konten ke
Contacts.ENTERPRISE_CONTENT_FILTER_URI
, dan memberikan nama kontak sebagai string kueri. - Setel direktori kontak yang akan ditelusuri. Misalnya,
ENTERPRISE_DEFAULT
menemukan kontak di kantor toko lokal di profil Anda.
Mengubah URI dapat berfungsi dengan mekanisme penyedia konten apa pun seperti
CursorLoader
—cocok untuk memuat data kontak ke dalam antarmuka pengguna karena
akses data terjadi
di thread pekerja. Untuk lebih mudahnya, contoh dalam
panggilan pemandu ContentResolver.query()
. Berikut adalah cara menemukan
kontak di direktori kontak lokal profil kerja:
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(); }
Direktori
Banyak organisasi menggunakan direktori
jarak jauh, seperti Microsoft Exchange atau LDAP,
yang berisi informasi kontak untuk seluruh organisasi. Aplikasi Anda dapat membantu
pengguna berkomunikasi dan berbagi dengan rekan kerja yang ada di lingkungan organisasi mereka
saat ini. Perhatikan bahwa direktori ini
biasanya berisi ribuan kontak,
dan aplikasi Anda juga memerlukan koneksi jaringan
aktif untuk menelusurinya. Anda dapat menggunakan
penyedia konten Directory
untuk mendapatkan direktori yang digunakan oleh
akun pengguna dan mencari tahu lebih lanjut
tentang direktori individual.
Mengkueri Directory.ENTERPRISE_CONTENT_URI
penyedia konten untuk mendapatkan direktori dari profil pribadi dan karya
profil yang ditampilkan. Penelusuran direktori profil kerja didukung di
Android 7.0 (level API 24) atau yang lebih tinggi. Aplikasi Anda masih membutuhkan
pengguna untuk memberi
READ_CONTACTS
izin untuk bekerja dengan kontak mereka
direktori.
Karena Android menyimpan informasi
kontak dalam berbagai jenis
direktori jarak jauh, class Directory
memiliki metode yang dapat Anda panggil untuk menemukan
tentang direktori:
isEnterpriseDirectoryId()
- Panggil metode ini untuk mengetahui apakah direktori tersebut berasal dari akun profil kerja.
Perlu diingat bahwa penyedia konten
ENTERPRISE_CONTENT_URI
akan menampilkan kontak direktori untuk profil pribadi dan kerja bersama-sama. isRemoteDirectoryId()
- Panggil metode ini untuk mengetahui apakah direktori tersebut jarak jauh. Direktori jarak jauh bisa jadi toko kontak perusahaan atau bisa berupa jejaring sosial pengguna.
Contoh berikut menunjukkan cara menggunakan metode ini untuk memfilter profil kerja direktori:
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(); }
Contoh ini mengambil ID dan nama paket untuk direktori. Untuk menampilkan pengguna
yang membantu pengguna memilih sumber direktori kontak, Anda mungkin perlu
mengambil informasi selengkapnya tentang direktori. Untuk melihat isian {i>metadata <i}lain yang
mungkin tersedia, baca referensi class Directory
.
Pencarian ponsel
Aplikasi dapat mengkueri
PhoneLookup.CONTENT_FILTER_URI
untuk secara efisien
mencari data kontak untuk nomor telepon. Anda bisa mendapatkan hasil pencarian dari
penyedia kontak pribadi dan profil kerja jika Anda mengganti URI ini dengan
PhoneLookup.ENTERPRISE_CONTENT_FILTER_URI
URI konten profil kerja ini tersedia di Android 5.0 (API level 21) atau
lebih tinggi.
Contoh berikut menampilkan aplikasi yang melakukan kueri URI konten profil kerja untuk mengonfigurasi antarmuka pengguna untuk panggilan masuk:
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; }
Pencarian email
Aplikasi Anda dapat memperoleh data kontak pribadi atau kerja untuk alamat email dengan membuat kueri
Email.ENTERPRISE_CONTENT_LOOKUP_URI
Meminta URL ini terlebih dahulu akan menelusuri kontak pribadi untuk pencocokan persis. Jika
penyedia tersebut tidak cocok dengan kontak
pribadi mana pun, penyedia kemudian mencari
kontak kerja untuk
mendapatkan kecocokan. URI ini tersedia di Android 6.0 (API level 23)
atau yang lebih tinggi.
Berikut adalah cara mencari informasi kontak untuk alamat email:
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(); }
Menampilkan kontak kantor
Aplikasi yang berjalan dalam profil pribadi dapat menampilkan kartu kontak di profil kerja.
Telepon
ContactsContract.QuickContact.showQuickContact()
inci
Android 5.0 atau yang lebih tinggi untuk meluncurkan aplikasi Kontak di profil kerja dan menampilkan
kartu kontak.
Agar dapat membuat URI yang benar untuk profil kerja, Anda harus memanggil
ContactsContract.Contacts.getLookupUri()
dan teruskan
ID kontak dan
kunci pencarian. Contoh berikut menunjukkan cara mendapatkan URI
lalu tampilkan kartu:
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(); }
Ketersediaan
Tabel berikut merangkum versi Android mana yang mendukung profil kerja data kontak di profil pribadi:
Versi Android | Dukungan |
---|---|
5.0 (API Level 21) | Cari nama kontak kantor untuk nomor telepon menggunakan PhoneLookup.ENTERPRISE_CONTENT_FILTER_URI . |
6.0 (level API 23) | Cari nama kontak kantor untuk alamat email menggunakan Email.ENTERPRISE_CONTENT_LOOKUP_URI . |
7.0 (level API 24) | Buat kueri nama kontak kerja dari direktori kerja menggunakan Contacts.ENTERPRISE_CONTENT_FILTER_URI .Cantumkan semua direktori di profil kerja dan pribadi menggunakan Directory.ENTERPRISE_CONTENT_URI . |
Pengembangan dan pengujian
Untuk membuat profil kerja, ikuti langkah-langkah berikut:
- Instal aplikasi Test DPC kami.
- Buka aplikasi Siapkan DPC Pengujian (bukan ikon aplikasi Test DPC).
- Ikuti petunjuk di layar untuk menyiapkan profil terkelola.
- Di profil kerja, buka aplikasi Contacts dan tambahkan beberapa contoh kontak.
Untuk menyimulasikan admin IT yang memblokir akses ke kontak profil kerja, ikuti langkah-langkah berikut:
- Di profil kerja, buka aplikasi Test DPC.
- Telusuri setelan Nonaktifkan penelusuran kontak antar-profil atau Nonaktifkan ID penelepon antar-profil.
- Setel setelan ke Aktif.
Untuk mempelajari lebih lanjut cara menguji aplikasi dengan profil kerja, baca Menguji Aplikasi untuk Kompatibilitas dengan Profil Kerja.
Referensi lainnya
Untuk mempelajari kontak atau profil kerja lebih lanjut, lihat referensi berikut:
- Profil kerja berisi lebih banyak praktik terbaik untuk pekerjaan untuk profil.
- Mengambil daftar kontak memandu langkah-langkah yang diperlukan untuk membuat daftar kontak.
- Penyedia Kontak menjelaskan struktur basis data kontak.