Xamarin Android,使用带有选择和选择参数的 CursorLoader 获取联系人手机号码

Posted

技术标签:

【中文标题】Xamarin Android,使用带有选择和选择参数的 CursorLoader 获取联系人手机号码【英文标题】:Xamarin Android, get contact mobile number by using CursorLoader with selection and selection args 【发布时间】:2017-04-09 14:08:17 【问题描述】:

我正在尝试使用 Intent 获取用户从 android 中的联系人列表中选择的联系人的详细联系信息,代码如下:

Intent Intent = new Intent(Intent.ActionPick, ContactsContract.Contacts.ContentUri);            
        Intent.SetType(ContactsContract.Contacts.ContentType);
        StartActivityForResult(Intent, 3);

现在在 Intent 结果上,我运行以下代码来获取特定的联系信息:

public override void OnActivityResult(int requestCode, int resultCode, Intent data)
               
        if (requestCode == 3 && resultCode == -1 && data != null) //result code -1 means OK 0 Means cancelled Result.Ok
        
            var ContactData = data.Data;
            string ID = "";
            string name = "";
            string address = "";
            byte[] picture = new byte[0];
            List<string> numbers = new List<string>();
            List<string> emails = new List<string>();
            string mobile = "";
            string email = "";
            string selectionString  = "id = ?";



            string[] columnsNames = new string[] 
                ContactsContract.Contacts.InterfaceConsts.Id,
                ContactsContract.Contacts.InterfaceConsts.DisplayName,
                ContactsContract.Contacts.InterfaceConsts.PhotoUri
            ;

            var loader = new CursorLoader(Statics.mainActivity, ContactData, null, null, null, null);                
            var cursor = (ICursor)loader.LoadInBackground();


            if (cursor.MoveToFirst())
            
                ID = cursor.GetString(cursor.GetColumnIndex(columnsNames[0]));
                name = cursor.GetString(cursor.GetColumnIndex(columnsNames[1]));
                picture = cursor.GetBlob(cursor.GetColumnIndex(columnsNames[2]));                  
            

            //Store Contact ID
            string[] selectionStringArgs = new string[]  ID ;

            //Phone Numbers
            string[] columnsNames2 = new string[] 
                ContactsContract.CommonDataKinds.Phone.Number                 
            ;

            var loader2 = new CursorLoader(Statics.mainActivity, ContactsContract.CommonDataKinds.Phone.ContentUri, columnsNames2, selectionString, selectionStringArgs, null);
            var cursor2 = (ICursor)loader2.LoadInBackground();

            while (cursor2.MoveToNext())
            
                numbers.Add(cursor2.GetString(cursor2.GetColumnIndex(columnsNames2[0])));
            

            //Email Address
            string[] columnsNames3 = new string[] 
                ContactsContract.CommonDataKinds.Email.Address
            ;


            var loader3 = new CursorLoader(Statics.mainActivity, ContactsContract.CommonDataKinds.Email.ContentUri, columnsNames3, selectionString, selectionStringArgs, null);
            var cursor3 = (ICursor)loader3.LoadInBackground();

            while (cursor3.MoveToNext())
            
                emails.Add(cursor3.GetString(cursor3.GetColumnIndex(columnsNames3[0])));
            



            int TempRecepitntID = 0;
            EmployeesViewModel tempRecipent = new EmployeesViewModel();
            TempRecepitntID = Statics.mainActivity.currentViewModel.SelectedChat.ReceiverEmployee;

            foreach (EmployeesViewModel evm in Statics.mainActivity.currentViewModel.Employees)
            
                if (evm.ID == TempRecepitntID)
                    tempRecipent = evm;
            

            new Android.Support.V7.App.AlertDialog.Builder(Statics.mainActivity)
                   .SetPositiveButton("Yes", (sender1, args) =>
                   
                       Statics.mainActivity.currentViewModel.AddMessage(picture, tempRecipent, Statics.mainActivity.currentViewModel.SelectedChat.ID, "contact", 0, "", name, numbers[0], mobile, email, address);
                   )
                   .SetNegativeButton("No", (sender1, args) =>
                   
                        // cancel
                    )
                   .SetMessage("Are you shure you want to send?")
                   .SetTitle("System Message")
                   .Show();                
        
    

问题是我只想检索用户选择的联系人的信息,但我得到的是所有其他联系人数据都被检索所以我尝试通过设置字符串 selectionString = "id 来使用 CursorLoader 的 selection 和 selectionargs 参数= ?”;和 selectionArgs 到 string[] selectionStringArgs = new string[] ID ; ID 值是从以下代码中检索的:

            if (cursor.MoveToFirst())
            
                ID = cursor.GetString(cursor.GetColumnIndex(columnsNames[0]));
                name = cursor.GetString(cursor.GetColumnIndex(columnsNames[1]));
                picture = cursor.GetBlob(cursor.GetColumnIndex(columnsNames[2]));                  
            

            //Store Contact ID
            string[] selectionStringArgs = new string[]  ID ;

            //Phone Numbers
            string[] columnsNames2 = new string[] 
                ContactsContract.CommonDataKinds.Phone.Number                 
            ;

但现在它返回 0 个结果,我在互联网上找不到任何适用于 Xamarin android 的内容,请帮助。

谢谢,

【问题讨论】:

【参考方案1】:

终于找到了解决办法,我在cursorloader方法的选择参数中使用了如下字符串:

string selectionString = ContactsContract.CommonDataKinds.Phone.InterfaceConsts.ContactId + "=" + ID;

现在只检索选定的联系人号码。

我希望这对其他人有帮助。

【讨论】:

我把它放在了第一个验证 cursor.movefirst() 的 IF 块中的变量 ID 之后,我得到了错误:无法在索引 1 处绑定参数,因为索引超出范围。该语句有 0 个参数。【参考方案2】:

在@TMSL的附加信息中,我在这个块之后添加了代码

if (cursor.MoveToFirst())
                    
                        ID = cursor.GetString(cursor.GetColumnIndex(columnsNames[0]));
                        name = cursor.GetString(cursor.GetColumnIndex(columnsNames[1]));
                        picture = cursor.GetBlob(cursor.GetColumnIndex(columnsNames[2]));

                    

这里

            selectionString = ContactsContract.CommonDataKinds.Phone.InterfaceConsts.ContactId + "=" + ID;

然后我把变量Loader2定义中用到的参数改了,把selectionStringArgs转换成null

var loader2 = new CursorLoader(this.Activity, ContactsContract.CommonDataKinds.Phone.ContentUri, columnsNames2, selectionString, null,null);
                    var cursor2 = (ICursor)loader2.LoadInBackground();

我从 xamarin 指南中找到了 this 文档

Uri – ContentProvider 的完全限定名称。 投影 - 指定为光标选择哪些列。 选择 – 类似于 SQL WHERE 子句。 SelectionArgs – 要在选择中替换的参数。 SortOrder – 排序依据的列。

所以,@TMSAL 代码中使用的变量selectionStringArgs 不能使用“contact_id = 2700”之类的值,因为 CursorLoader 的参数SelectionArgs 不是过滤器而不是“选择中要替换的参数"

我希望这对其他人也有帮助。

【讨论】:

以上是关于Xamarin Android,使用带有选择和选择参数的 CursorLoader 获取联系人手机号码的主要内容,如果未能解决你的问题,请参考以下文章

如何在 xamarin android ui 测试自动化中使用日期选择器

在 Xamarin.Forms 中具有两个带有数字的选择列的选择器

Xamarin.Android编译CPU类型选择方式

xamarin android 文件选择

Xamarin android 中文件选择器的示例代码

Xamarin 波斯语日期选择器