editing and saving contact details using Maui

81 Views Asked by At

previous thread about saving edited contact details

I was following this post to try to understand how to save an edited contact - My project is Maui using VS2022 and targets ios and android though I am initially trying to get the android app working. Maui allows a simple means of selecting a contact viz var contact = await Microsoft.Maui.ApplicationModel.Communication.Contacts.Default.PickContactAsync();

It used to be able to save using Maui.essentials but that has disappeared and one has to delve into the black magic of android code. (Unless someone can tell me there is a simple Maui way of saving and edited contact record)

I have cannibalised the code suggested in the above post but being unfamiliar with low level android code I am having difficulty understanding what is going on I particularly want to edit name, address (physical) and email. I can seem to edit single fields such as given name but when I use similar code to edit or add another email it seems to put the content in the name field I guess Ive not formatted it right - Ive tried reading the Android developers documentation but Im afraid I still dont get it. Can some kind soul tell me where I'm going wrong with this code - Am I understanding the concept right ? builder is passed the id and mimetype with builder.withselection? So far so good - I can edit and change simple fields like givenname, But There can be many emails for one contact how does one edit the static fields such as given name yet add a new email? or how does on reference a particular emailaddress within a specific contact Id?

public class SaveContact
{
    public void SaveContactToPhoneBook(string id,string fname, string sname, string Email)
    {
    #if ANDROID

        ContentProviderOperation.Builder builder =ContentProviderOperation.NewUpdate(ContactsContract.Data.ContentUri);
        
        List<ContentProviderOperation> ops = new List<ContentProviderOperation>();
        builder.WithValue(ContactsContract.CommonDataKinds.StructuredName.FamilyName,sname);
        ops.Add(builder.Build());

       
        // now try to save a new Email
       
        String emailSelection = ContactsContract.Data.InterfaceConsts.Id + " = ? "  +ContactsContract.Data.InterfaceConsts.Mimetype + " = ? ";
        String[] emailSelectionArgs = {id,ContactsContract.CommonDataKinds.Email.ContentItemType};
        
        // i am  not sure how the above parameters work - they are obviously passed in builder.WithSelection()  and I assume the Args are substitued for the '?'
        // to construct the sqlite statement which appears to be constructed deep in the code somewher but how?

        builder = ContentProviderOperation.NewUpdate(ContactsContract.Data.ContentUri);
        builder.WithSelection(emailSelection, emailSelectionArgs);            
        builder.WithValue(ContactsContract.CommonDataKinds.Email.Address, Email);
     
          ops.Add(builder.Build());

        // Update the contact
         ContentProviderResult[] res;
        try
        {
            res =  Android.App.Application.Context.ContentResolver.ApplyBatch(ContactsContract.Authority, ops);
            ops.Clear();//Add this line  
        }
        catch (Exception e)
        {
            System.Diagnostics.Debug.WriteLine( e.Message);
        }
                  
    #elif IOS
    #endif
    }
}

latest version of code which doesnt save anything

     List<ContentProviderOperation> ops = new List<ContentProviderOperation>();
 // Name 
String nameSelection = ContactsContract.Data.InterfaceConsts.RawContactId + " = ? AND " 
                       + ContactsContract.Data.InterfaceConsts.Mimetype + " = ? ";
String[] nameSelectionArgs = {
    id,
    ContactsContract.CommonDataKinds.StructuredName.ContentItemType
};
ContentProviderOperation.Builder builder = ContentProviderOperation.NewUpdate(ContactsContract.Data.ContentUri);
builder.WithSelection(nameSelection, nameSelectionArgs);
builder.WithValue(ContactsContract.CommonDataKinds.StructuredName.GivenName, fname);
builder.WithValue(ContactsContract.CommonDataKinds.StructuredName.FamilyName, sname);
ops.Add(builder.Build());

String emailSelection = ContactsContract.Data.InterfaceConsts.RawContactId + " = ?  ";
String[] emailSelectionArgs = {id};
builder = ContentProviderOperation.NewUpdate(ContactsContract.Data.ContentUri);
builder.WithSelection(emailSelection, emailSelectionArgs);
builder.WithValue(ContactsContract.CommonDataKinds.Email.Address, Email);
ops.Add(builder.Build());
try
{         
    var result = Android.App.Application.Context.ContentResolver.ApplyBatch(ContactsContract.Authority, ops);
    ops.Clear();
    }
catch(Exception e) {var ee = e.Message;}   
1

There are 1 best solutions below

6
Jessie Zhang -MSFT On

You can refer to the following code to change the phoneNumber:

public void ChangeContactNumber( string oldnumber,string newnumber) //  requires android.permission.READ_CONTACTS
        {
            Context context = Android.App.Application.Context;

            if (context == null) return ;
            var cursor = context.ContentResolver.Query(
                    ContactsContract.CommonDataKinds.Phone.ContentUri,
                    new string[] { ContactsContract.Contacts.InterfaceConsts.Id, ContactsContract.CommonDataKinds.Phone.Number },
                    ContactsContract.CommonDataKinds.Phone.Number + "=?",
                    new string[] { oldnumber },
                    null
            );
            if (cursor == null || cursor.Count == 0) return;
            cursor.MoveToFirst();
            string id = cursor.GetString(cursor.GetColumnIndex(ContactsContract.Contacts.InterfaceConsts.Id));
            //get the contactid here
            var contentvalues = new ContentValues();
            var where = ContactsContract.Contacts.InterfaceConsts.Id + "=?" + " AND "  + ContactsContract.CommonDataKinds.Phone.Number + "=?";
            var whereArgs = new String[] { id, oldnumber };
            contentvalues.Put(ContactsContract.CommonDataKinds.Phone.Number, newnumber);

            Android.Net.Uri uri = Android.Net.Uri.Parse("content://com.android.contacts/data");

            context.ContentResolver.Update(uri, contentvalues, where, whereArgs);
        }

In addition, when you get the contactid, you can change the name, email and other info by methodContentResolver.Update

Please refer to the following code:

       // Name 
        String nameSelection = ContactsContract.Data.InterfaceConsts.RawContactId + " = ? AND " 
                               + ContactsContract.Data.InterfaceConsts.Mimetype + " = ? ";
        String[] nameSelectionArgs = {
            _Contact.DataId.ToString(),
            ContactsContract.CommonDataKinds.StructuredName.ContentItemType
        };

        ContentProviderOperation.Builder builder = ContentProviderOperation.NewUpdate(ContactsContract.Data.ContentUri);
        builder.WithSelection(nameSelection, nameSelectionArgs);
        builder.WithValue(ContactsContract.CommonDataKinds.StructuredName.GivenName, _Contact.FirstName);
        builder.WithValue(ContactsContract.CommonDataKinds.StructuredName.FamilyName, _Contact.LastName);
        ops.Add(builder.Build());

        // Phone
        String phoneSelection = ContactsContract.Data.InterfaceConsts.RawContactId + " = ? AND " 
                                + ContactsContract.Data.InterfaceConsts.Mimetype + " = ? ";
        String[] phoneelectionArgs = {
            _Contact.DataId.ToString(),
            ContactsContract.CommonDataKinds.Phone.ContentItemType
        };

        builder = ContentProviderOperation.NewUpdate(ContactsContract.Data.ContentUri);
        builder.WithSelection(phoneSelection, phoneelectionArgs);
        builder.WithValue(ContactsContract.CommonDataKinds.Phone.Number, _Contact.Phone);
        ops.Add(builder.Build());

        // Email
        String emailSelection = ContactsContract.Data.InterfaceConsts.RawContactId + " = ? AND "
                         + ContactsContract.Data.InterfaceConsts.Mimetype + " = ? ";
        String[] emailSelectionArgs = {
            _Contact.DataId.ToString(),
            ContactsContract.CommonDataKinds.Email.ContentItemType
        };

        builder = ContentProviderOperation.NewUpdate(ContactsContract.Data.ContentUri);
        builder.WithSelection(emailSelection, emailSelectionArgs);
        builder.WithValue(ContactsContract.CommonDataKinds.Email.InterfaceConsts.Data, _Contact.Email);
        ops.Add(builder.Build());

        // Update the contact
        ContentProviderResult[] result;
        try
        {
            result = ContentResolver.ApplyBatch(ContactsContract.Authority, ops);
        }
        catch { }