CNContactPickerServiceController和Android联系人选择器-切换到单个或多个联系人

CNContactPickerServiceController和Android联系人选择器-切换到单个或多个联系人,android,swift,xamarin.ios,xamarin.android,Android,Swift,Xamarin.ios,Xamarin.android,我正在为xamarin表单应用程序开发一个联系人搜索模块。我使用依赖注入来启动本机联系人选择器。搜索功能有四个过滤器 仅限电子邮件 联系人必须至少有一个电子邮件地址 仅电话号码 联系人必须至少有一个电话号码 电子邮件电话号码 联系人必须至少有电子邮件地址或电话号码 电子邮件和电话号码 联系人必须至少有一个电子邮件地址和电话号码 以下是我的Xamarin.ios代码 public async Task<List<CNContact>> LaunchContact(IVi

我正在为xamarin表单应用程序开发一个联系人搜索模块。我使用依赖注入来启动本机联系人选择器。搜索功能有四个过滤器

  • 仅限电子邮件 联系人必须至少有一个电子邮件地址
  • 仅电话号码 联系人必须至少有一个电话号码
  • 电子邮件电话号码 联系人必须至少有电子邮件地址或电话号码
  • 电子邮件和电话号码 联系人必须至少有一个电子邮件地址和电话号码
以下是我的Xamarin.ios代码

public async Task<List<CNContact>> LaunchContact(IViewContext context, ContactsSearch contactsSearch)
    {
        List<CNContact> contactsList = new List<CNContact>();

        CNContactPickerViewController contactPickerViewController = new CNContactPickerViewController();

        var emailPredicate = NSPredicate.FromFormat("emailAddresses.@count > 0");
        var phoneNumbersPredicate = NSPredicate.FromFormat("phoneNumbers.@count > 0");

        var compoundPredicate = new List<NSPredicate>();

        switch (contactsSearch.SearchOption)
        {
            case SearchOption.OnlyEmail:
                compoundPredicate.Add(emailPredicate);
                break;
            case SearchOption.OnlyPhoneNumber:
                compoundPredicate.Add(phoneNumbersPredicate);
                break;
            case SearchOption.EmailOrPhoneNumber:
                compoundPredicate.Add(NSPredicate.FromFormat("emailAddresses.@count > 0 OR phoneNumbers.@count > 0"));
                break;
            case SearchOption.EmailAndPhoneNumber:
                compoundPredicate.Add(emailPredicate);
                compoundPredicate.Add(phoneNumbersPredicate);
                break;
            default:
                break;
        }

        var predicateListCount = compoundPredicate.Count;

        if (predicateListCount > 0)
        {
            var compoundPredicateArray = new NSPredicate[predicateListCount];
            for (int index = 0; index < predicateListCount; index++)
            {
                compoundPredicateArray[index] = compoundPredicate[index];
            }
            contactPickerViewController.PredicateForEnablingContact =
                NSCompoundPredicate.CreateAndPredicate(compoundPredicateArray);
        }


        TaskCompletionSource<List<CNContact>> promise = new TaskCompletionSource<List<CNContact>>();
        bool contactPickerPresented = false;

        try
        {
            var displayWaitingIndicator = WaitingIndicator.IsWaitingIndicatorVisible;
            var currentContext = ((PageRenderer)context.Renderer);


            contactPickerViewController.PredicateForSelectionOfContact = NSPredicate.FromValue(true);
            contactPickerViewController.Delegate = new ContactPickerDelegate(promise);

            contactPickerViewController.DisplayedPropertyKeys = KeysToFetch;

            if (displayWaitingIndicator)
            {
                await WaitingIndicator.HideWaitingIndicatorAsync(true);
            }
            currentContext.PresentViewController(contactPickerViewController, true, null);
            contactPickerPresented = true;

            if (displayWaitingIndicator)
            {
                await WaitingIndicator.ShowWaitingIndicatorAsync();
            }
            contactsList = await promise.Task;
            if (contactsList.Count == 0)
            {
                throw new Exception();
            }
        }
        catch (TaskCanceledException ex)
        {
            Console.WriteLine(ex.Message);
            if (contactPickerViewController != null && contactPickerPresented)
            {
                contactPickerViewController.DismissModalViewController(true);
            }
        }

        return contactsList;
    }
公共异步任务启动联系人(IViewContext上下文,联系人搜索联系人搜索)
{
列表联系人列表=新列表();
CNContactPickerViewController contactPickerViewController=新的CNContactPickerViewController();
var emailPredicate=NSPredicate.FromFormat(“emailAddresses@count>0”);
var phonenumberspredite=NSPredicate.FromFormat(“phoneNumbers@count>0”);
var compoundPredicate=新列表();
开关(触点搜索选项)
{
case SearchOption.only电子邮件:
compoundPredicate.Add(emailPredicate);
打破
case SearchOption.OnlyPhoneNumber:
Add(phoneNumbersPredicate);
打破
案例搜索选项。电子邮件或电话号码:
compoundPredicate.Add(NSPredicate.FromFormat(“emailAddresses@count>0或phoneNumbers@count>0”);
打破
案例搜索选项。电子邮件和电话号码:
compoundPredicate.Add(emailPredicate);
Add(phoneNumbersPredicate);
打破
违约:
打破
}
var predicateListCount=compoundPredicate.Count;
如果(谓词列表计数>0)
{
var compoundPredicateArray=新的NSPredicate[predicateListCount];
for(int index=0;index
我为此实现了CNContactPickerDelegate

下面是我的Xamarin.android代码

public async Task<ICursor> LaunchContact(IViewContext context, ContactsSearch contactsSearch)
    {
        var currentActivity = (Activity)((PageRenderer)context.Renderer).Context;
        var contentResolver = currentActivity.ContentResolver;
        var promise = new TaskCompletionSource<ICursor>();
        var type = string.Empty;

        switch (contactsSearch.SearchOption)
        {
            case SearchOption.OnlyEmail:

                type = ContactsContract.CommonDataKinds.Email.ContentType;
                break;

            case SearchOption.OnlyPhoneNumber:
                type = ContactsContract.CommonDataKinds.Phone.ContentType;
                break;

            case SearchOption.EmailOrPhoneNumber:
                break;

            case SearchOption.EmailAndPhoneNumber:
                break;

            default:
                break;
        }

        ContactsActivity.ContactsPickerPromise = promise;

        var contactsActivityIntent = new Intent(currentActivity, typeof(ContactsActivity));
        contactsActivityIntent.PutExtra(ContactsActivity.INTENT_TYPE_KEY, type);
        currentActivity.StartActivity(contactsActivityIntent);

        ICursor selectedContactsCursor = await promise.Task;

        return selectedContactsCursor;
    }
公共异步任务启动联系人(IViewContext上下文,联系人搜索联系人搜索)
{
var currentActivity=(活动)((PageRenderer)context.Renderer.context;
var contentResolver=currentActivity.contentResolver;
var promise=new TaskCompletionSource();
var type=string.Empty;
开关(触点搜索选项)
{
case SearchOption.only电子邮件:
类型=ContactsContract.CommonDataTypes.Email.ContentType;
打破
case SearchOption.OnlyPhoneNumber:
类型=ContactsContract.CommonDataTypes.Phone.ContentType;
打破
案例搜索选项。电子邮件或电话号码:
打破
案例搜索选项。电子邮件和电话号码:
打破
违约:
打破
}
ContactsActivity.ContactsPickerPromise=承诺;
var contactsActivityIntent=新意图(currentActivity,typeof(ContactsActivity));
ContactsActivityContent.PutExtra(ContactsActivity.INTENT类型键,类型);
currentActivity.StartActivity(ContactsActivity内容);
ICursor SelectedContactsCRSOR=等待承诺。任务;
返回所选联系人或;
}
联系活动

public class ContactsActivity : Activity
{

    private const int REQUEST_CODE = 101;
    private readonly TaskCompletionSource<ICursor> promise;
    public static TaskCompletionSource<ICursor> ContactsPickerPromise { get; set; }
    public const string IntentExtraContext = "ActivityContext";
    public const string INTENT_TYPE_KEY = "CONTACT_PICKER_URL_INTENT";

    public ContactsActivity()
    {
        promise = ContactsPickerPromise;
    }

    protected override void OnCreate(Bundle savedInstanceState)
    {
        base.OnCreate(savedInstanceState);

        LaunchContactPicker();
    }

    private void LaunchContactPicker()
    {
        var contactPickerType = Intent.GetStringExtra(INTENT_TYPE_KEY);
        var contactPickerIntent = new Intent(Intent.ActionPick);
        if (contactPickerType != "")
        {
            contactPickerIntent.SetType(contactPickerType);
        }
        else
        {
            contactPickerIntent.SetData(ContactsContract.Contacts.ContentUri);
        }


        StartActivityForResult(contactPickerIntent, REQUEST_CODE);
    }

    protected override void OnActivityResult(int requestCode, [GeneratedEnum] Result resultCode, Intent data)
    {
        base.OnActivityResult(requestCode, resultCode, data);

        Finish();

        Task.Factory.StartNew(() =>
        {
            try
            {
                if (requestCode == REQUEST_CODE && resultCode == Result.Ok)
                {
                    Android.Net.Uri uri = data.Data;
                    var contentResolver = this.ContentResolver;
                    var contactsCursor = contentResolver.Query(uri, null, null, null, null);
                    promise.TrySetResult(contactsCursor);
                }
                else
                {
                    promise.TrySetCanceled();
                    return;
                }
            }
            catch (Exception ex)
            {
                promise.SetException(ex);
            }
        });
    }
}
公共类联系人活动:活动
{
私有const int REQUEST_CODE=101;
私有只读任务完成源承诺;
公共静态任务完成源联系人SpickerPromise{get;set;}
public const string IntentExtraContext=“ActivityContext”;
public const string INTENT\u TYPE\u KEY=“CONTACT\u PICKER\u URL\u INTENT”;
公共联系活动()
{
承诺=联系人承诺;
}
创建时受保护的覆盖无效(Bundle savedInstanceState)
{
base.OnCreate(savedInstanceState);
启动ContactPicker();
}
私有无效启动ContactPicker()
{
var contactPickerType=Intent.GetStringExtra(Intent\u TYPE\u键);
var contactPickerIntent=新意图(Intent.ActionPick);