این راهنمای توسعهدهنده توضیح میدهد که چگونه میتوانید برنامهتان را بهبود دهید تا از دادههای مخاطب نمایه کاری استفاده کند. اگر قبلاً از میاناهای برنامهسازی کاربردی مخاطبین Android استفاده نکردهاید، ارائهدهنده مخاطبین را بخوانید تا با میاناهای برنامهسازی کاربردی آشنا شوید.
نمای کلی
دستگاههای دارای نمایه کاری مخاطبین را در فهرستهای راهنمای محلی جداگانهای برای نمایههای کاری و شخصی ذخیره میکنند. بهطور پیشفرض، وقتی برنامهای در نمایه شخصی اجرا میشود، مخاطبین کاری را نمایش نمیدهد. بااینحال، برنامه میتواند به اطلاعات تماس از نمایه کاری دسترسی داشته باشد. برای مثال، برنامهای که این کار را انجام میدهد برنامه «مخاطبین Android» از Google است که هم مخاطبین شخصی و هم مخاطبین فهرست راهنمای کاری را در نتایج جستجو نشان میدهد.
کاربران اغلب میخواهند از دستگاهها و برنامههای شخصیشان برای کار استفاده کنند. بااستفاده از مخاطبین نمایه کاری، برنامهتان میتواند بخشی از روز کاری کاربر شود.
تجربه کاربری
درنظر بگیرید که برنامهتان چگونه ممکن است اطلاعات تماس را از نمایه کاری ارائه دهد. بهترین رویکرد به ماهیت برنامه شما و دلیل استفاده افراد از آن بستگی دارد، اما به موارد زیر فکر کنید:
- آیا برنامه شما باید بهطور پیشفرض مخاطبین نمایه کاری را دربرگیرد یا کاربر باید موافقت کند؟
- مخلوط کردن یا جدا کردن مخاطبین نمایه کاری و شخصی چه تأثیری بر جریان کاربر خواهد داشت؟
- تأثیر ضربه زدن تصادفی روی مخاطب نمایه کاری چیست؟
- وقتی مخاطبین نمایه کاری دردسترس نباشند، چه اتفاقی برای میانای برنامهتان میافتد؟
برنامهتان باید مخاطب نمایه کاری را بهوضوح نشان دهد. شاید بتوانید بااستفاده از نماد کاری آشنا (مثل کیف دستی) به مخاطب نشان بدهید.
برای مثال، برنامه «مخاطبین Google» (نشاندادهشده در شکل ۱) برای فهرست کردن ترکیبی از مخاطبین نمایه کاری و شخصی کارهای زیر را انجام میدهد:
- عنوان فرعیای برای جدا کردن بخشهای کاری و شخصی فهرست درج میکند.
- مخاطبین کاری را با نماد کیف اداری نشاندار میکند.
- وقتی روی آن تکضرب بزنید، مخاطب کاری را در نمایه کاری باز میکند.
اگر فردی که از دستگاه استفاده میکند نمایه کاری را خاموش کند، برنامه شما نمیتواند اطلاعات تماس را از نمایه کاری یا فهرستهای راهنمای تماس ازراهدور سازمان جستجو کند. بسته به نحوه استفاده شما از مخاطبین نمایه کاری، میتوانید این مخاطبین را بدون اطلاع کاربر حذف کنید یا ممکن است لازم باشد کنترلهای میانای کاربر را غیرفعال کنید.
اجازهها
اگر برنامهتان ازقبل با مخاطبین کاربر کار میکند، اجازه
READ_CONTACTS (یا احتمالاً
WRITE_CONTACTS) را که در فایل مانیفست برنامهتان درخواست کردهاید خواهید داشت. چون یک نفر از نمایه شخصی و نمایه کاری استفاده میکند، برای دسترسی به دادههای مخاطب از نمایه کاری به اجازه بیشتری نیاز ندارید.
سرپرست فناوری اطلاعات میتواند مسدود کند که نمایه کاری اطلاعات تماس را با نمایه شخصی همرسانی کند. اگر سرپرست فناوری اطلاعات دسترسی را مسدود کند، جستجوهای مخاطب شما بهعنوان نتایج خالی برگردانده میشود. اگر کاربر نمایه کاری را خاموش کرده باشد، برنامهتان نیازی به رسیدگی به خطاهای خاص ندارد. ارائهدهنده محتوای دایرکتوری همچنان اطلاعات مربوط به دایرکتوریهای مخاطبین کاری کاربر را برمیگرداند (بخش دایرکتوریها را ببینید). برای آزمایش این اجازهها، به بخش توسعه و آزمایش مراجعه کنید.
جستجوهای مخاطب
میتوانید مخاطبین را از نمایه کاری بااستفاده از همان میاناهای برنامهسازی کاربردی و فرایندهایی که برنامهتان برای دریافت مخاطبین در نمایه شخصی استفاده میکند دریافت کنید. URI سازمانی برای مخاطبین در Android نسخه ۷.۰ (سطح میانای برنامهسازی کاربردی ۲۴) یا بالاتر پشتیبانی میشود. باید اصلاحات زیر را در URI اعمال کنید:
- شناسه منبع یکسان ارائهدهنده محتوا را روی
Contacts.ENTERPRISE_CONTENT_FILTER_URIتنظیم کنید، و نام مخاطب را بهعنوان رشته پُرسمان ارائه دهید. - فهرست راهنمای مخاطبین را برای جستجو تنظیم کنید. برای مثال،
ENTERPRISE_DEFAULTمخاطبین را در فضای ذخیرهسازی محلی نمایه کاری پیدا میکند.
تغییر URI با هر سازوکار ارائهدهنده محتوا مانند
CursorLoader کار میکند—ایدهآل برای بار کردن دادههای مخاطب در میانای کاربر زیرا
دسترسی به دادهها در رشته عامل اتفاق میافتد. برای سادگی، مثالهای این
راهنما ContentResolver.query() را فراخوانی میکنند. در اینجا نحوه پیدا کردن مخاطبین در فهرست مخاطبین محلی نمایه کاری آورده شده است:
کاتلین
// 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)}") } }
جاوا
// 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(); }
فهرستهای راهنما
بسیاری از سازمانها از دایرکتوریهای راه دور، مانند Microsoft Exchange یا LDAP، استفاده میکنند
که حاوی اطلاعات تماس کل سازمان است. برنامه شما میتواند به کاربران کمک کند با همکاران کاری که در فهرست راهنمای سازمانشان پیدا شدهاند ارتباط برقرار کنند و با آنها همرسانی کنند. توجه داشته باشید که این دایرکتوریها معمولاً حاوی هزاران مخاطب هستند،
و برنامهتان برای جستجو در آنها به اتصال شبکه فعال نیز نیاز دارد. میتوانید از ارائهدهنده محتوای Directory برای دریافت دایرکتوریهای استفادهشده توسط حسابهای کاربر و کسب اطلاعات بیشتر درباره یک دایرکتوری خاص استفاده کنید.
از ارائهدهنده محتوای Directory.ENTERPRISE_CONTENT_URI درخواست کنید تا دایرکتوریهای نمایه شخصی و نمایه کاری را باهم برگرداند. جستجوی دایرکتوریهای نمایه کاری در
Android نسخه ۷.۰ (سطح میانای برنامهسازی کاربردی ۲۴) یا بالاتر پشتیبانی میشود. برنامه شما همچنان به کاربر نیاز دارد تا
اجازههای READ_CONTACTS را برای کار با
فهرستهای مخاطبین خود بدهد.
چون Android اطلاعات مخاطب را در انواع مختلفی از دایرکتوریهای محلی و
ازراهدور ذخیره میکند، کلاس Directory روشهایی دارد که میتوانید برای کسب اطلاعات بیشتر
درباره دایرکتوری فراخوانی کنید:
isEnterpriseDirectoryId()- این روش را فراخوانی کنید تا متوجه شوید که آیا دایرکتوری از حساب نمایه کاری است یا نه.
بهیاد داشته باشید که ارائهدهنده محتوای
ENTERPRISE_CONTENT_URIدایرکتوریهای مخاطب را برای نمایه شخصی و کاری باهم برمیگرداند. isRemoteDirectoryId()- این روش را فراخوانی کنید تا متوجه شوید که آیا دایرکتوری از راه دور است یا نه. دایرکتوریهای از دور ممکن است فروشگاههای مخاطب سازمانی یا شبکههای اجتماعی کاربر باشند.
مثال زیر نشان میدهد که چگونه میتوانید از این روشها برای فیلتر کردن دایرکتوریهای نمایه کاری استفاده کنید:
کاتلین
// 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)}") } } }
جاوا
// 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(); }
این نمونه شناسه و نام بسته را برای دایرکتوری واکشی میکند. برای نمایش میانای کاربر که به کاربران کمک میکند منبع فهرست راهنمای مخاطب را انتخاب کنند، شاید لازم باشد اطلاعات بیشتری درباره فهرست راهنما واکشی کنید. برای دیدن سایر فیلدهای فراداده که
ممکن است دردسترس باشند، مرجع کلاس Directory را بخوانید.
جستجوی تلفن
برنامهها میتوانند
PhoneLookup.CONTENT_FILTER_URI را جستجو کنند تا بهطور مؤثر
دادههای مخاطب را برای شماره تلفن جستجو کنند. اگر این URI را با PhoneLookup.ENTERPRISE_CONTENT_FILTER_URI جایگزین کنید، میتوانید نتایج جستجو را از ارائهدهنده مخاطبین نمایه کاری و شخصی دریافت کنید.
این شناسه منبع یکسان محتوای نمایه کاری در Android نسخه ۵.۰ (سطح میانای برنامهسازی کاربردی ۲۱) یا بالاتر دردسترس است.
مثال زیر برنامهای را نشان میدهد که شناسه منبع یکسان محتوای نمایه کاری را برای پیکربندی میانای کاربر برای تماس ورودی پُرسمان میکند:
کاتلین
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 }
جاوا
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; }
جستجوی ایمیل
برنامه شما میتواند با پرسمان کردن از Email.ENTERPRISE_CONTENT_LOOKUP_URI، دادههای تماس شخصی یا کاری را برای نشانی ایمیل دریافت کند.
با جستجوی این نشانی وب، ابتدا مخاطبین شخصی برای یافتن مورد منطبق دقیق جستجو میشود. اگر
ارائهدهنده با هیچ مخاطب شخصیای مطابقت نداشته باشد، ارائهدهنده سپس
مخاطبین کاری را برای یافتن مطابقت جستجو میکند. این URI در Android 6.0 (سطح میانای برنامهسازی کاربردی ۲۳)
یا بالاتر دردسترس است.
در اینجا نحوه جستجوی اطلاعات تماس برای نشانی ایمیل آورده شده است:
کاتلین
// 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)}") } }
جاوا
// 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(); }
نمایش مخاطب کاری
برنامههایی که در نمایه شخصی اجرا میشوند میتوانند کارت مخاطب را در نمایه کاری نشان دهند.
برای راهاندازی برنامه «مخاطبین» در نمایه کاری و نمایش کارت مخاطب،
ContactsContract.QuickContact.showQuickContact() را در Android نسخه ۵.۰ یا بالاتر فراخوانی کنید.
برای تولید URI صحیح برای نمایه کاری، باید
ContactsContract.Contacts.getLookupUri() را فراخوانی کنید و
شناسه مخاطب و کلید جستجو را ارسال کنید. مثال زیر نشان میدهد که چگونه میتوانید URI را دریافت کنید
و سپس کارت را نشان دهید:
کاتلین
// 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 ) } }
جاوا
// 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(); }
دردسترس بودن
جدول زیر خلاصه میکند که کدام نسخههای Android از دادههای مخاطب نمایه کاری در نمایه شخصی پشتیبانی میکنند:
| نسخه Android | پشتیبانی |
|---|---|
| ۵.۰ (سطح میانای برنامهسازی کاربردی ۲۱) | نام مخاطبین کاری را برای شماره تلفنها بااستفاده از PhoneLookup.ENTERPRISE_CONTENT_FILTER_URI جستجو کنید. |
| ۶.۰ (سطح میانای برنامهسازی کاربردی ۲۳) | بااستفاده از Email.ENTERPRISE_CONTENT_LOOKUP_URI، نام مخاطبین کاری را برای نشانیهای ایمیل جستجو کنید. |
| ۷.۰ (سطح ایپیآی ۲۴) | نام مخاطبین کاری را بااستفاده از Contacts.ENTERPRISE_CONTENT_FILTER_URI از دایرکتوریهای کاری پُرسمان کنید.همه دایرکتوریهای موجود در نمایههای کاری و شخصی را بااستفاده از Directory.ENTERPRISE_CONTENT_URI فهرست کنید. |
توسعه و آزمایش
برای ایجاد نمایه کاری، این مراحل را دنبال کنید:
- برنامه Test DPC ما را نصب کنید.
- برنامه Set up Test DPC را باز کنید (نه نماد برنامه Test DPC).
- برای راهاندازی نمایه مدیریتشده، دستورالعملهای روی صفحه را دنبال کنید.
- در نمایه کاری، برنامه مخاطبین را باز کنید و چند مخاطب نمونه اضافه کنید.
برای شبیهسازی مسدود کردن دسترسی به مخاطبین نمایه کاری توسط سرپرست فناوری اطلاعات، این مراحل را دنبال کنید:
- در نمایه کاری، برنامه Test DPC را باز کنید.
- تنظیم غیرفعال کردن جستجوی مخاطبین بیننمایهای یا تنظیم غیرفعال کردن شناسه تماسگیرنده بیننمایهای را جستجو کنید.
- تنظیم را به روشن تغییر دهید.
برای کسب اطلاعات بیشتر درباره آزمایش کردن برنامه با نمایههای کاری، آزمایش کردن برنامه برای سازگاری با نمایههای کاری را بخوانید.
منابع بیشتر
برای کسب اطلاعات بیشتر درباره مخاطبین یا نمایه کاری، این منابع را ببینید:
- نمایههای کاری حاوی روالهای مطلوب بیشتری برای نمایههای کاری است.
- بازیابی فهرست مخاطبین مراحل لازم برای فهرست کردن مخاطبین در برنامه را توضیح میدهد.
- ارائهکننده مخاطبین ساختار پایگاه داده مخاطبین را توضیح میدهد.