B4A Library [library] ContentResolver

ContentResolver library allows you to access "content providers" applications.

This functionality is already available with objects such as: CallLog, Contacts, Contacts2 and others.

With this library you have more flexibility as you can implement it completely in Basic4android.

The classes in this library are similar to the Java classes. The purpose it to make it easier to convert Java code. Note that most of the constants are not available in this wrapper. This means that you need to replace them with the actual values.

The features of ContentResolver are similar to SQL features. The main operations are: Query, Insert, Update and Delete. For each feature there is a synchronous method and an asynchronous method (QueryAsync, InsertAsync...). The asynchronous methods raise events when the operation completes.

Note that you should reference SQL library together with this library.

For example, the following code allows you to access the contacts provider:

Manifest editor

AddPermission("android.permission.READ_CONTACTS")
AddPermission("android.permission.WRITE_CONTACTS")

Code

B4X:
Sub Process_Globals
   Private PeopleProjection() As String = Array As String("times_contacted", "last_time_contacted", _
      "display_name", "has_phone_number", "starred", "_id", "photo_id")
   Private cr As ContentResolver
End Sub

Sub Globals

End Sub

Sub Activity_Create(FirstTime As Boolean)
   If FirstTime Then
      cr.Initialize("cr")
   End If
   UpdateStarred("John", True)
End Sub
'Gets all contacts asynchronously and prints them.
Sub GetAllContacts
   Dim u As Uri
   u.Parse("content://com.android.contacts/contacts")
   cr.QueryAsync(u, PeopleProjection, "", Null, "")
End Sub

Sub CR_QueryCompleted (Success As Boolean, Crsr As Cursor)
   If Success = False Then
      Log(LastException)
   Else
      For i = 0 To Crsr.RowCount - 1
         Crsr.Position = i
         Log(Crsr.GetString("display_name"))
      Next
      Crsr.Close
   End If
End Sub
'Update the starred state of the given contact. Note that we use LIKE in the selection.
Sub UpdateStarred (Name As String, Starred As Boolean)
   Dim u As Uri
   u.Parse("content://com.android.contacts/contacts")
   Dim values As ContentValues
   values.Initialize
   values.PutBoolean("starred", Starred)
   Log(cr.Update(u, values, "display_name LIKE ?", Array As String("%" & Name & "%")))
End Sub

'Deletes the contact with the given name.
Sub DeleteContactByName(Name As String)
   Dim u As Uri
   u.Parse("content://com.android.contacts/data")
   Dim crsr As Cursor = cr.Query(u, Array As String("_id", "raw_contact_id"), _
      "mimetype = ? AND data1 = ?", Array As String("vnd.android.cursor.item/name", Name), "")
   For i = 0 To crsr.RowCount - 1
      crsr.Position = i
      Dim rawId As Long = crsr.GetLong("raw_contact_id")
      Log(cr.Delete(u, "raw_contact_id = ?", Array As String(rawId)))
      Dim u2 As Uri
      u2.Parse("content://com.android.contacts/raw_contacts")
      Log(cr.Delete(u2, "_id = ?", Array As String(rawId)))
   Next
   crsr.Close
End Sub

'Inserts a new contact.
Sub InsertContact(Name As String, Phone As String)
   Dim values As ContentValues
   Dim uri1 As Uri
   uri1.Parse("content://com.android.contacts/raw_contacts")
   values.Initialize
   values.PutNull("account_name")
   values.PutNull("account_type")
   Dim rawUri As Uri = cr.Insert(uri1, values)
   Dim rawContactId As Long = rawUri.ParseId
 
   uri1.Parse("content://com.android.contacts/data")
   values.Initialize
   values.PutLong("raw_contact_id", rawContactId)
   values.PutString("mimetype", "vnd.android.cursor.item/phone_v2")
   values.PutString("data1", Phone)
   cr.Insert(uri1, values)
 
   values.Initialize
   values.PutLong("raw_contact_id", rawContactId)
   values.PutString("mimetype", "vnd.android.cursor.item/name")
   values.PutString("data1", Name)
   cr.Insert(uri1, values)
End Sub

Installation instructions:
- Copy the two files in the zip to the internal libraries folder.
 
Last edited:

pierpa

Member
Licensed User
Longtime User
this will let me read/write contacts note field?

vnd.android.cursor.item/note

just because here 9.30pm and i will unzip/run the example tomorrow morning :)
 
Last edited:

Erel

B4X founder
Staff member
Licensed User
Longtime User
You can already read the note field with Contacts2.

You can read and write the note field with this library:
B4X:
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

This sub is useful for debugging:
B4X:
Sub PrintAggregatedDataFields(Name As String, Exact As Boolean)
   Dim u As Uri
   u.Parse("content://com.android.contacts/contacts")
   Dim selection As String
   selection = "display_name "
   If Exact Then 
      selection = selection & "= ?" 
   Else 
      selection = selection & "LIKE ?"
      Name = "%" & Name & "%"
   End If
   Dim crsr As Cursor = cr.Query(u, Null, selection, Array As String(Name), "")
   If crsr.RowCount = 0 Then
      Log("No match found.")
   End If
   For i = 0 To crsr.RowCount - 1
      crsr.Position = i
      LogColor(crsr.GetString("display_name"), Colors.Blue)
      For c = 0 To crsr.ColumnCount - 1
         Log(crsr.GetColumnName(c) & ": " & crsr.GetString2(c))
      Next
      Dim id As Long = crsr.GetLong("_id")
      
      'print phones
      Dim phonesUri As Uri
      phonesUri.Parse("content://com.android.contacts/data/phones")
      Dim phones As Cursor = cr.Query(phonesUri, Array As String("data1", "data2"), _
         "contact_id = ?", Array As String(id), "")
      For p = 0 To phones.RowCount - 1
         phones.Position = p
         Log("Phone: " & phones.GetString("data1") & ", type = " & phones.GetInt("data2"))
      Next
      phones.Close
      
      'print emails
      Dim emailsUri As Uri
      emailsUri.Parse("content://com.android.contacts/data/emails")
      Dim emails As Cursor = cr.Query(emailsUri, Array As String("data1"), _
         "contact_id = ?", Array As String(id), "")
      For p = 0 To emails.RowCount - 1
         emails.Position = p
         Log("Email: " & emails.GetString("data1"))
      Next
      emails.Close
      
      'print data fields
      Dim dataUri As Uri
      dataUri.Parse("content://com.android.contacts/data")
      Dim data As Cursor = cr.Query(dataUri, Array As String("mimetype", "data1"), _
         "contact_id = ?", Array As String(id), "")
      For d = 0 To data.RowCount - 1
         data.Position = d
         Log(data.GetString("mimetype") & "=" & data.GetString("data1"))
      Next
      data.Close
   Next
   crsr.Close
End Sub
 

bsnqt

Active Member
Licensed User
Longtime User
Dear Erel,

I guess (though I did not try yet) this will help us in deleting an individual call log easily (by phone number or by call log id)...

In the last few days, I spent days and nights to llearn and create for myself a library which help me in deleting a call log by id. Finally I succeeded, learned a lot but spent quite a lot of time...

And now I see this library... If I could see this library earlier, I would spend less time :)

Thank you very much for this library. It is very great :)

Best
bsnqt
 
Last edited:

Kiese

Member
Licensed User
Longtime User
Hi all and thanks for this great work.
I'm very new to b4a and am currently testing it.
I'm looking for the correct syntax to:
-find a contact from the DisplayName
-update the email address with a variable
any ideas/pointers?
(I'm just really beginning so I haven't started coding yet)
 

bsnqt

Active Member
Licensed User
Longtime User
Hi Erel, just a quick question: how I can write in B4A the following "Uri.encode(...)"
I cannot figure it out... It is in the following code from Java:

B4X:
Uri contactUri = Uri.withAppendedPath(ContactsContract.PhoneLookup.CONTENT_FILTER_URI, Uri.encode(phonenumber));

Do I need to write Uri.Parse("....")?

Thank you very much.
 
Last edited:

bsnqt

Active Member
Licensed User
Longtime User
I did find out... Thanks for your time.

B4X:
Dim phonesUri As Uri
phonesUri.Parse("content://com.android.contacts/phone_lookup")
phonesUri.WithAppendedPath(phonesUri, phonenumber)
 

ronin69

Member
Licensed User
Longtime User
Hi i'm Gianluca From Italy, i'm a newbie.

i have this error

Parsing code. Error
Error parsing program.
Error description: Unknown type: contentresolver
Are you missing a library reference?
Occurred on line: 8
Private cr As ContentResolver

i copied contentsolver library in library dir.

How can i solve this thing ?

thanks.
 

Walter Adriano da Silva

Member
Licensed User
Longtime User
In Deleting Events, which is the constant value "Events.CONTENT_URI"?

Edit: I have found this value, but now I a have another problem.
Same as code that does deleting an event in version 4.4.3, does not work in version 4.2.2.

B4X:
Sub DeleteCalendarEvent(callId As Long)
    Dim deleteUri As Uri
    Dim strUri As String = "content://com.android.calendar/events"
    deleteUri.Parse(strUri)
    Try
        cr.UpdateDelete(deleteUri, "_id=?", Array As String(callId))
    Catch
        Log(LastException.Message)
    End Try
End Sub
 
Last edited:

AZKANSOY

Member
Licensed User
Longtime User
Hi,
I'm getting Contact Photo_ID but I don't know how to use it. I wanna get real contact photo full size (hi-res) not thumbnail.
 

AZKANSOY

Member
Licensed User
Longtime User
Thank you for quick reply Erel,
This is very important for me.

Can you check this address http://developer.android.com/reference/android/provider/ContactsContract.DisplayPhoto.html

this site say "Retrieving a full-size photo by photo file ID (see PHOTO_FILE_ID)" with this Usage example


B4X:
 public InputStream openDisplayPhoto(long photoFileId) {
    Uri displayPhotoUri = ContentUris.withAppendedId(DisplayPhoto.CONTENT_URI, photoKey);
    try {
        AssetFileDescriptor fd = getContentResolver().openAssetFileDescriptor(
            displayPhotoUri, "r");
        return fd.createInputStream();
    } catch (IOException e) {
        return null;
    }
}

I'm not converting to B4A this code.
 
Top