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

Status
Not open for further replies.
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:
B4X:
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:
B4X:
'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 String, Phone As String) As 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:
B4X:
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.
 

Attachments

  • ContactsUtils.zip
    11.6 KB · Views: 507
Last edited:

CapReed

Member
Licensed User
But that would imply that if the contact has picture, notes, phones, emails, etc, etc, would be lost to delete and re-create.

I think there must be a way to resolve this without having to delete / create.

The problem arises mainly when there are already some other contact with the same name to be modified. I'm still investigating ...

If you think of anything, would be appreciated.
 
Last edited:

Douglas Farias

Expert
Licensed User
@Erel how can i edit one contact with id? i dont found this on the forum only get all contacts but not edit with id *-*
i need delet and add new? or have a way to only edit? i dont find any set, edit function
 

Beja

Expert
Licensed User
Hi Erel,
I read the first page of this thread, so the answer to my question may be buried somewhere inside..
I am asking if with this lib, I can copy all contacts and then add them to another phone? A simple code is much appreciated.
 

fbritop

Active Member
Licensed User
Erel,
One thing I came across when searching for a contact by his phone number, is that Android, somehow formats the phone number in the contact data store, depending on the country with some spaces. For example, my phone number 5699129XXXX gets stored as 56 9 9129 XXXX.

So when I try to search for 9129XXXX, because of the strange spacing, it does not return the matched contact. I ended up viewing the contact data format on Android devices, and the raw main number is stored in "data4". I'm not sure if this is right, but at least it searchs and matches now the phone number that I'm looking for in the contacts.

It helps to search more deeply with the folowwing Sub

B4X:
Public Sub FindContactsByPhone2(PhoneNumber As String, Exact As Boolean, VisibleOnly As Boolean) As List
    Return FindContactsIdFromData("vnd.android.cursor.item/phone_v2", "data4", PhoneNumber, "=", Exact, VisibleOnly)
End Sub
 

Dwight Schrute

New Member
Licensed User
Hello,

I am being lazy here, but I have a very specific task and just figured it would be easier to ask IF I can do it before I invested a lot of time in learning the ContactUtils functions.

I have assigned several of my contacts a custom notification sound for when I receive a text from them. I've done this too many times, tho, and now I'm forgetting who got a custom notification sound, and if they did, what does it sound like.

I'll want to be able to:

1. Loop through all my contacts.
2. Perform the following Pseudocode:

B4X:
SELECT LastName, FirstName, NotificationSound,
NotificationSoundFilePath, NotificationSoundBlob
FROM Contacts
WHERE NotificationSound IS NOT NULL and NotificationSound <> "Default"

All the fields returned in such a query would be strings except for the NotificationSoundBlob, which would be the actual sound in binary.

BTW, NotificationSound is not a standard field the user is presented with when adding a new contact; you need to select "Add Another Field" and selecting it from there.

I don't know in what Android version the ability to add customized notification sounds for individual contacts was added.

Thanks --
DKS,
Assistant to the Assistant to the Regional Manager
 
Last edited:

JOTHA

Well-Known Member
Licensed User
Added some new functions to get ContactGroups, and filter contacts by Contact Groups.

How can I get the Groups of one Contact?

If I code this ... I'll get ALL Groups listed.
B4X:
    StringBuilder1.Append("Groups:").Append(CRLF)
        For Each Grp As cuGroup In ContactsUtils1.FindAllGroups()
            StringBuilder1.Append(""&Grp.Id&": "&Grp.Title&"").Append(CRLF)
        Next
 

Erel

Administrator
Staff member
Licensed User
What is the code of FindAllGroups?

This code will get the group ids:
B4X:
Public Sub GetGroups(Id As Long) As List
   Dim uri As Uri
   uri.Parse("content://com.android.contacts/contacts/" & Id & "/entities")
   Dim c As Cursor = cr.Query(uri, Array As String("group_sourceid"), "", Null, "")
   Dim group_sources As List
   group_sources.Initialize
   For i = 0 To c.RowCount - 1
     c.Position = i
     If c.GetString("group_sourceid") <> Null Then
       group_sources.Add(c.GetString("group_sourceid"))
     End If
   Next
   c.Close
   Return group_sources
End Sub
 

JOTHA

Well-Known Member
Licensed User
Hi Erel,

thank you for responding!

The code of FindAllGroups (Code by thedesolatesoul) is as follows:
B4X:
Public Sub FindAllGroups As List
  
    Dim Projection(2) As String = Array As String("_id", "title")
    Dim crsr As Cursor = cr.Query(groupContactUri, Projection,   "title <> ?", Array As String("null"), "")
    Dim ret As List
    ret.Initialize
    For i = 0 To crsr.RowCount - 1
        crsr.Position = i
        Dim Grp As cuGroup
        Grp.Id    = crsr.GetLong("_id")      
        Grp.Title = crsr.GetString("title")
        ret.Add(Grp)
    Next
    crsr.Close
    Return ret
  
End Sub

When I use your code (GetGroups)
B4X:
Log("-GetGroups: "&ContactsUtils1.GetGroups(Kontakt.Id)&"")
the result is:
GetGroups: (ArrayList) [6, 6f3ff5dc8e50c0ab, 2ae8b8430881e18f, 786a3cd288035f2f, 6f3ff5dc8e50c0ab, 6f3ff5dc8e50c0ab]

I think these are objects, but I need a list of all Groups for 1 Contact (Kontakt.Id)
I can't convert them into String.
 

DonManfred

Expert
Licensed User
You now have an Array with pairs... Index and id of the Group for this contact.

Remember the id's in a new list.
Check all Groups and compare the groupid with the remembered id's. If a Group Match you then have the name for this Group...

I did not tried it but as from the code in this thread i guess it should work
 

JOTHA

Well-Known Member
Licensed User
Hello DonManfred,

with FindAllGroups I can generate a List of all Groups (included Id's), but with GetGroups I can't generate such a List ...
 
Status
Not open for further replies.
Top