1. *** New version of B4J is available ***
    B4J v7.8
    Dismiss Notice

B4A Library [class] ContactsUtils - Provides read / write access to the stored contacts

Discussion in 'Additional libraries, classes and official updates' started by Erel, Jul 7, 2013.

  1. Erel

    Erel Administrator Staff Member Licensed User

    ContactsUtils is a class based on ContentResolver library.

    ContactsUtils allows you to read all kinds of information from the device stored contacts and also to modify the information, add new contacts and delete existing contacts.

    Most of the methods expect a contact id. You can get this id by calling one of the Find methods. All the Find methods return a List that holds cuContact items.

    The cuContact object holds the contact name and id. With that id you can get more information, add or modify existing fields and delete the contact.

    Types:
    Code:
    Type cuContact (Id As Long, DisplayName As String)
    Type cuEmail (Email As String, EmailType As String)
    Type cuPhone (Number As String, PhoneType As String)
    Type cuEvent (DateString As String, EventType As String)
    Public subs:
    Code:
    'Returns a List with cuContact items based on the given name.
    'Name - Name to look for.
    'Exact - Whether to search for the exact name or to search for names that contain the given value.
    'VisibleOnly - Whether to return only visible contacts. In most cases there are many invisible contacts.
    Public Sub FindContactsByName(Name As String, Exact As Boolean, VisibleOnly As Boolean) As List

    'Similar to FindContactsByName. Finds contacts based on the mail address.
    Public Sub FindContactsByMail(Mail As String, Exact As Boolean, VisibleOnly As Boolean) As List

    'Similar to FindContactsByName. Finds contacts based on the notes field.
    Public Sub FindContactsByNotes(Note As String, Exact As Boolean, VisibleOnly As Boolean) As List

    'Similar to FindContactsByName. Finds contacts based on the phone number.
    Public Sub FindContactsByPhone(PhoneNumber As String, Exact As Boolean, VisibleOnly As Boolean) As List

    'Returns the starred contacts.
    Public Sub FindContactsByStarred(Starred As Boolean) As List

    'Returns all contacts.
    Public Sub FindAllContacts(VisibleOnly As Boolean) As List

    'Returns all contacts with a photo.
    Public Sub FindContactsWithPhotos As List

    'Returns a List with cuEmail items.
    Public Sub GetEmails(Id As Long) As List

    'Returns a List with cuEvents items.
    Public Sub GetEvents(Id As Long) As List

    'Returns a List with cuPhone items.
    Public Sub GetPhones(id As Long) As List

    'Returns the note field.
    Public Sub GetNote(id As Long) As String

    'Returns the thumbnail photo of the given contact. Returns an uninitialized bitmap if no photo is available.
    Public Sub GetPhoto(Id As Long) As Bitmap

    'Gets whether the contact is "starred".
    Public Sub GetStarred(Id As Long) As Boolean

    'Sets the note field of the given id.
    Public Sub SetNote(Id As Long, Note As String)

    'Adds an email field to the given contact id.
    'EmailType - One of the email types strings (see Initialize method).
    Public Sub AddEmail(Id As Long, Email As String, EmailType As String)

    'Adds a phone field to the given contact id.
    'PhoneType - One of the phone types strings (see Initialize method).
    Public Sub AddPhone(Id As Long, PhoneNumber As String, PhoneType As String)

    'Deletes the given phone number.
    Public Sub DeletePhone(Id As Long, PhoneNumber As String)

    'Deletes the given email address.
    Public Sub DeleteEmail(Id As Long,Email As String)

    'Sets the starred state of the given id.
    Public Sub SetStarred (Id As Long, Starred As Boolean)

    'Deletes the contact with the given Id.
    Public Sub DeleteContact(Id As Long)

    'Inserts a new contact and returns the cuContact object of this contact.
    Public Sub InsertContact(Name As StringPhone As StringAs cuContact
    To use this class you need to add a reference to the ContentResolver and SQL libraries.

    The following permissions should be added in the manifest editor:
    Code:
    AddPermission("android.permission.READ_CONTACTS")
    AddPermission(
    "android.permission.WRITE_CONTACTS"'if write access is required
    It should be pretty simple to extend this class and retrieve or modify other fields based on the existing code.

    The attached project, which includes the ContactsUtils class shows a list with the visible contacts. Pressing on a contact will show some details about the contact and its photo. Long pressing on a contact will change its starred state.

    V1.20 - Adds GetGroups and GetAccounts methods.
    V1.10 - Adds GetEvents method.
    V1.05 - Fixes an issue with InsertContact on HTC devices.
     

    Attached Files:

    Last edited: Aug 26, 2016
    JOTHA, koaunglay, RFman and 3 others like this.
  2. bsnqt

    bsnqt Active Member Licensed User

    Dear Erel,

    Just a newbie / stupid question, in your example how can i sort by using cu.sort(true)... it does not work as it does not contains string but contacts...
    The contacts displayed in the listview (in your example) seems not being in alphabet order... I know that I can add all displaynames (cachedname) to another list and sort it. But can I do it directly with cu (ContactsUtil)?

    Thanks a lot.

    Best regards,
    bsnqt
     
    Daniel-White likes this.
  3. Erel

    Erel Administrator Staff Member Licensed User

    You can use SortType:
    Code:
    Sub Activity_Create(FirstTime As Boolean)
       
    If FirstTime Then
          cu.Initialize
       
    End If
       
    Activity.LoadLayout("1")
       
    Dim allContacts As List = cu.FindAllContacts(True)
       allContacts.SortType(
    "DisplayName"True)
       
    For Each c As cuContact In allContacts
          lstContacts.AddSingleLine2(c.DisplayName, c)
       
    Next
    End Sub
     
    Daniel-White likes this.
  4. bsnqt

    bsnqt Active Member Licensed User

    Oh, ok, I got it, thank you very much. I totally forgot the method "SortType".

    Best regards,
    bsnqt
     
  5. bsnqt

    bsnqt Active Member Licensed User

    Dear Erel,

    Using the ContactUtils it is much and much faster to find & load all Contacts from phone than using Phone and Contacts2 library. Earlier, I did that task with more than 12 sec. (as also reported by other members), now this task is done very quickly, almost immediately or < 1 sec.

    However, I still have a problem.

    If I want to find a stored Contact name by using the phone number and "FindContactsByPhone", I have to know exactly the phone number that I stored earlier. Let say in the past I stored "003311223344" now if my searching number is "0033-1122-3344", then I cannot find out this Contact.

    I am doing anything wrong? How can we eliminate the "phone number format" factor when doing search, as the user can enter (store) every kind of format they want, let say 0033-1122-3344 or (00) 33 1122- 3344 and so on...

    Code:
    Sub Button2_Click
        
    Dim phoneList As List
        phoneList.Initialize
        phoneList = cu.FindContactsByPhone(
    "0033-1122-3344"FalseFalse)
        
    For i = 0 To phoneList.Size - 1
            
    ToastMessageShow(phoneList.Get(i), False)
        
    Next
    End Sub
     
  6. Erel

    Erel Administrator Staff Member Licensed User

    Please start a new thread for this question and I'll try to write a small example for that.
     
  7. bsnqt

    bsnqt Active Member Licensed User

    I thought it is related to ContactUtils but anyway I will start a new thread... Thanks in advance.
     
  8. Erel

    Erel Administrator Staff Member Licensed User

    It is related. I just want to make sure that such an example doesn't "get lost" in a long thread (when a user searches for it).
     
  9. CapReed

    CapReed Member Licensed User

    I have noticed that sometimes some contacts do not recover your photos with GetPhoto correctly.

    I made this minimal modification in ContactUtils Module to get the picture when this circumstance occurs:

    Code:
    'Returns the thumbnail photo of the given contact. Returns an uninitialized bitmap if no photo is available.
    Public Sub GetPhoto(Id As Long) As Bitmap
        
    Dim raw As List = GetData("vnd.android.cursor.item/photo"Array As String("data15"), IdArray As Boolean(True))
        
    Dim bmp As Bitmap
        
    Log("Numero de posibles fotos : " & raw.Size)
        
    If raw.Size > 0 Then
            
    For ra =0 To raw.Size-1
                
    Dim obj() As Object = raw.Get(ra)
                
    Dim bytes() As Byte = obj(0)
                
    If bytes <> Null Then
                    
    Dim In As InputStream
                    
    In.InitializeFromBytesArray(bytes, 0, bytes.Length)
                    bmp.Initialize2(
    In)
                    
    In.Close
                
    End If
            
    Next
        
    End If
        
    Return bmp
    End Sub
    Hope this helps to some other user with the same situation.
     
  10. peacemaker

    peacemaker Well-Known Member Licensed User

    No possibility to update an existing contact (notes field) ?
     
  11. bsnqt

    bsnqt Active Member Licensed User

    I think it is completely possible.

    Code from Erel's example project:
    Code:
    Sub UpdateNote(Name As String, Note As String)
      
    Dim u As Uri
      u.Parse(
    "content://com.android.contacts/contacts")
      
    Dim crsr As Cursor = cr.Query(u, Array As String("_id"), "display_name = ?"Array As String(Name), "")
      
    If crsr.RowCount = 0 Then
          
    Log("No match found: " & Name)
      
    Else
          crsr.Position = 
    0
          
    Dim id As Long = crsr.GetLong("_id")
          
    Dim cv As ContentValues
          cv.Initialize
          cv.PutString(
    "data1", Note)
          
    Dim dataUri As Uri
          dataUri.Parse(
    "content://com.android.contacts/data")
          
    Log(cr.Update(dataUri, cv, "mimetype = 'vnd.android.cursor.item/note' AND contact_id = ?", _
            
    Array As String(id)))
      
    End If
      crsr.Close
    End Sub
     
    Rockefeller Goldman likes this.
  12. Erel

    Erel Administrator Staff Member Licensed User

    It is simpler. Once you have the contact id you just need to write:
    Code:
    cu.SetNote(contact.Id, "note message")
     
    ocalle and Rockefeller Goldman like this.
  13. peacemaker

    peacemaker Well-Known Member Licensed User

    Wow ! Great.
    But will it update the current Notes, or add ?
    I remember in some Android version there were several records for Notes.
     
  14. Erel

    Erel Administrator Staff Member Licensed User

    It will set the current notes field. You can modify the code in ContactsUtils to add a new note (if multiple notes are supported).
     
  15. thedesolatesoul

    thedesolatesoul Expert Licensed User

    Added some new functions to get ContactGroups, and filter contacts by Contact Groups.
     

    Attached Files:

  16. Filippo

    Filippo Expert Licensed User

    Hi Erel,

    with this code I can add address.
    Code:
    values.Initialize
                values.PutLong(
    "raw_contact_id", rawContactId)
                values.PutString(
    "mimetype""vnd.android.cursor.item/postal-address_v2")
                values.PutInteger(
    "data2"Address.TYP) 'Address type
                values.PutString("data5"Address.POBOX)
                values.PutString(
    "data4"Address.STREET)
                values.PutString(
    "data7"Address.CITY)
                values.PutString(
    "data8"Address.REGION)
                values.PutString(
    "data9"Address.POSTCODE)
                values.PutString(
    "data10"Address.COUNTRY)
                cr.Insert(dataUri, values)
    How can I delete an address?
     
  17. Erel

    Erel Administrator Staff Member Licensed User

    Try:
    Code:
    cr.Delete(dataUri, "mimetype = ? AND raw_contact_id = ?"Array As String("vnd.android.cursor.item/postal-address_v2", rawContactId))
     
  18. Filippo

    Filippo Expert Licensed User

    Thanks Erel, it works perfectly.
     
  19. Filippo

    Filippo Expert Licensed User

    Hi Erel,

    maybe you can help me.
    With this code I can read the SIM contacts.

    Code:
    Dim simUri As Uri
    simUri.Parse(
    "content://icc/adn")

    Public Sub FindSIMContacts As List
       
    Return FindSIMContactsIdFromData("vnd.android.cursor.item/name""data1""null""<>"TrueFalse)
    End Sub

    Private Sub FindSIMContactsIdFromData (Mime As String, DataColumn As String, Value As String, Operator As String, _
        Exact 
    As Boolean, VisibleOnly As Boolean) As List
        
    If Not(Exact) Then
            Operator = 
    "LIKE"
            Value = 
    "%" & Value & "%"
        
    End If
        
    Dim selection As String = "mimetype = ? AND " & DataColumn & " " & Operator & " ? "
        
    If VisibleOnly Then selection = selection & " AND in_visible_group = 1"
    '    Dim crsr As Cursor = cr.Query(simUri, Array As String("_id", "name"), selection, _
    '        Array As String(Mime, Value), "")
        Dim crsr As Cursor = cr.Query(simUri, NullNullNull,"")
        
    Dim res As List
        res.Initialize
        
    Dim m As Map
        m.Initialize
        
    For i = 0 To crsr.RowCount - 1
            printCursor(crsr)
            crsr.Position = i
            
    Dim cu As cuContact
            cu.Initialize
            cu.id = crsr.GetLong(
    "_id")
            cu.DisplayName = crsr.GetString(
    "name")

            
    If m.ContainsKey(cu.id) Then Continue
           
            
    Dim p As cuPhone
            
    Dim lst As List
            lst.Initialize
            p.Number=crsr.GetString(
    "number")
            p.PhoneType=phoneTypes.Get(
    2)
            lst.Add(p)
            cu.Phonenumber = lst

            m.Put(cu.id, 
    Null)
            res.Add(cu)
        
    Next
        crsr.Close
        
    Return res
    End Sub
    I have on my SIM card exactly 4 contacts(see Appendix), can you tell me why I see only two contacts with my code?
     

    Attached Files:

  20. Erel

    Erel Administrator Staff Member Licensed User

    Wild guess, maybe they somehow have the same id? Try to remove this line:
    If m.ContainsKey(cu.id) Then Continue
     
Loading...
  1. This site uses cookies to help personalise content, tailor your experience and to keep you logged in if you register.
    By continuing to use this site, you are consenting to our use of cookies.
    Dismiss Notice