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. Filippo

    Filippo Expert Licensed User

    This is a log-file created by "printCursor(crsr)"
    Code:
    name: Fili 1
    number: 
    123456789
    emails: 
    null
    _
    id0
    ***************
    name: Fili 
    2
    number: 
    987654321
    emails: 
    null
    _
    id1
    ***************
    name: Fili 
    1
    number: 
    123456789
    emails: 
    null
    _
    id0
    ***************
    name: Fili 
    2
    number: 
    987654321
    emails: 
    null
    _
    id1
    ***************
     
  2. Erel

    Erel Administrator Staff Member Licensed User

    Not sure. Your code is correct. This is the way to read SIM contacts...
     
  3. Filippo

    Filippo Expert Licensed User

    I have started my new smartphone and now everything works, thank you. :)
     
  4. Filippo

    Filippo Expert Licensed User

    Hi Erel,

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

    Code:
    values.Initialize
            values.PutLong(
    "_id", rawContactId)
            values.PutString(
    "tag", kontakt1.DisplayName)
            values.PutString(
    "number", kontakt1.Number)
            cr.Insert(simUri, values)
    How to modify a SIM contact?

    I tried with this code so far but it does not work.
    Code:
    values.Initialize
            values.PutString(
    "number", kontakt1.Number)
            
    'SetData("vnd.android.cursor.item/phone_v2", values, rawContactId, True)
            cr.Update(simUri, values, "mimetype = ? AND _id = ?"Array As String("vnd.android.cursor.item/phone", rawContactId))
           
            values.Initialize
            values.PutString(
    "tag", kontakt1.DisplayName)
            
    'SetData("vnd.android.cursor.item/name", values, rawContactId, True)
            cr.Update(simUri, values, "mimetype = ? AND _id = ?"Array As String("vnd.android.cursor.item/name", rawContactId))
     
  5. DKCERT

    DKCERT Member Licensed User

    Erel; Could you please throw an AddNote sub together. Mine eighter updates all Notes or only leaves the first one (deletes all others).

    Btw: This a version of GetNote(s) that steps through all Notes and returns them as a List:

    Code:
    Public Sub GetNotes(id As Long) As List
        
    Dim nl As List
        nl.Initialize
        
    For Each obj() As Object In GetData("vnd.android.cursor.item/note"Array As String("data1"), idNull)
            
    If obj(0) <> "" Then nl.Add(obj(0))
        
    Next
        
    Return nl
    End Sub
     
  6. Erel

    Erel Administrator Staff Member Licensed User

    @Filippo, 1. check the output of cr.update. It returns the number of updated rows. 2. Try to remove the mimetype. I don't think that it is used with sim contacts.

    @DKCERT, have you tried to set the last parameter in SetNote sub to False?
     
  7. DKCERT

    DKCERT Member Licensed User

    Yes I have. It results in an exception (this is the Sub):

    Code:
    Public Sub AddNote(Id As Long, Note As String)
        
    Dim v As ContentValues
        v.Initialize
        v.PutString(
    "data1", Note)
        SetData(
    "vnd.android.cursor.item/note", v, IdFalse)
    End Sub
    ...
    ...
    Sub lstContacts_ItemLongClick (Position As Int, Value As Object)
        
    Dim c As cuContact = Value
        cu.AddNote(c.Id, 
    "New Note")
        
    'update the text
        lstContacts_ItemClick(Position, Value)
    End Sub
    Code:
    contactsutils_setdata (java line: 685)
    java.lang.IllegalArgumentException: Invalid column name_raw_contact_id
      at android.database.DatabaseUtils.readExceptionFromParcel(DatabaseUtils.java:
    144)
      at android.database.DatabaseUtils.readExceptionFromParcel(DatabaseUtils.java:
    114)
      at android.content.ContentProviderProxy.bulkQueryInternal(ContentProviderNative.java:
    398)
      at android.content.ContentProviderProxy.query(ContentProviderNative.java:
    439)
      at android.content.ContentResolver.query(
    ContentResolver.java:264)
      at anywheresoftware.b4a.objects.ContentResolverWrapper.Query(ContentResolverWrapper.java:
    43)
      at testapp.contactsutils._setdata(contactutils.java:
    685)
      at testapp.contactsutils._addnote(contactutils.java:
    96)
      at testapp.contactsutils.main._lstcontacts_itemlongclick(main.java:
    384)
      at java.lang.reflect.Method.invokeNative(Native Method)
      at java.lang.reflect.Method.invoke(Method.java:
    507)
      at anywheresoftware.b4a.BA.raiseEvent2(BA.java:
    169)
      at anywheresoftware.b4a.BA$
    2.run(BA.java:272)
      at android.os.Handler.handleCallback(Handler.java:
    587)
      at android.os.Handler.dispatchMessage(Handler.java:
    92)
      at android.os.Looper.loop(Looper.java:
    150)
      at android.app.ActivityThread.main(ActivityThread.java:
    4385)
      at java.lang.reflect.Method.invokeNative(Native Method)
      at java.lang.reflect.Method.invoke(Method.java:
    507)
      at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:
    849)
      at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:
    607)
      at dalvik.system.NativeStart.main(Native Method)
    java.lang.IllegalArgumentException: Invalid column name_raw_contact_id
    I hope this helps?
     
  8. Filippo

    Filippo Expert Licensed User

    I tried it that way, but unfortunately it does not work. :(
    Code:
    values.Initialize
            values.PutString(
    "number", kontakt1.Number)
            
    Log(cr.Update(simUri, values, "_id = ?"Array As String(rawContactId)) )
           
            values.Initialize
            values.PutString(
    "tag", kontakt1.DisplayName)
            
    Log(cr.Update(simUri, values, "_id = ?"Array As String(rawContactId)) )
    Maybe you have an idea again?
     
  9. Erel

    Erel Administrator Staff Member Licensed User

    @DKCERT, I tried this code and it worked fine:
    Code:
    Public Sub AddNote(Id As Long, Note As String)
       
    Dim v As ContentValues
       v.Initialize
       v.PutString(
    "data1", Note)
       SetData(
    "vnd.android.cursor.item/note", v, IdFalse)
    End Sub
    Maybe there is a problem somewhere else in your code.

    Sorry Filippo. Not sure why it doesn't work. Try to find a Java solution. It should be simple to convert it.
     
  10. DKCERT

    DKCERT Member Licensed User

    Hi Erel, I'm actually using your demo code for ContactsUtils as my test platform :)
    How do you test the code and on what device(s)? It fails on my test device: HTC Desire S (v/2.3.5 - API 10).
    Reason for asking is I stumbled on these ones: https://code.google.com/p/android/issues/detail?id=11619 from http://stackoverflow.com/questions/...ntract-contact-missing-constants-from-the-api
    Anyway, the Desire allows adding Notes to the given Contact - so it is of course possible. Any ideas?
     
  11. thedesolatesoul

    thedesolatesoul Expert Licensed User

    @DKCERT from your logs its seems you made some modifications to your class?
    It cannot find name_raw_contact_id in contactUri. See here: http://developer.android.com/reference/android/provider/ContactsContract.Contacts.html
    It should be there, I dont understand how you get that exception unless your device doesnt have that feature or you changed the uri. Try testing on the emulator as well with a different android version.

    @Filippo are you sure you need to pass the raw contact id rather than the contact_id when doing a modify? Do you have documentation for the simUri and its fields?
     
    NJDude likes this.
  12. Filippo

    Filippo Expert Licensed User

    koaunglay likes this.
  13. DKCERT

    DKCERT Member Licensed User

    Well... modifications... I added AddNote (Update As Boolean -> False) and GetNotes (loops through all notes) and AddPhoto2 to the class. The "name_raw_contact_id" param is from the SetData sub in ContactsUtils v/1.05:

    Code:
    Private Sub SetData(Mime As String, Values As ContentValuesId As Long, Update As Boolean)
        
    If Update Then
            cr.Update(dataUri, Values, 
    "mimetype = ? AND contact_id = ?"Array As String(Mime, Id))
        
    Else
            
    Dim crsr As Cursor = cr.Query(contactUri, Array As String("name_raw_contact_id"), _    <---------------------------
                
    "_id = ?"Array As String(Id), "")
            
    If crsr.RowCount = 0 Then
                
    Log("Error getting raw_contact_id")
                crsr.Close
                
    Return
            
    End If
            crsr.Position = 
    0
            Values.PutString(
    "raw_contact_id", crsr.GetString("name_raw_contact_id"))   <---------------------------
            crsr.Close
            Values.PutString(
    "mimetype", Mime)
            cr.Insert(dataUri, Values)
        
    End If
    End Sub
    The emulator fails as well (using API level 8 -> Android v/2.2). So does the physical HTC Desire S (API level 10 -> Android 2.3.5).
     
  14. Filippo

    Filippo Expert Licensed User

    I have found the solution.

    With this code you can change a SIM-contact:

    Code:
    Dim cr As ContentResolver
        
    Dim values As ContentValues

        values.Initialize
        values.PutString(
    "tag", old_DisplayName)
        values.PutString(
    "number", old_Number)
        values.PutString(
    "newTag", new_DisplayName)
        values.PutString(
    "newNumber", new_Number)
       
        cr.Update(simUri, values, 
    NullNull)
     
    thedesolatesoul and Erel like this.
  15. Erel

    Erel Administrator Staff Member Licensed User

    @DKCERT I tested it with Nexus 4. Seems like your device misses this column.

    The purpose of this column is to find the primary raw_contact_id from the aggregated contact. If you like you can check which other columns are available and see whether there is an alternative way to find the raw_contact_id.
     
  16. DKCERT

    DKCERT Member Licensed User

    Well... I somehow hoped you could help me there ;) As the SDK also fails you properly have the right tools to pin down this issue!?
     
  17. luke2012

    luke2012 Well-Known Member Licensed User

    This library handle google account contacts only ?
     
  18. Erel

    Erel Administrator Staff Member Licensed User

    No. It should handle all non-sim contacts.
     
  19. shaffnert03

    shaffnert03 Member Licensed User

    Is it possible for me to add birthday to what this library can pull? And if so, any advice on where I'd start?
     
  20. Erel

    Erel Administrator Staff Member Licensed User

    I've uploaded an updated version that includes a GetEvents method.

    Note that the DateString can be without a year. For example:
    --01-01 => January 1st.
    2013-12-15 => December 15, 2013
     
    shaffnert03 likes this.
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